summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]Android.mk25
-rw-r--r--api/current.txt5
-rw-r--r--cmds/installd/commands.c16
-rw-r--r--cmds/installd/installd.c5
-rw-r--r--cmds/installd/installd.h4
-rw-r--r--cmds/installd/utils.c6
-rw-r--r--cmds/servicemanager/Android.mk6
-rw-r--r--cmds/servicemanager/service_manager.c7
-rw-r--r--core/java/android/accounts/ChooseAccountTypeActivity.java1
-rw-r--r--core/java/android/app/ActivityManager.java25
-rw-r--r--core/java/android/app/ActivityThread.java182
-rw-r--r--core/java/android/app/AirplaneModeSettings.java133
-rw-r--r--core/java/android/app/ApplicationPackageManager.java10
-rwxr-xr-xcore/java/android/app/ConnectionSettings.java216
-rw-r--r--core/java/android/app/ContextImpl.java54
-rw-r--r--core/java/android/app/IProfileManager.aidl50
-rw-r--r--core/java/android/app/MediaRouteButton.java2
-rw-r--r--core/java/android/app/Notification.java9
-rw-r--r--core/java/android/app/NotificationGroup.aidl19
-rw-r--r--core/java/android/app/NotificationGroup.java201
-rw-r--r--core/java/android/app/Profile.aidl19
-rw-r--r--core/java/android/app/Profile.java554
-rw-r--r--core/java/android/app/ProfileGroup.java348
-rw-r--r--core/java/android/app/ProfileManager.java287
-rw-r--r--core/java/android/app/RingModeSettings.java135
-rw-r--r--core/java/android/app/StreamSettings.java130
-rwxr-xr-xcore/java/android/bluetooth/BluetoothDevice.java3
-rw-r--r--core/java/android/bluetooth/BluetoothUuid.java14
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/content/Intent.java48
-rw-r--r--core/java/android/content/SyncManager.java19
-rw-r--r--core/java/android/content/pm/ActivityInfo.java5
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java28
-rw-r--r--core/java/android/content/pm/BaseThemeInfo.java244
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl3
-rw-r--r--core/java/android/content/pm/PackageInfo.java73
-rw-r--r--core/java/android/content/pm/PackageManager.java28
-rw-r--r--core/java/android/content/pm/PackageParser.java74
-rwxr-xr-xcore/java/android/content/pm/ThemeInfo.aidl3
-rw-r--r--core/java/android/content/pm/ThemeInfo.java205
-rw-r--r--core/java/android/content/res/AssetManager.java158
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java16
-rw-r--r--core/java/android/content/res/Configuration.java75
-rw-r--r--core/java/android/content/res/CustomTheme.java117
-rw-r--r--core/java/android/content/res/PackageRedirectionMap.aidl22
-rw-r--r--core/java/android/content/res/PackageRedirectionMap.java90
-rwxr-xr-xcore/java/android/content/res/Resources.java29
-rw-r--r--core/java/android/database/sqlite/SQLiteSession.java2
-rw-r--r--core/java/android/hardware/Camera.java97
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java44
-rw-r--r--core/java/android/net/wimax/WimaxHelper.java188
-rw-r--r--core/java/android/net/wimax/WimaxManagerConstants.java18
-rwxr-xr-x[-rw-r--r--]core/java/android/nfc/Tag.java8
-rwxr-xr-x[-rw-r--r--]core/java/android/nfc/tech/BasicTagTechnology.java0
-rwxr-xr-xcore/java/android/nfc/tech/IsoPcdA.java101
-rwxr-xr-xcore/java/android/nfc/tech/IsoPcdB.java101
-rwxr-xr-x[-rw-r--r--]core/java/android/nfc/tech/TagTechnology.java18
-rw-r--r--core/java/android/os/BatteryManager.java28
-rw-r--r--core/java/android/os/BatteryStats.java5
-rw-r--r--core/java/android/os/IPowerManager.aidl4
-rw-r--r--core/java/android/os/PowerManager.java31
-rw-r--r--core/java/android/os/SystemProperties.java48
-rw-r--r--core/java/android/os/Trace.java2
-rw-r--r--core/java/android/preference/PreferenceActivity.java58
-rw-r--r--core/java/android/preference/VolumePreference.java17
-rw-r--r--core/java/android/provider/Settings.java945
-rw-r--r--core/java/android/view/ViewConfiguration.java17
-rw-r--r--core/java/android/view/VolumePanel.java155
-rw-r--r--core/java/android/view/Window.java8
-rw-r--r--core/java/android/view/WindowManager.java4
-rw-r--r--core/java/android/view/WindowManagerPolicy.java1
-rw-r--r--core/java/android/webkit/WebCoreThreadWatchdog.java2
-rw-r--r--core/java/android/webkit/WebSettingsClassic.java27
-rw-r--r--core/java/android/webkit/WebViewClassic.java29
-rw-r--r--core/java/android/webkit/WebViewCore.java6
-rw-r--r--core/java/android/widget/OverScroller.java8
-rw-r--r--core/java/android/widget/Scroller.java5
-rw-r--r--core/java/android/widget/TabWidget.java44
-rw-r--r--core/java/com/android/internal/app/ActivityTrigger.java72
-rw-r--r--core/java/com/android/internal/app/ExternalMediaFormatActivity.java36
-rw-r--r--core/java/com/android/internal/app/IAssetRedirectionManager.aidl42
-rwxr-xr-xcore/java/com/android/internal/app/IMediaContainerService.aidl2
-rw-r--r--core/java/com/android/internal/app/PlatLogoActivity.java9
-rw-r--r--core/java/com/android/internal/app/ThemeUtils.java56
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java3
-rw-r--r--core/java/com/android/internal/os/DeviceDockBatteryHandler.java53
-rw-r--r--core/java/com/android/internal/os/DeviceKeyHandler.java26
-rw-r--r--core/java/com/android/internal/os/IDeviceHandler.java25
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java6
-rw-r--r--core/java/com/android/internal/policy/IPolicy.java4
-rw-r--r--core/java/com/android/internal/policy/PolicyManager.java5
-rw-r--r--core/java/com/android/internal/view/RotationPolicy.java4
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuItemView.java2
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuPresenter.java24
-rw-r--r--core/java/com/android/internal/widget/ILockSettings.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java58
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java143
-rw-r--r--core/java/com/android/internal/widget/LockSettingsService.java33
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/GlowPadView.java70
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java12
-rw-r--r--core/jni/Android.mk7
-rw-r--r--core/jni/AndroidRuntime.cpp10
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp12
-rw-r--r--core/jni/android_emoji_EmojiFactory.cpp14
-rw-r--r--core/jni/android_hardware_Camera.cpp4
-rw-r--r--core/jni/android_media_AudioRecord.cpp83
-rw-r--r--core/jni/android_media_AudioTrack.cpp120
-rw-r--r--core/jni/android_net_wifi_Wifi.cpp6
-rw-r--r--core/jni/android_util_AssetManager.cpp366
-rw-r--r--core/jni/android_util_PackageRedirectionMap.cpp176
-rw-r--r--core/jni/com_android_internal_app_ActivityTrigger.cpp167
-rw-r--r--core/res/AndroidManifest.xml40
-rw-r--r--core/res/res/drawable-hdpi/ic_lock_expanded_desktop.pngbin0 -> 1169 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lock_idle_calendar.pngbin0 -> 709 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lock_profile.pngbin0 -> 3919 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lock_reboot.pngbin0 -> 1645 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lock_screenshot.pngbin0 -> 1326 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_alarm_activated.pngbin0 -> 7879 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_alarm_normal.pngbin0 -> 2438 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_answer_active.pngbin0 -> 9066 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.pngbin0 -> 17982 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.pngbin0 -> 6412 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_browser_activated.pngbin0 -> 7833 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_browser_normal.pngbin0 -> 4672 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_calendar_activated.pngbin0 -> 7158 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_calendar_normal.pngbin0 -> 1788 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.pngbin7214 -> 7417 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.pngbin1630 -> 2167 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_chrome_activated.pngbin0 -> 7736 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_chrome_normal.pngbin0 -> 2277 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_decline_activated.pngbin0 -> 8327 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.pngbin0 -> 16563 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.pngbin0 -> 5387 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_email2_activated.pngbin0 -> 6936 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_email2_normal.pngbin0 -> 3550 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_email_activated.pngbin0 -> 7164 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_email_normal.pngbin0 -> 3944 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_facebook_activated.pngbin0 -> 6983 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_facebook_normal.pngbin0 -> 3626 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_gallery_activated.pngbin0 -> 6905 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_gallery_normal.pngbin0 -> 3526 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_activated.pngbin12152 -> 8473 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_normal.pngbin12262 -> 5413 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_small_activated.pngbin0 -> 7545 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_small_normal.pngbin0 -> 2146 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_gplus_activated.pngbin0 -> 7491 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_gplus_normal.pngbin0 -> 2336 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_gtalk_activated.pngbin0 -> 7373 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_gtalk_normal.pngbin0 -> 2052 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.pngbin8376 -> 927 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_maps_activated.pngbin0 -> 7436 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_maps_normal.pngbin0 -> 4281 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_movie_activated.pngbin0 -> 7127 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_movie_normal.pngbin0 -> 3825 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_music_activated.pngbin0 -> 7020 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_music_normal.pngbin0 -> 3705 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_nav_activated.pngbin0 -> 7479 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_nav_normal.pngbin0 -> 2228 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_phone_activated.pngbin0 -> 7177 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_phone_normal.pngbin0 -> 3969 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_podcast_activated.pngbin0 -> 7890 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_podcast_normal.pngbin0 -> 4723 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_rss_activated.pngbin0 -> 7399 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_rss_normal.pngbin0 -> 4110 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_sms_activated.pngbin0 -> 7168 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_sms_normal.pngbin0 -> 1836 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.pngbin5172 -> 2576 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_target_activated.pngbin0 -> 5668 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_twitter_activated.pngbin0 -> 7321 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_twitter_normal.pngbin0 -> 4133 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_sys_adb.pngbin841 -> 3346 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_sys_tether_bluetooth.pngbin891 -> 1355 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_sys_tether_usb.pngbin909 -> 1400 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_sys_tether_wifi.pngbin1139 -> 1381 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lock_expanded_desktop.pngbin0 -> 951 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lock_idle_calendar.pngbin0 -> 583 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lock_profile.pngbin0 -> 3517 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lock_reboot.pngbin0 -> 3374 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lock_screenshot.pngbin0 -> 1176 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_alarm_activated.pngbin0 -> 4788 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_alarm_normal.pngbin0 -> 1869 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_answer_active.pngbin0 -> 5554 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_answer_focused.pngbin0 -> 10251 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_answer_normal.pngbin0 -> 3732 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_browser_activated.pngbin0 -> 4720 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_browser_normal.pngbin0 -> 3939 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_calendar_activated.pngbin0 -> 4411 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_calendar_normal.pngbin0 -> 1584 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.pngbin4543 -> 4413 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.pngbin1186 -> 1616 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_chrome_activated.pngbin0 -> 4655 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_chrome_normal.pngbin0 -> 1739 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_decline_activated.pngbin0 -> 5114 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_decline_focused.pngbin0 -> 9202 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_decline_normal.pngbin0 -> 3028 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_email2_activated.pngbin0 -> 4169 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_email2_normal.pngbin0 -> 3282 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_email_activated.pngbin0 -> 4309 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_email_normal.pngbin0 -> 3462 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_facebook_activated.pngbin0 -> 4212 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_facebook_normal.pngbin0 -> 3322 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_gallery_activated.pngbin0 -> 4200 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_gallery_normal.pngbin0 -> 3296 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_activated.pngbin7057 -> 5042 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_normal.pngbin6519 -> 4292 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_small_activated.pngbin0 -> 4577 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_small_normal.pngbin0 -> 1672 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_gplus_activated.pngbin0 -> 5106 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_gplus_normal.pngbin0 -> 1846 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_gtalk_activated.pngbin0 -> 4437 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_gtalk_normal.pngbin0 -> 1641 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.pngbin4800 -> 643 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_maps_activated.pngbin0 -> 4485 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_maps_normal.pngbin0 -> 3685 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_movie_activated.pngbin0 -> 4376 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_movie_normal.pngbin0 -> 3543 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_music_activated.pngbin0 -> 4255 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_music_normal.pngbin0 -> 3371 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_nav_activated.pngbin0 -> 4377 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_nav_normal.pngbin0 -> 1595 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_phone_activated.pngbin0 -> 4328 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_phone_normal.pngbin0 -> 3504 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_podcast_activated.pngbin0 -> 4756 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_podcast_normal.pngbin0 -> 3964 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_rss_activated.pngbin0 -> 4461 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_rss_normal.pngbin0 -> 3640 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_sms_activated.pngbin0 -> 4314 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_sms_normal.pngbin0 -> 1503 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.pngbin2871 -> 1792 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_target_activated.pngbin0 -> 4756 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_twitter_activated.pngbin0 -> 4433 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_twitter_normal.pngbin0 -> 3618 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_adb.pngbin511 -> 3152 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_tether_bluetooth.pngbin675 -> 1214 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_tether_usb.pngbin698 -> 1242 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sys_tether_wifi.pngbin814 -> 1230 bytes
-rw-r--r--core/res/res/drawable-nodpi/cidlogo.pngbin0 -> 34391 bytes
-rw-r--r--core/res/res/drawable-nodpi/cidlogo_alt.pngbin0 -> 35091 bytes
-rw-r--r--core/res/res/drawable-sw600dp-xhdpi/ic_lock_expanded_desktop.pngbin0 -> 1390 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lock_expanded_desktop.pngbin0 -> 1390 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lock_idle_calendar.pngbin0 -> 823 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lock_profile.pngbin0 -> 4208 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lock_reboot.pngbin0 -> 1558 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lock_screenshot.pngbin0 -> 1437 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_alarm_activated.pngbin0 -> 10296 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_alarm_normal.pngbin0 -> 2396 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_answer_active.pngbin0 -> 13057 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_answer_focused.pngbin0 -> 26181 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_answer_normal.pngbin0 -> 9504 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_browser_activated.pngbin0 -> 10138 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_browser_normal.pngbin0 -> 4828 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_calendar_activated.pngbin0 -> 9471 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_calendar_normal.pngbin0 -> 1659 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.pngbin10375 -> 10425 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.pngbin2341 -> 2907 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_chrome_activated.pngbin0 -> 10150 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_chrome_normal.pngbin0 -> 2481 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_decline_activated.pngbin0 -> 11903 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_decline_focused.pngbin0 -> 23969 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_decline_normal.pngbin0 -> 7480 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_email2_activated.pngbin0 -> 9247 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_email2_normal.pngbin0 -> 3542 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_email_activated.pngbin0 -> 9456 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_email_normal.pngbin0 -> 3854 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_facebook_activated.pngbin0 -> 9256 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_facebook_normal.pngbin0 -> 3618 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_gallery_activated.pngbin0 -> 9238 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_gallery_normal.pngbin0 -> 3581 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.pngbin17254 -> 10722 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.pngbin18528 -> 5203 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_small_activated.pngbin0 -> 9938 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_small_normal.pngbin0 -> 2225 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_gplus_activated.pngbin0 -> 10478 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_gplus_normal.pngbin0 -> 2743 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_activated.pngbin0 -> 9660 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_normal.pngbin0 -> 2000 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.pngbin12221 -> 1355 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_maps_activated.pngbin0 -> 9774 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_maps_normal.pngbin0 -> 4343 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_movie_activated.pngbin0 -> 9263 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_movie_normal.pngbin0 -> 3597 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_music_activated.pngbin0 -> 9362 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_music_normal.pngbin0 -> 3723 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_nav_activated.pngbin0 -> 10098 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_nav_normal.pngbin0 -> 2580 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_phone_activated.pngbin0 -> 9613 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_phone_normal.pngbin0 -> 4230 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_podcast_activated.pngbin0 -> 10131 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_podcast_normal.pngbin0 -> 4762 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_rss_activated.pngbin0 -> 9719 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_rss_normal.pngbin0 -> 4289 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_sms_activated.pngbin0 -> 9489 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_sms_normal.pngbin0 -> 1882 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.pngbin7698 -> 3578 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_target_activated.pngbin0 -> 8184 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_twitter_activated.pngbin0 -> 9732 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_twitter_normal.pngbin0 -> 4325 bytes
-rw-r--r--core/res/res/drawable-xhdpi/stat_sys_adb.pngbin882 -> 3560 bytes
-rw-r--r--core/res/res/drawable-xhdpi/stat_sys_tether_bluetooth.pngbin1111 -> 1504 bytes
-rw-r--r--core/res/res/drawable-xhdpi/stat_sys_tether_usb.pngbin1182 -> 1555 bytes
-rw-r--r--core/res/res/drawable-xhdpi/stat_sys_tether_wifi.pngbin1542 -> 1493 bytes
-rw-r--r--core/res/res/drawable/progress_large.xml4
-rw-r--r--core/res/res/drawable/progress_large_white.xml4
-rw-r--r--core/res/res/drawable/progress_medium.xml4
-rw-r--r--core/res/res/drawable/progress_medium_white.xml4
-rw-r--r--core/res/res/drawable/progress_small.xml4
-rw-r--r--core/res/res/drawable/progress_small_titlebar.xml4
-rw-r--r--core/res/res/drawable/progress_small_white.xml4
-rw-r--r--core/res/res/drawable/search_spinner.xml4
-rw-r--r--core/res/res/layout-port/keyguard_host_view.xml3
-rw-r--r--core/res/res/layout-sw600dp/keyguard_screen_status_land.xml6
-rw-r--r--core/res/res/layout-sw600dp/keyguard_screen_status_port.xml5
-rw-r--r--core/res/res/layout/keyguard_glow_pad_view.xml2
-rw-r--r--core/res/res/layout/keyguard_screen_tab_unlock.xml4
-rw-r--r--core/res/res/layout/keyguard_screen_tab_unlock_land.xml14
-rw-r--r--core/res/res/layout/keyguard_sim_pin_view.xml2
-rw-r--r--core/res/res/layout/keyguard_sim_puk_view.xml2
-rw-r--r--core/res/res/values-ar-rEG/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-ar/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-bg/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-ca/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-cs/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-cs/strings.xml1211
-rw-r--r--core/res/res/values-da/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-da/strings.xml76
-rw-r--r--core/res/res/values-de/donottranslate-cldr.xml5
-rw-r--r--core/res/res/values-de/strings.xml153
-rw-r--r--core/res/res/values-el/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-el/strings.xml102
-rw-r--r--core/res/res/values-en-rAU/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-en-rGB/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-en-rIE/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-en-rIN/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-en-rNZ/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-en-rZA/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-es-rUS/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-es/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-es/strings.xml74
-rw-r--r--core/res/res/values-fa/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-fi-rFI/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-fi/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-fi/strings.xml81
-rw-r--r--core/res/res/values-fr/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-fr/strings.xml45
-rw-r--r--core/res/res/values-hi-rIN/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-hr-rHR/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-hr/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-hu-rHU/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-hu/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-hu/strings.xml36
-rw-r--r--core/res/res/values-in-rID/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-in/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-it/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-it/strings.xml33
-rw-r--r--core/res/res/values-iw/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-iw/strings.xml93
-rw-r--r--core/res/res/values-ja/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-ja/strings.xml62
-rw-r--r--core/res/res/values-ko/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-ko/strings.xml66
-rw-r--r--core/res/res/values-land/integers.xml2
-rw-r--r--core/res/res/values-lt-rLT/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-lt/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-lv-rLV/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-lv/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-mcc450-ko/config.xml21
-rw-r--r--core/res/res/values-nb/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-nl/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-nl/strings.xml37
-rw-r--r--core/res/res/values-pl/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-pt-rPT/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-pt-rPT/strings.xml4
-rw-r--r--core/res/res/values-pt/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-pt/strings.xml37
-rw-r--r--core/res/res/values-ro-rRO/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-ro/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-ro/strings.xml32
-rw-r--r--core/res/res/values-ru/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-ru/strings.xml26
-rw-r--r--core/res/res/values-sk-rSK/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-sk/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-sl-rSI/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-sl/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-sr-rRS/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-sr/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-sv/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-sw360dp/dimens.xml30
-rw-r--r--core/res/res/values-sw720dp/dimens.xml2
-rw-r--r--core/res/res/values-th-rTH/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-th/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-tl/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-tr/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-uk-rUA/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-uk/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-vi-rVN/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-vi/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-zh-rCN/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values-zh-rCN/strings.xml98
-rw-r--r--core/res/res/values-zh-rTW/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values/arrays.xml24
-rwxr-xr-xcore/res/res/values/config.xml100
-rw-r--r--core/res/res/values/dimens.xml11
-rw-r--r--core/res/res/values/donottranslate-cldr.xml1
-rw-r--r--core/res/res/values/public.xml144
-rwxr-xr-xcore/res/res/values/strings.xml98
-rw-r--r--core/res/res/values/styles.xml2
-rw-r--r--core/res/res/values/symbols.xml89
-rw-r--r--core/res/res/xml/profile_default.xml267
-rw-r--r--data/etc/com.stericsson.hardware.fm.receiver.xml20
-rw-r--r--data/etc/com.stericsson.hardware.fm.transmitter.xml20
-rw-r--r--data/etc/platform.xml5
-rw-r--r--data/sounds/Alarm_Classic.wavbin365318 -> 0 bytes
-rw-r--r--data/sounds/AllAudio.mk24
-rw-r--r--data/sounds/AudioPackage2.mk104
-rw-r--r--data/sounds/AudioPackage3.mk100
-rw-r--r--data/sounds/AudioPackage4.mk104
-rwxr-xr-xdata/sounds/AudioPackage5.mk73
-rwxr-xr-xdata/sounds/AudioPackage6.mk45
-rwxr-xr-xdata/sounds/AudioPackage7.mk68
-rwxr-xr-xdata/sounds/AudioPackage7alt.mk67
-rw-r--r--data/sounds/AudioPackageElements.mk41
-rw-r--r--data/sounds/AudioPackageNewWave.mk76
-rw-r--r--data/sounds/AudioPackageStars.mk93
-rw-r--r--data/sounds/NewAudio.mk18
-rw-r--r--data/sounds/OldAudio.mk73
-rw-r--r--data/sounds/OriginalAudio.mk74
-rw-r--r--data/sounds/alarms/Cesium.oggbin27025 -> 0 bytes
-rwxr-xr-xdata/sounds/alarms/ogg-jp/Argon.oggbin56056 -> 0 bytes
-rwxr-xr-xdata/sounds/alarms/ogg-jp/Carbon.oggbin43364 -> 0 bytes
-rwxr-xr-xdata/sounds/alarms/ogg-jp/Helium.oggbin58729 -> 0 bytes
-rwxr-xr-xdata/sounds/alarms/ogg-jp/Krypton.oggbin103196 -> 0 bytes
-rwxr-xr-xdata/sounds/alarms/ogg-jp/Neon.oggbin176788 -> 0 bytes
-rwxr-xr-xdata/sounds/alarms/ogg-jp/Oxygen.oggbin27025 -> 0 bytes
-rw-r--r--data/sounds/alarms/ogg/Analysis.oggbin51938 -> 0 bytes
-rw-r--r--data/sounds/alarms/ogg/Departure.oggbin27986 -> 0 bytes
-rw-r--r--data/sounds/alarms/ogg/FireDrill.oggbin102973 -> 0 bytes
-rw-r--r--data/sounds/alarms/ogg/Timing.oggbin47948 -> 0 bytes
-rw-r--r--data/sounds/alarms/old/Alarm_Beep_01.ogg (renamed from data/sounds/Alarm_Beep_01.ogg)bin16130 -> 16130 bytes
-rw-r--r--data/sounds/alarms/old/Alarm_Beep_02.ogg (renamed from data/sounds/Alarm_Beep_02.ogg)bin5898 -> 5898 bytes
-rw-r--r--data/sounds/alarms/old/Alarm_Beep_03.ogg (renamed from data/sounds/Alarm_Beep_03.ogg)bin21153 -> 21153 bytes
-rw-r--r--data/sounds/alarms/old/Alarm_Buzzer.ogg (renamed from data/sounds/Alarm_Buzzer.ogg)bin11368 -> 11368 bytes
-rw-r--r--data/sounds/alarms/old/Alarm_Classic.ogg (renamed from data/sounds/Alarm_Classic.ogg)bin27052 -> 27052 bytes
-rw-r--r--data/sounds/alarms/old/Alarm_Rooster_01.ogg (renamed from data/sounds/Alarm_Rooster_01.ogg)bin10316 -> 10316 bytes
-rw-r--r--data/sounds/alarms/old/Alarm_Rooster_02.ogg (renamed from data/sounds/Alarm_Rooster_02.ogg)bin11160 -> 11160 bytes
-rw-r--r--data/sounds/alarms/wav/Barium.wavbin344292 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Cesium.wavbin365318 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Copernicium.wavbin1556024 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Curium.wavbin1485328 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Fermium.wavbin1345138 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Hassium.wavbin1697166 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Neptunium.wavbin1143548 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Nobelium.wavbin3606262 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Plutonium.wavbin875606 -> 0 bytes
-rw-r--r--data/sounds/alarms/wav/Scandium.wavbin694936 -> 0 bytes
-rw-r--r--data/sounds/effects/Dock.aifbin44154 -> 0 bytes
-rw-r--r--data/sounds/effects/KeypressDelete.wavbin29892 -> 0 bytes
-rw-r--r--data/sounds/effects/KeypressReturn.wavbin64320 -> 0 bytes
-rw-r--r--data/sounds/effects/KeypressSpacebar.wavbin49400 -> 0 bytes
-rw-r--r--data/sounds/effects/KeypressStandard.wavbin17992 -> 0 bytes
-rw-r--r--data/sounds/effects/Lock.wavbin11352 -> 0 bytes
-rw-r--r--data/sounds/effects/LowBattery.aifbin88902 -> 0 bytes
-rw-r--r--data/sounds/effects/Undock.aifbin44154 -> 0 bytes
-rw-r--r--data/sounds/effects/Unlock.wavbin11352 -> 0 bytes
-rw-r--r--data/sounds/effects/VideoRecord.wavbin33728 -> 0 bytes
-rw-r--r--data/sounds/effects/camera_click.wavbin13030 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]data/sounds/effects/ogg/KeypressDelete.oggbin5492 -> 6020 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressDelete_120.oggbin6020 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressDelete_14.oggbin5053 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressDelete_49.oggbin3918 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]data/sounds/effects/ogg/KeypressReturn.oggbin5490 -> 6222 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressReturn_120.oggbin6222 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressReturn_14.oggbin5175 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressReturn_49.oggbin4135 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]data/sounds/effects/ogg/KeypressSpacebar.oggbin5254 -> 6103 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressSpacebar_120.oggbin6103 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressSpacebar_14.oggbin5055 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressSpacebar_49.oggbin3953 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]data/sounds/effects/ogg/KeypressStandard.oggbin5222 -> 6069 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressStandard_120.oggbin6069 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressStandard_14.oggbin5055 -> 0 bytes
-rw-r--r--data/sounds/effects/ogg/KeypressStandard_49.oggbin3950 -> 0 bytes
-rw-r--r--data/sounds/effects/old/Dock.ogg (renamed from data/sounds/effects/Dock.ogg)bin6019 -> 6019 bytes
-rw-r--r--data/sounds/effects/old/Effect_Tick.ogg (renamed from data/sounds/effects/Effect_Tick.ogg)bin3994 -> 3994 bytes
-rw-r--r--data/sounds/effects/old/KeypressDelete.ogg (renamed from data/sounds/effects/KeypressDelete.ogg)bin6193 -> 6193 bytes
-rw-r--r--data/sounds/effects/old/KeypressReturn.ogg (renamed from data/sounds/effects/KeypressReturn.ogg)bin7972 -> 7972 bytes
-rw-r--r--data/sounds/effects/old/KeypressSpacebar.ogg (renamed from data/sounds/effects/KeypressSpacebar.ogg)bin7392 -> 7392 bytes
-rw-r--r--data/sounds/effects/old/KeypressStandard.ogg (renamed from data/sounds/effects/KeypressStandard.ogg)bin5194 -> 5194 bytes
-rw-r--r--data/sounds/effects/old/Lock.ogg (renamed from data/sounds/effects/Lock.ogg)bin4661 -> 4661 bytes
-rw-r--r--data/sounds/effects/old/LowBattery.ogg (renamed from data/sounds/effects/LowBattery.ogg)bin6585 -> 6585 bytes
-rw-r--r--data/sounds/effects/old/Undock.ogg (renamed from data/sounds/effects/Undock.ogg)bin6016 -> 6016 bytes
-rw-r--r--data/sounds/effects/old/Unlock.ogg (renamed from data/sounds/effects/Unlock.ogg)bin4666 -> 4666 bytes
-rw-r--r--data/sounds/effects/old/VideoRecord.ogg (renamed from data/sounds/effects/VideoRecord.ogg)bin5582 -> 5582 bytes
-rw-r--r--data/sounds/effects/old/camera_click.ogg (renamed from data/sounds/effects/camera_click.ogg)bin4851 -> 4851 bytes
-rw-r--r--data/sounds/effects/wav/CameraClick.wavbin71370 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/CameraFocus.wavbin71370 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/Dock.wavbin53696 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/Effect_Tick.wavbin13884 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressDelete.wavbin64252 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressDelete_14.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressDelete_49.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressReturn.wavbin49332 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressReturn_14.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressReturn_49.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressSpacebar.wavbin29824 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressSpacebar_14.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressSpacebar_49.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressStandard.wavbin17924 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressStandard_14.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/KeypressStandard_49.wavbin13926 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/Lock.wavbin11352 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/LowBattery.wavbin239278 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/Media_Volume.wavbin849046 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/NFCFailure.wavbin248116 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/NFCInitiated.wavbin283464 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/NFCSuccess.wavbin248116 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/Undock.wavbin53696 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/Unlock.wavbin11352 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/VideoRecord.wavbin80208 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/VideoStop.wavbin53696 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/VideoTransmitBegin.wavbin133232 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/VideoTransmitEnd.wavbin133232 -> 0 bytes
-rw-r--r--data/sounds/effects/wav/VolumeIncremental.wavbin106720 -> 0 bytes
-rw-r--r--data/sounds/notifications/Altair.oggbin7021 -> 0 bytes
-rw-r--r--data/sounds/notifications/Antares.oggbin10375 -> 0 bytes
-rw-r--r--data/sounds/notifications/Betelgeuse.oggbin16108 -> 0 bytes
-rw-r--r--data/sounds/notifications/Capella.oggbin13162 -> 0 bytes
-rw-r--r--data/sounds/notifications/CetiAlpha.oggbin26158 -> 0 bytes
-rw-r--r--data/sounds/notifications/CetiAlpha.wavbin507500 -> 0 bytes
-rw-r--r--data/sounds/notifications/Cricket.wavbin157524 -> 0 bytes
-rw-r--r--data/sounds/notifications/Deneb.oggbin14416 -> 0 bytes
-rw-r--r--data/sounds/notifications/Doink.wavbin63708 -> 0 bytes
-rw-r--r--data/sounds/notifications/Drip.wavbin218872 -> 0 bytes
-rw-r--r--data/sounds/notifications/Plastic_Pipe.wavbin69856 -> 0 bytes
-rw-r--r--data/sounds/notifications/Polaris.oggbin20567 -> 0 bytes
-rw-r--r--data/sounds/notifications/Pollux.oggbin23397 -> 0 bytes
-rw-r--r--data/sounds/notifications/Procyon.oggbin22380 -> 0 bytes
-rw-r--r--data/sounds/notifications/SpaceSeed.wavbin507500 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/aidos.oggbin14038 -> 0 bytes
-rw-r--r--data/sounds/notifications/arcturus.oggbin7908 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/circios.oggbin39179 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/horkos.oggbin18211 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/hypnos1.oggbin16391 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/kratos1.oggbin25158 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/kratos2.oggbin32305 -> 0 bytes
-rw-r--r--data/sounds/notifications/moonbeam.wavbin359980 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/nomos1.oggbin14620 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/nomos2.oggbin19885 -> 0 bytes
-rw-r--r--data/sounds/notifications/ogg/Acrux.oggbin10908 -> 0 bytes
-rw-r--r--data/sounds/notifications/ogg/Aldebaran.ogg (renamed from data/sounds/notifications/Aldebaran.ogg)bin7593 -> 7593 bytes
-rw-r--r--data/sounds/notifications/ogg/Bellatrix.oggbin15714 -> 0 bytes
-rw-r--r--data/sounds/notifications/ogg/Canopus.ogg (renamed from data/sounds/notifications/Canopus.ogg)bin11948 -> 11948 bytes
-rw-r--r--data/sounds/notifications/ogg/Castor.ogg (renamed from data/sounds/notifications/Castor.ogg)bin14648 -> 14648 bytes
-rw-r--r--data/sounds/notifications/ogg/Electra.ogg (renamed from data/sounds/notifications/Electra.ogg)bin15199 -> 15199 bytes
-rw-r--r--data/sounds/notifications/ogg/Fomalhaut.ogg (renamed from data/sounds/notifications/Fomalhaut.ogg)bin22003 -> 22003 bytes
-rw-r--r--data/sounds/notifications/ogg/Merope.ogg (renamed from data/sounds/notifications/Merope.ogg)bin18854 -> 18854 bytes
-rw-r--r--data/sounds/notifications/ogg/Regulus.ogg (renamed from data/sounds/notifications/regulus.ogg)bin27852 -> 27852 bytes
-rw-r--r--data/sounds/notifications/ogg/Sirius.ogg (renamed from data/sounds/notifications/sirius.ogg)bin26612 -> 26612 bytes
-rw-r--r--data/sounds/notifications/ogg/Sirrah.ogg (renamed from data/sounds/notifications/Sirrah.ogg)bin20976 -> 20976 bytes
-rw-r--r--data/sounds/notifications/old/Beat_Box_Android.ogg (renamed from data/sounds/notifications/Beat_Box_Android.ogg)bin34601 -> 34601 bytes
-rw-r--r--data/sounds/notifications/old/Bees_Knees.ogg (renamed from data/sounds/notifications/Bees_Knees.ogg)bin59135 -> 59135 bytes
-rw-r--r--data/sounds/notifications/old/Cheeper.ogg (renamed from data/sounds/notifications/Cheeper.ogg)bin19392 -> 19392 bytes
-rw-r--r--data/sounds/notifications/old/Cricket.ogg (renamed from data/sounds/notifications/Cricket.ogg)bin10936 -> 10936 bytes
-rw-r--r--data/sounds/notifications/old/Doink.ogg (renamed from data/sounds/notifications/Doink.ogg)bin8911 -> 8911 bytes
-rw-r--r--data/sounds/notifications/old/Drip.ogg (renamed from data/sounds/notifications/Drip.ogg)bin13244 -> 13244 bytes
-rw-r--r--data/sounds/notifications/old/F1_MissedCall.ogg (renamed from data/sounds/F1_MissedCall.ogg)bin11950 -> 11950 bytes
-rw-r--r--data/sounds/notifications/old/F1_NewVoicemail.ogg (renamed from data/sounds/F1_NewVoicemail.ogg)bin18653 -> 18653 bytes
-rw-r--r--data/sounds/notifications/old/F1_New_MMS.ogg (renamed from data/sounds/F1_New_MMS.ogg)bin20983 -> 20983 bytes
-rw-r--r--data/sounds/notifications/old/F1_New_SMS.ogg (renamed from data/sounds/F1_New_SMS.ogg)bin11941 -> 11941 bytes
-rw-r--r--data/sounds/notifications/old/Heaven.ogg (renamed from data/sounds/notifications/Heaven.ogg)bin38517 -> 38517 bytes
-rw-r--r--data/sounds/notifications/old/IM_Me.ogg (renamed from data/sounds/notifications/IM_Me.ogg)bin28944 -> 28944 bytes
-rw-r--r--data/sounds/notifications/old/Moonbeam.ogg (renamed from data/sounds/notifications/moonbeam.ogg)bin16243 -> 16243 bytes
-rw-r--r--data/sounds/notifications/old/Pixiedust.ogg (renamed from data/sounds/notifications/pixiedust.ogg)bin16905 -> 16905 bytes
-rw-r--r--data/sounds/notifications/old/Pizzicato.ogg (renamed from data/sounds/notifications/pizzicato.ogg)bin18884 -> 18884 bytes
-rw-r--r--data/sounds/notifications/old/Plastic_Pipe.ogg (renamed from data/sounds/notifications/Plastic_Pipe.ogg)bin6652 -> 6652 bytes
-rw-r--r--data/sounds/notifications/old/ShortCircuit.ogg (renamed from data/sounds/notifications/ShortCircuit.ogg)bin16562 -> 16562 bytes
-rw-r--r--data/sounds/notifications/old/SpaceSeed.ogg (renamed from data/sounds/notifications/SpaceSeed.ogg)bin26180 -> 26180 bytes
-rw-r--r--data/sounds/notifications/old/Star_Struck.ogg (renamed from data/sounds/notifications/Star_Struck.ogg)bin50350 -> 50350 bytes
-rw-r--r--data/sounds/notifications/old/TaDa.ogg (renamed from data/sounds/notifications/TaDa.ogg)bin43522 -> 43522 bytes
-rw-r--r--data/sounds/notifications/old/Tinkerbell.ogg (renamed from data/sounds/notifications/Tinkerbell.ogg)bin18858 -> 18858 bytes
-rw-r--r--data/sounds/notifications/old/Tweeters.ogg (renamed from data/sounds/notifications/tweeters.ogg)bin10421 -> 10421 bytes
-rwxr-xr-xdata/sounds/notifications/ouranos.oggbin21168 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/phantasos.oggbin27842 -> 0 bytes
-rw-r--r--data/sounds/notifications/pixiedust.wavbin332032 -> 0 bytes
-rw-r--r--data/sounds/notifications/pizzicato.wavbin384592 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/poros.oggbin24934 -> 0 bytes
-rwxr-xr-xdata/sounds/notifications/thrasos1.oggbin15737 -> 0 bytes
-rw-r--r--data/sounds/notifications/tweeters.wavbin151368 -> 0 bytes
-rw-r--r--data/sounds/notifications/vega.oggbin29476 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Altair.wavbin212766 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Antares.wavbin177418 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Betelgeuse.wavbin212766 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Deneb.wavbin212766 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Hojus.wavbin211724 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Lalande.wavbin283464 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Mira.wavbin212766 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Proxima.wavbin177418 -> 0 bytes
-rw-r--r--data/sounds/notifications/wav/Upsilon.wavbin283464 -> 0 bytes
-rw-r--r--data/sounds/ring3.oggbin16991 -> 0 bytes
-rw-r--r--data/sounds/ringer.oggbin32466 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ANDROMEDA.oggbin25014 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Aquila.oggbin21509 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ArgoNavis.oggbin89534 -> 0 bytes
-rw-r--r--data/sounds/ringtones/BOOTES.oggbin26310 -> 0 bytes
-rw-r--r--data/sounds/ringtones/CANISMAJOR.oggbin31170 -> 0 bytes
-rw-r--r--data/sounds/ringtones/CASSIOPEIA.oggbin31941 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Carina.oggbin15462 -> 0 bytes
-rwxr-xr-xdata/sounds/ringtones/Carina.wavbin264848 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Centaurus.oggbin27681 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Cygnus.oggbin29844 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Draco.oggbin31819 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Eridani.oggbin36585 -> 0 bytes
-rw-r--r--data/sounds/ringtones/FreeFlight.oggbin113055 -> 0 bytes
-rw-r--r--data/sounds/ringtones/FreeFlight.wavbin2229120 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Lyra.oggbin42540 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Machina.oggbin38077 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Orion.oggbin54456 -> 0 bytes
-rw-r--r--data/sounds/ringtones/PERSEUS.oggbin112981 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Pegasus.oggbin86731 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Pyxis.oggbin16653 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Rigel.oggbin32129 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Scarabaeus.oggbin108968 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Sceptrum.oggbin294019 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Solarium.oggbin60201 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Testudo.oggbin72078 -> 0 bytes
-rw-r--r--data/sounds/ringtones/URSAMINOR.oggbin144112 -> 0 bytes
-rw-r--r--data/sounds/ringtones/Vespa.oggbin18043 -> 0 bytes
-rw-r--r--data/sounds/ringtones/hydra.oggbin22962 -> 0 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Classic_01.ogg (renamed from data/sounds/Ring_Classic_01.ogg)bin53097 -> 53097 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Classic_02.ogg (renamed from data/sounds/Ring_Classic_02.ogg)bin59024 -> 59024 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Classic_03.ogg (renamed from data/sounds/Ring_Classic_03.ogg)bin31085 -> 31085 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Classic_04.ogg (renamed from data/sounds/Ring_Classic_04.ogg)bin28745 -> 28745 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Classic_05.ogg (renamed from data/sounds/Ring_Classic_05.ogg)bin12746 -> 12746 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Digital_01.ogg (renamed from data/sounds/Ring_Digital_01.ogg)bin28256 -> 28256 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Digital_02.ogg (renamed from data/sounds/Ring_Digital_02.ogg)bin21007 -> 21007 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Digital_03.ogg (renamed from data/sounds/Ring_Digital_03.ogg)bin23456 -> 23456 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Digital_04.ogg (renamed from data/sounds/Ring_Digital_04.ogg)bin30844 -> 30844 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Digital_05.ogg (renamed from data/sounds/Ring_Digital_05.ogg)bin21003 -> 21003 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Synth_01.ogg (renamed from data/sounds/Ring_Synth_01.ogg)bin26852 -> 26852 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Synth_02.ogg (renamed from data/sounds/Ring_Synth_02.ogg)bin52809 -> 52809 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Synth_03.ogg (renamed from data/sounds/Ring_Synth_03.ogg)bin23269 -> 23269 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Synth_04.ogg (renamed from data/sounds/Ring_Synth_04.ogg)bin43965 -> 43965 bytes
-rw-r--r--data/sounds/ringtones/old/Ring_Synth_05.ogg (renamed from data/sounds/Ring_Synth_05.ogg)bin35187 -> 35187 bytes
-rw-r--r--data/sounds/ringtones/ringtone18.oggbin214887 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone19.oggbin118444 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone20.oggbin53191 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone21.oggbin75013 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone22.oggbin102024 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone23.oggbin80588 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone24.oggbin104820 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone25.oggbin131029 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone26.oggbin97565 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone27.oggbin88468 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone28.oggbin121949 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone29.oggbin110062 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone30.oggbin113368 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone31.oggbin97936 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone32.oggbin175983 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone33.oggbin63250 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone34.oggbin60727 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone35.oggbin163844 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone36.oggbin40589 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone37.oggbin145806 -> 0 bytes
-rw-r--r--data/sounds/ringtones/ringtone38.oggbin126162 -> 0 bytes
-rw-r--r--data/sounds/ringtones/wav/Carina.wavbin264848 -> 0 bytes
-rw-r--r--data/sounds/ringtones/wav/Cassiopeia.wavbin610442 -> 0 bytes
-rw-r--r--data/sounds/ringtones/wav/Lyra.wavbin743000 -> 0 bytes
-rw-r--r--data/sounds/ringtones/wav/Sceptrum.wavbin5303008 -> 0 bytes
-rw-r--r--data/sounds/ringtones/wav/Solarium.wavbin1576224 -> 0 bytes
-rw-r--r--data/sounds/ringtones/wav/UrsaMinor.wavbin2263002 -> 0 bytes
-rw-r--r--data/sounds/ringtones/wav/Vespa.wavbin1167186 -> 0 bytes
-rw-r--r--fmradio/include/android_fmradio.h203
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmBand.aidl22
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmBand.java258
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmReceiver.java1327
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmReceiverImpl.java1126
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmReceiverService.java1347
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmTransmitter.java807
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmTransmitterImpl.java703
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/FmTransmitterService.java846
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IFmReceiver.aidl84
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IFmTransmitter.aidl64
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnAutomaticSwitchListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnBlockScanListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnErrorListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnExtraCommandListener.aidl30
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnForcedPauseListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnForcedResetListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnRDSDataFoundListener.aidl30
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnScanListener.aidl29
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnSignalStrengthListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnStartedListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnStateChangedListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/IOnStereoListener.aidl28
-rw-r--r--fmradio/java/com/stericsson/hardware/fm/package.html13
-rw-r--r--fmradio/jni/Android.mk41
-rwxr-xr-xfmradio/jni/android_fmradio.cpp1188
-rwxr-xr-xfmradio/jni/android_fmradio_Receiver.cpp1494
-rwxr-xr-xfmradio/jni/android_fmradio_Transmitter.cpp1098
-rw-r--r--include/androidfw/AssetManager.h18
-rw-r--r--include/androidfw/PackageRedirectionMap.h68
-rw-r--r--include/androidfw/ResourceTypes.h13
-rw-r--r--include/androidfw/ZipEntry.h345
-rw-r--r--include/androidfw/ZipFile.h270
-rw-r--r--libs/androidfw/Android.mk3
-rw-r--r--libs/androidfw/AssetManager.cpp211
-rw-r--r--libs/androidfw/PackageRedirectionMap.cpp203
-rw-r--r--libs/androidfw/ResourceTypes.cpp116
-rw-r--r--media/java/android/media/AudioFormat.java10
-rw-r--r--media/java/android/media/AudioManager.java24
-rw-r--r--media/java/android/media/AudioRecord.java23
-rwxr-xr-x[-rw-r--r--]media/java/android/media/AudioService.java379
-rwxr-xr-x[-rw-r--r--]media/java/android/media/AudioSystem.java20
-rw-r--r--media/java/android/media/AudioTrack.java12
-rw-r--r--media/java/android/media/MediaFile.java63
-rw-r--r--media/java/android/media/MediaRecorder.java13
-rw-r--r--media/java/android/media/Ringtone.java22
-rw-r--r--media/java/android/media/RingtoneManager.java146
-rwxr-xr-xmedia/jni/mediaeditor/Android.mk9
-rw-r--r--obex/javax/obex/ClientOperation.java12
-rw-r--r--obex/javax/obex/Operation.java2
-rw-r--r--obex/javax/obex/ServerOperation.java36
-rw-r--r--opengl/java/android/opengl/GLSurfaceView.java4
-rw-r--r--packages/BackupRestoreConfirmation/res/values-cs/strings.xml6
-rw-r--r--packages/DefaultContainerService/res/values-cs/strings.xml4
-rw-r--r--packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java46
-rw-r--r--packages/FusedLocation/res/values-cs/strings.xml4
-rw-r--r--packages/FusedLocation/res/values-es/strings.xml21
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm331
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm329
-rw-r--r--packages/InputDevices/res/values-cs/strings.xml33
-rw-r--r--packages/InputDevices/res/values-es/strings.xml51
-rw-r--r--packages/InputDevices/res/values/strings.xml6
-rw-r--r--packages/InputDevices/res/xml/keyboard_layouts.xml8
-rw-r--r--packages/SettingsProvider/res/values-cs/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java12
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java11
-rw-r--r--packages/SystemUI/AndroidManifest.xml23
-rw-r--r--packages/SystemUI/res/color/clock_view_color.xml9
-rw-r--r--packages/SystemUI/res/color/date_view_color.xml9
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.pngbin935 -> 784 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_2g3g_on.pngbin0 -> 3640 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_2g_on.pngbin0 -> 3426 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_3g_on.pngbin0 -> 3494 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_battery_neutral.pngbin0 -> 3046 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_neutral.pngbin0 -> 4760 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_gps_neutral.pngbin0 -> 4159 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_gps_off.pngbin0 -> 4277 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_gps_on.pngbin0 -> 4163 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_off.pngbin0 -> 3171 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_on.pngbin0 -> 3187 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_off.pngbin0 -> 4117 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_on.pngbin0 -> 4122 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_profiles.pngbin0 -> 3592 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_off.pngbin0 -> 3257 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_on.pngbin0 -> 3271 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_ring_off.pngbin0 -> 3573 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_ring_on.pngbin0 -> 3536 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_ring_vibrate_on.pngbin0 -> 3586 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_off.pngbin0 -> 4034 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_on.pngbin0 -> 4076 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_signal_data_off.pngbin0 -> 3169 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_sleep.pngbin0 -> 3256 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_sync_off.pngbin0 -> 3447 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_sync_on.pngbin0 -> 3463 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_torch_off.pngbin0 -> 3377 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_torch_on.pngbin0 -> 3394 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_unexpected_network.pngbin0 -> 3595 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_connected.pngbin0 -> 3493 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_off.pngbin0 -> 3613 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_on.pngbin0 -> 3515 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_off.pngbin0 -> 2166 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_on.pngbin0 -> 3777 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_neutral.pngbin0 -> 3638 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_off.pngbin0 -> 3680 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_on.pngbin0 -> 3655 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_recents_clear_normal.pngbin0 -> 762 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_recents_clear_pressed.pngbin0 -> 1228 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_add.pngbin0 -> 200 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_land.pngbin0 -> 196 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_side.pngbin0 -> 992 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.pngbin1053 -> 1778 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.pngbin0 -> 773 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.pngbin1063 -> 1790 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_side.pngbin0 -> 1300 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big.pngbin0 -> 1180 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big_land.pngbin0 -> 1176 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_side.pngbin0 -> 1226 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_search.pngbin0 -> 1846 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_land.pngbin0 -> 1850 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_side.pngbin0 -> 1440 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_2g3g_off.pngbin0 -> 3199 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_2g3g_on.pngbin0 -> 3329 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_3g_on.pngbin0 -> 3200 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_airplane_off.pngbin0 -> 1713 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_airplane_on.pngbin0 -> 1941 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_bgoff.9.pngbin0 -> 1074 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_bgon.9.pngbin0 -> 1099 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_bgon_custom.9.pngbin0 -> 194 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_bluetooth_off.pngbin0 -> 1001 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_bluetooth_on.pngbin0 -> 1848 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_brightness_auto.pngbin0 -> 2248 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_brightness_mid.pngbin0 -> 2171 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_brightness_off.pngbin0 -> 1247 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_brightness_on.pngbin0 -> 2362 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_data_off.pngbin0 -> 1492 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_data_on.pngbin0 -> 1603 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_flashlight_off.pngbin0 -> 3327 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_flashlight_on.pngbin0 -> 3344 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_gps_off.pngbin0 -> 1093 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_gps_on.pngbin0 -> 1974 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_inner_focus.9.pngbin0 -> 1082 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_inner_press.9.pngbin0 -> 1080 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_lock_screen_off.pngbin0 -> 1309 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_lock_screen_on.pngbin0 -> 1387 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_lte_off.pngbin0 -> 3010 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_lte_on.pngbin0 -> 3028 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_media_next.pngbin0 -> 3207 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_media_pause.pngbin0 -> 3020 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_media_play.pngbin0 -> 3147 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_media_previous.pngbin0 -> 3235 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_orientation_off.pngbin0 -> 1886 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_orientation_on.pngbin0 -> 2206 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_ring_off.pngbin0 -> 1401 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_ring_on.pngbin0 -> 1796 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_ring_vibrate_on.pngbin0 -> 1902 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_off.pngbin0 -> 1876 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_on.pngbin0 -> 2142 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_silent.pngbin0 -> 1498 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sleep.pngbin0 -> 1687 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sync_off.pngbin0 -> 1153 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sync_on.pngbin0 -> 2173 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim0.pngbin0 -> 1187 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim100.pngbin0 -> 3264 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim15.pngbin0 -> 3260 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim28.pngbin0 -> 3267 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim43.pngbin0 -> 3269 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim57.pngbin0 -> 3264 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim71.pngbin0 -> 3272 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim85.pngbin0 -> 3267 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_0.pngbin0 -> 3186 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_100.pngbin0 -> 2882 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_15.pngbin0 -> 2912 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_28.pngbin0 -> 2897 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_43.pngbin0 -> 2897 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_57.pngbin0 -> 2897 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_71.pngbin0 -> 2896 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_85.pngbin0 -> 2896 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_hp.pngbin0 -> 1162 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_hp.pngbin0 -> 3116 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_0.pngbin0 -> 633 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_100.pngbin0 -> 398 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_15.pngbin0 -> 493 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_28.pngbin0 -> 485 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_43.pngbin0 -> 490 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_57.pngbin0 -> 452 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_71.pngbin0 -> 498 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_85.pngbin0 -> 488 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim0.pngbin0 -> 573 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim100.pngbin0 -> 586 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim15.pngbin0 -> 646 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim28.pngbin0 -> 671 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim43.pngbin0 -> 679 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim57.pngbin0 -> 642 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim71.pngbin0 -> 692 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim85.pngbin0 -> 678 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim0.pngbin0 -> 1188 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim100.pngbin0 -> 3267 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim15.pngbin0 -> 3258 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim28.pngbin0 -> 3270 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim43.pngbin0 -> 3274 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim57.pngbin0 -> 3269 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim71.pngbin0 -> 3279 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim85.pngbin0 -> 3279 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_icon.pngbin0 -> 543 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_0.pngbin0 -> 3161 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_100.pngbin0 -> 2930 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_15.pngbin0 -> 2961 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_28.pngbin0 -> 2940 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_43.pngbin0 -> 2948 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_57.pngbin0 -> 2943 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_71.pngbin0 -> 2937 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_85.pngbin0 -> 2929 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_unknown.pngbin0 -> 496 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_sys_signal_min.pngbin0 -> 3194 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_vibrate_off.pngbin0 -> 1309 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_vibrate_on.pngbin0 -> 1309 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_off.pngbin0 -> 3476 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_on.pngbin0 -> 3495 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_wifi_off.pngbin0 -> 1140 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_wifi_on.pngbin0 -> 1988 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_wimax_off.pngbin0 -> 3169 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/stat_wimax_on.pngbin0 -> 3163 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.pngbin469 -> 398 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_2g3g_on.pngbin0 -> 3301 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_2g_on.pngbin0 -> 3235 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_3g_on.pngbin0 -> 3257 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_battery_neutral.pngbin0 -> 2989 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_neutral.pngbin0 -> 3689 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_gps_neutral.pngbin0 -> 3509 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_gps_off.pngbin0 -> 3567 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_gps_on.pngbin0 -> 3508 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_off.pngbin0 -> 3045 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_on.pngbin0 -> 3051 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_off.pngbin0 -> 3595 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_on.pngbin0 -> 3630 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_profiles.pngbin0 -> 3299 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_off.pngbin0 -> 3130 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_on.pngbin0 -> 3141 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_ring_off.pngbin0 -> 3347 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_ring_on.pngbin0 -> 3304 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_ring_vibrate_on.pngbin0 -> 3328 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_off.pngbin0 -> 3503 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_on.pngbin0 -> 3495 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_signal_data_off.pngbin0 -> 3031 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_sleep.pngbin0 -> 3097 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_sync_off.pngbin0 -> 3231 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_sync_on.pngbin0 -> 3247 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_torch_off.pngbin0 -> 3194 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_torch_on.pngbin0 -> 3210 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_unexpected_network.pngbin0 -> 3388 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_connected.pngbin0 -> 3325 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_off.pngbin0 -> 3380 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_on.pngbin0 -> 3341 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_off.pngbin0 -> 1704 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_on.pngbin0 -> 3458 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_neutral.pngbin0 -> 3311 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_off.pngbin0 -> 3348 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_on.pngbin0 -> 3359 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_recents_clear_normal.pngbin0 -> 687 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_recents_clear_pressed.pngbin0 -> 883 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_add.pngbin0 -> 199 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_land.pngbin0 -> 291 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_side.pngbin0 -> 1083 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.pngbin0 -> 565 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_side.pngbin0 -> 1177 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big.pngbin0 -> 1095 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big_land.pngbin0 -> 1082 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_side.pngbin0 -> 1151 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_search.pngbin0 -> 1449 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_land.pngbin0 -> 1450 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_side.pngbin0 -> 1266 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_2g3g_off.pngbin0 -> 3073 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_2g3g_on.pngbin0 -> 3166 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_3g_on.pngbin0 -> 3082 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_airplane_off.pngbin0 -> 1451 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_airplane_on.pngbin0 -> 1599 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_bgoff.9.pngbin0 -> 1074 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_bgon.9.pngbin0 -> 1099 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_bgon_custom.9.pngbin0 -> 194 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_bluetooth_off.pngbin0 -> 706 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_bluetooth_on.pngbin0 -> 1170 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_brightness_auto.pngbin0 -> 1371 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_brightness_mid.pngbin0 -> 1341 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_brightness_off.pngbin0 -> 844 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_brightness_on.pngbin0 -> 1401 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_data_off.pngbin0 -> 1320 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_data_on.pngbin0 -> 1411 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_flashlight_off.pngbin0 -> 3159 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_flashlight_on.pngbin0 -> 3178 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_gps_off.pngbin0 -> 750 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_gps_on.pngbin0 -> 1268 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_inner_focus.9.pngbin0 -> 1082 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_inner_press.9.pngbin0 -> 1080 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_lock_screen_off.pngbin0 -> 1196 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_lock_screen_on.pngbin0 -> 1273 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_lte_off.pngbin0 -> 2951 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_lte_on.pngbin0 -> 2956 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_media_next.pngbin0 -> 3115 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_media_pause.pngbin0 -> 2987 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_media_play.pngbin0 -> 3024 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_media_previous.pngbin0 -> 3134 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_orientation_off.pngbin0 -> 1532 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_orientation_on.pngbin0 -> 1709 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_ring_off.pngbin0 -> 989 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_ring_on.pngbin0 -> 1408 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_ring_vibrate_on.pngbin0 -> 1471 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_off.pngbin0 -> 1490 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_on.pngbin0 -> 1609 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_silent.pngbin0 -> 935 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sleep.pngbin0 -> 1483 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sync_off.pngbin0 -> 777 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sync_on.pngbin0 -> 1350 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim0.pngbin0 -> 1111 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim100.pngbin0 -> 3107 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim15.pngbin0 -> 3105 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim28.pngbin0 -> 3102 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim43.pngbin0 -> 3111 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim57.pngbin0 -> 3110 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim71.pngbin0 -> 3109 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim85.pngbin0 -> 3113 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_0.pngbin0 -> 3046 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_100.pngbin0 -> 2883 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_15.pngbin0 -> 2901 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_28.pngbin0 -> 2901 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_43.pngbin0 -> 2907 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_57.pngbin0 -> 2911 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_71.pngbin0 -> 2898 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_85.pngbin0 -> 2902 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_hp.pngbin0 -> 1086 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_hp.pngbin0 -> 3041 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_0.pngbin0 -> 633 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_100.pngbin0 -> 398 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_15.pngbin0 -> 493 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_28.pngbin0 -> 485 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_43.pngbin0 -> 490 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_57.pngbin0 -> 452 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_71.pngbin0 -> 498 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_85.pngbin0 -> 488 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim0.pngbin0 -> 573 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim100.pngbin0 -> 586 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim15.pngbin0 -> 646 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim28.pngbin0 -> 671 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim43.pngbin0 -> 679 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim57.pngbin0 -> 642 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim71.pngbin0 -> 692 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim85.pngbin0 -> 678 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim0.pngbin0 -> 1106 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim100.pngbin0 -> 3116 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim15.pngbin0 -> 3099 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim28.pngbin0 -> 3105 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim43.pngbin0 -> 3117 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim57.pngbin0 -> 3118 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim71.pngbin0 -> 3118 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim85.pngbin0 -> 3120 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_icon.pngbin0 -> 538 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_0.pngbin0 -> 3051 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_100.pngbin0 -> 2941 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_15.pngbin0 -> 2973 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_28.pngbin0 -> 2965 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_43.pngbin0 -> 2967 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_57.pngbin0 -> 2963 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_71.pngbin0 -> 2956 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_85.pngbin0 -> 2955 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_unknown.pngbin0 -> 496 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_sys_signal_min.pngbin0 -> 3052 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_vibrate_off.pngbin0 -> 905 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_vibrate_on.pngbin0 -> 905 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_off.pngbin0 -> 3276 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_on.pngbin0 -> 3264 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_wifi_off.pngbin0 -> 785 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_wifi_on.pngbin0 -> 1257 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_wimax_off.pngbin0 -> 3046 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/stat_wimax_on.pngbin0 -> 3060 bytes
-rw-r--r--packages/SystemUI/res/drawable-nodpi/cid_angry.pngbin0 -> 10454 bytes
-rw-r--r--packages/SystemUI/res/drawable-nodpi/cid_confused.pngbin0 -> 10782 bytes
-rw-r--r--packages/SystemUI/res/drawable-nodpi/cid_normal.pngbin0 -> 10519 bytes
-rw-r--r--packages/SystemUI/res/drawable-nodpi/cidlogo.pngbin0 -> 34391 bytes
-rw-r--r--packages/SystemUI/res/drawable-nodpi/cidlogo_alt.pngbin0 -> 35091 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.pngbin1480 -> 2166 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.pngbin1452 -> 2153 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.pngbin910 -> 1563 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.pngbin901 -> 1569 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.pngbin2126 -> 2800 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.pngbin2106 -> 2803 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim0.pngbin0 -> 1179 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim100.pngbin0 -> 3249 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim15.pngbin0 -> 3238 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim28.pngbin0 -> 3250 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim43.pngbin0 -> 3247 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim57.pngbin0 -> 3247 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim71.pngbin0 -> 3251 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim85.pngbin0 -> 3238 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_0.pngbin0 -> 3173 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_100.pngbin0 -> 2922 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_15.pngbin0 -> 2919 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_28.pngbin0 -> 2915 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_43.pngbin0 -> 2920 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_57.pngbin0 -> 2916 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_71.pngbin0 -> 2917 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_85.pngbin0 -> 2918 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_hp.pngbin0 -> 902 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_hp.pngbin0 -> 264 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim0.pngbin0 -> 1182 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim100.pngbin0 -> 3255 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim15.pngbin0 -> 3235 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim28.pngbin0 -> 3256 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim43.pngbin0 -> 3256 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim57.pngbin0 -> 3255 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim71.pngbin0 -> 3257 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim85.pngbin0 -> 3262 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_0.pngbin0 -> 3152 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_100.pngbin0 -> 2958 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_15.pngbin0 -> 2971 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_28.pngbin0 -> 2963 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_43.pngbin0 -> 2964 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_57.pngbin0 -> 2962 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_71.pngbin0 -> 2952 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_85.pngbin0 -> 2946 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_min.pngbin0 -> 3395 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim0.pngbin0 -> 1179 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim100.pngbin0 -> 3249 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim15.pngbin0 -> 3238 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim28.pngbin0 -> 3250 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim43.pngbin0 -> 3247 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim57.pngbin0 -> 3247 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim71.pngbin0 -> 3251 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim85.pngbin0 -> 3238 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_0.pngbin0 -> 3173 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_100.pngbin0 -> 2922 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_15.pngbin0 -> 2919 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_28.pngbin0 -> 2915 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_43.pngbin0 -> 2920 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_57.pngbin0 -> 2916 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_71.pngbin0 -> 2917 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_85.pngbin0 -> 2918 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_hp.pngbin0 -> 893 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_hp.pngbin0 -> 234 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_min.pngbin0 -> 3151 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim0.pngbin0 -> 1287 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim100.pngbin0 -> 3452 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim15.pngbin0 -> 3426 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim28.pngbin0 -> 3453 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim43.pngbin0 -> 3448 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim57.pngbin0 -> 3453 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim71.pngbin0 -> 3451 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim85.pngbin0 -> 3438 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_0.pngbin0 -> 3359 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_100.pngbin0 -> 2901 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_15.pngbin0 -> 2918 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_28.pngbin0 -> 2923 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_43.pngbin0 -> 2922 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_57.pngbin0 -> 2918 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_71.pngbin0 -> 2918 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_85.pngbin0 -> 2921 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_hp.pngbin0 -> 911 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_hp.pngbin0 -> 294 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim0.pngbin0 -> 1303 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim100.pngbin0 -> 3489 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim15.pngbin0 -> 3463 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim28.pngbin0 -> 3503 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim43.pngbin0 -> 3500 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim57.pngbin0 -> 3500 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim71.pngbin0 -> 3499 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim85.pngbin0 -> 3478 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_0.pngbin0 -> 3328 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_100.pngbin0 -> 2974 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_15.pngbin0 -> 3003 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_28.pngbin0 -> 2994 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_43.pngbin0 -> 2994 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_57.pngbin0 -> 2996 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_71.pngbin0 -> 2986 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_85.pngbin0 -> 2992 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_min.pngbin0 -> 3588 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.pngbin1751 -> 876 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_2g3g_on.pngbin0 -> 3804 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_2g_on.pngbin0 -> 3612 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_3g_on.pngbin0 -> 3672 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_neutral.pngbin0 -> 3147 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_neutral.pngbin0 -> 6268 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_neutral.pngbin0 -> 5105 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_off.pngbin0 -> 5334 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_on.pngbin0 -> 5074 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_off.pngbin0 -> 3214 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_on.pngbin0 -> 3226 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_off.pngbin0 -> 4710 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_on.pngbin0 -> 4661 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_profiles.pngbin0 -> 3904 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_off.pngbin0 -> 3436 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_on.pngbin0 -> 3451 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_off.pngbin0 -> 3763 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_on.pngbin0 -> 3796 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_vibrate_on.pngbin0 -> 3829 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_off.pngbin0 -> 4232 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_on.pngbin0 -> 4135 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_data_off.pngbin0 -> 389 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_sleep.pngbin0 -> 3305 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_off.pngbin0 -> 3628 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_on.pngbin0 -> 3643 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_off.pngbin0 -> 3538 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_on.pngbin0 -> 3553 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_unexpected_network.pngbin0 -> 3890 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_connected.pngbin0 -> 3712 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_off.pngbin0 -> 3874 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_on.pngbin0 -> 3737 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_off.pngbin0 -> 2769 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_on.pngbin0 -> 4104 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_neutral.pngbin0 -> 3895 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_off.pngbin0 -> 3991 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_on.pngbin0 -> 3917 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_normal.pngbin0 -> 861 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_pressed.pngbin0 -> 1606 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add.pngbin0 -> 469 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_land.pngbin0 -> 455 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_side.pngbin0 -> 517 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.pngbin1421 -> 2153 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.pngbin0 -> 1136 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.pngbin1429 -> 2178 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_side.pngbin0 -> 3434 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big.pngbin0 -> 1138 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big_land.pngbin0 -> 1137 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_side.pngbin0 -> 3209 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search.pngbin0 -> 2256 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_land.pngbin0 -> 2261 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_side.pngbin0 -> 3766 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_2g3g_off.pngbin0 -> 3354 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_2g3g_on.pngbin0 -> 3484 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_3g_on.pngbin0 -> 3375 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_airplane_off.pngbin0 -> 2046 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_airplane_on.pngbin0 -> 2352 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_off.pngbin0 -> 1314 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_on.pngbin0 -> 2461 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_brightness_auto.pngbin0 -> 3120 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_brightness_mid.pngbin0 -> 3073 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_brightness_off.pngbin0 -> 1711 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_brightness_on.pngbin0 -> 3312 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_data_off.pngbin0 -> 1691 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_data_on.pngbin0 -> 1828 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_flashlight_off.pngbin0 -> 3507 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_flashlight_on.pngbin0 -> 3518 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_gps_off.pngbin0 -> 1497 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_gps_on.pngbin0 -> 2878 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_off.pngbin0 -> 1413 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_on.pngbin0 -> 1519 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_lte_off.pngbin0 -> 3053 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_lte_on.pngbin0 -> 3054 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_media_next.pngbin0 -> 3232 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_media_pause.pngbin0 -> 2901 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_media_play.pngbin0 -> 3248 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_media_previous.pngbin0 -> 3239 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_orientation_off.pngbin0 -> 2271 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_orientation_on.pngbin0 -> 2749 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_ring_off.pngbin0 -> 1854 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_ring_on.pngbin0 -> 2271 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_ring_vibrate_on.pngbin0 -> 2455 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_off.pngbin0 -> 2296 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_on.pngbin0 -> 2628 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_silent.pngbin0 -> 2230 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sleep.pngbin0 -> 1847 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sync_off.pngbin0 -> 1521 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sync_on.pngbin0 -> 3048 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim0.pngbin0 -> 1285 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim100.pngbin0 -> 3436 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim15.pngbin0 -> 3429 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim28.pngbin0 -> 3434 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim43.pngbin0 -> 3444 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim57.pngbin0 -> 3431 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim71.pngbin0 -> 3443 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim85.pngbin0 -> 3432 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_0.pngbin0 -> 3341 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_100.pngbin0 -> 2910 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_15.pngbin0 -> 2930 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_28.pngbin0 -> 2923 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_43.pngbin0 -> 2922 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_57.pngbin0 -> 2928 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_71.pngbin0 -> 2916 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_85.pngbin0 -> 2920 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_hp.pngbin0 -> 1251 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_hp.pngbin0 -> 3240 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim0.pngbin0 -> 1302 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim100.pngbin0 -> 3488 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim15.pngbin0 -> 3475 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim28.pngbin0 -> 3501 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim43.pngbin0 -> 3504 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim57.pngbin0 -> 3493 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim71.pngbin0 -> 3504 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim85.pngbin0 -> 3508 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_icon.pngbin0 -> 575 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_0.pngbin0 -> 3316 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_100.pngbin0 -> 2992 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_15.pngbin0 -> 3017 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_28.pngbin0 -> 3010 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_43.pngbin0 -> 2993 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_57.pngbin0 -> 3013 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_71.pngbin0 -> 3007 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_85.pngbin0 -> 2997 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_min.pngbin0 -> 3425 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_vibrate_off.pngbin0 -> 1840 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_vibrate_on.pngbin0 -> 1840 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_off.pngbin0 -> 3776 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_on.pngbin0 -> 3801 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_wifi_off.pngbin0 -> 1538 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_wifi_on.pngbin0 -> 2828 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_wimax_off.pngbin0 -> 3306 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/stat_wimax_on.pngbin0 -> 3317 bytes
-rw-r--r--packages/SystemUI/res/drawable/ic_notifications.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_notify_clear.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_notify_quicksettings.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_recents_clear.xml21
-rw-r--r--packages/SystemUI/res/drawable/stat_power_background.xml22
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_battery_charge_min.xml29
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_battery_min.xml30
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_kb_battery.xml30
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_kb_battery_charge.xml29
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_kb_battery_charge_min.xml27
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_kb_battery_min.xml30
-rw-r--r--packages/SystemUI/res/layout-land/status_bar_recent_panel.xml9
-rw-r--r--packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_land.xml93
-rw-r--r--packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_port.xml93
-rw-r--r--packages/SystemUI/res/layout-sw600dp/navigation_bar.xml275
-rw-r--r--packages/SystemUI/res/layout/mid_navigation_bar_land.xml97
-rw-r--r--packages/SystemUI/res/layout/mid_navigation_bar_port.xml95
-rw-r--r--packages/SystemUI/res/layout/navigation_bar.xml192
-rw-r--r--packages/SystemUI/res/layout/power_widget_button.xml35
-rw-r--r--packages/SystemUI/res/layout/quick_settings_tile_generic.xml24
-rw-r--r--packages/SystemUI/res/layout/signal_cluster_text_view.xml53
-rw-r--r--packages/SystemUI/res/layout/status_bar.xml61
-rwxr-xr-x[-rw-r--r--]packages/SystemUI/res/layout/status_bar_expanded.xml8
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded_header.xml7
-rw-r--r--packages/SystemUI/res/layout/status_bar_recent_panel.xml9
-rw-r--r--packages/SystemUI/res/layout/system_bar_notification_area.xml9
-rw-r--r--packages/SystemUI/res/layout/system_bar_notification_panel_title.xml12
-rw-r--r--packages/SystemUI/res/layout/system_bar_recent_panel.xml9
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml139
-rw-r--r--packages/SystemUI/res/values-da/strings.xml49
-rw-r--r--packages/SystemUI/res/values-de-large/strings.xml33
-rw-r--r--packages/SystemUI/res/values-de/strings.xml96
-rw-r--r--packages/SystemUI/res/values-el/strings.xml35
-rw-r--r--packages/SystemUI/res/values-es/strings.xml63
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml48
-rw-r--r--packages/SystemUI/res/values-it/strings.xml45
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml50
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml43
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml48
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml43
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml74
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml4
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml5
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml49
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml11
-rw-r--r--packages/SystemUI/res/values/donottranslate.xml5
-rw-r--r--packages/SystemUI/res/values/strings.xml57
-rw-r--r--packages/SystemUI/res/values/styles.xml20
-rw-r--r--packages/SystemUI/res/xml/dream_info.xml4
-rw-r--r--packages/SystemUI/res/xml/dream_settings.xml23
-rw-r--r--packages/SystemUI/src/com/android/systemui/BeanBag.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/BeanBagDream.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/BeanBagDreamSettings.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUI.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIService.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/AirplaneModeTile.java83
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/AlarmTile.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/AutoRotateTile.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/BatteryTile.java85
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/BluetoothTile.java107
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/BrightnessTile.java145
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/BugReportTile.java107
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/GPSTile.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/InputMethodTile.java133
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTile.java158
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTypeTile.java198
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/NfcTile.java102
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/PreferencesTile.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/ProfileTile.java113
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java108
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/QuietHoursTile.java61
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/RingerModeTile.java217
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/ScreenTimeoutTile.java168
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/SleepScreenTile.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/SyncTile.java102
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/ToggleLockscreenTile.java81
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/TorchTile.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/UsbTetherTile.java140
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/UserTile.java174
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/WiFiDisplayTile.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/WiFiTile.java78
-rw-r--r--packages/SystemUI/src/com/android/systemui/quicksettings/WifiAPTile.java111
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java176
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java47
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java558
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java171
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java148
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java639
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java496
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java187
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java419
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleDockBattery.java141
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java128
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java75
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java47
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AirplaneButton.java65
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AutoRotateButton.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BluetoothButton.java132
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BrightnessButton.java196
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/FlashlightButton.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/GPSButton.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LTEButton.java89
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LockScreenButton.java78
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaKeyEventButton.java57
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaNextButton.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPlayPauseButton.java57
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPreviousButton.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MobileDataButton.java68
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/NetworkModeButton.java194
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java194
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerWidget.java536
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/ScreenTimeoutButton.java175
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SleepButton.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SoundButton.java207
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/StateTracker.java155
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SyncButton.java75
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiApButton.java153
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiButton.java147
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WimaxButton.java159
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java72
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java2
-rw-r--r--packages/VpnDialogs/res/values-cs/strings.xml8
-rw-r--r--packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/GlobalActions.java356
-rw-r--r--[-rwxr-xr-x]policy/src/com/android/internal/policy/impl/PhoneWindowManager.java834
-rw-r--r--policy/src/com/android/internal/policy/impl/Policy.java5
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java13
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java107
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java15
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java3
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java21
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java231
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java14
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java149
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java53
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java18
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard_obsolete/PatternUnlockScreen.java2
-rw-r--r--services/input/Android.mk8
-rw-r--r--services/input/InputReader.cpp70
-rw-r--r--services/input/InputReader.h21
-rw-r--r--services/java/com/android/server/AppsLaunchFailureReceiver.java73
-rw-r--r--services/java/com/android/server/AssetRedirectionManagerService.java397
-rw-r--r--services/java/com/android/server/BatteryService.java244
-rw-r--r--services/java/com/android/server/ConnectivityService.java18
-rw-r--r--services/java/com/android/server/DeviceHandlerService.java125
-rw-r--r--services/java/com/android/server/DeviceStorageMonitorService.java28
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java35
-rw-r--r--services/java/com/android/server/LocationManagerService.java3
-rw-r--r--services/java/com/android/server/MountService.java125
-rw-r--r--services/java/com/android/server/NetworkManagementService.java10
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java268
-rw-r--r--services/java/com/android/server/ProfileManagerService.java551
-rw-r--r--services/java/com/android/server/RotationSwitchObserver.java163
-rw-r--r--services/java/com/android/server/SystemServer.java100
-rw-r--r--services/java/com/android/server/ThrottleService.java17
-rw-r--r--services/java/com/android/server/UiModeManagerService.java20
-rwxr-xr-xservices/java/com/android/server/VibratorService.java29
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java6
-rw-r--r--services/java/com/android/server/WifiService.java9
-rw-r--r--services/java/com/android/server/WiredAccessoryManager.java61
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java2
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java51
-rw-r--r--[-rwxr-xr-x]services/java/com/android/server/am/ActivityStack.java29
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java18
-rw-r--r--services/java/com/android/server/input/InputManagerService.java29
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java225
-rw-r--r--services/java/com/android/server/pm/Settings.java2
-rw-r--r--services/java/com/android/server/power/DisplayPowerController.java2
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java73
-rw-r--r--services/java/com/android/server/power/ShutdownThread.java80
-rw-r--r--services/java/com/android/server/usb/LegacyUsbDeviceManager.java676
-rw-r--r--services/java/com/android/server/usb/UsbDeviceManager.java32
-rw-r--r--services/java/com/android/server/usb/UsbService.java3
-rw-r--r--services/java/com/android/server/wm/ScreenRotationAnimation.java28
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java52
-rw-r--r--services/jni/Android.mk12
-rw-r--r--services/jni/com_android_server_BatteryService.cpp8
-rw-r--r--services/jni/com_android_server_input_InputManagerService.cpp33
-rwxr-xr-xservices/jni/com_android_server_location_GpsLocationProvider.cpp16
-rw-r--r--services/jni/com_android_server_power_PowerManagerService.cpp8
-rw-r--r--telephony/java/android/telephony/CellInfoLte.java2
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.java10
-rw-r--r--telephony/java/android/telephony/SignalStrength.java22
-rwxr-xr-xtelephony/java/android/telephony/TelephonyManager.java37
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl8
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java3
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java16
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java8
-rw-r--r--tools/aapt/Bundle.h6
-rw-r--r--tools/aapt/Main.cpp14
-rw-r--r--tools/aapt/ResourceTable.cpp12
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java10
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl2
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java12
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java2
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java35
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pService.java2
1494 files changed, 39989 insertions, 3166 deletions
diff --git a/Android.mk b/Android.mk
index eae49ef..3022765 100644..100755
--- a/Android.mk
+++ b/Android.mk
@@ -26,8 +26,6 @@ LOCAL_PATH := $(call my-dir)
# TODO: find a more appropriate way to do this.
framework_res_source_path := APPS/framework-res_intermediates/src
-# the library
-# ============================================================
include $(CLEAR_VARS)
# FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
@@ -70,6 +68,7 @@ LOCAL_SRC_FILES += \
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
core/java/android/app/INotificationManager.aidl \
+ core/java/android/app/IProfileManager.aidl \
core/java/android/app/IProcessObserver.aidl \
core/java/android/app/ISearchManager.aidl \
core/java/android/app/ISearchManagerCallback.aidl \
@@ -169,6 +168,7 @@ LOCAL_SRC_FILES += \
core/java/com/android/internal/app/IBatteryStats.aidl \
core/java/com/android/internal/app/IUsageStats.aidl \
core/java/com/android/internal/app/IMediaContainerService.aidl \
+ core/java/com/android/internal/app/IAssetRedirectionManager.aidl \
core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
core/java/com/android/internal/backup/IBackupTransport.aidl \
@@ -222,7 +222,21 @@ LOCAL_SRC_FILES += \
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
voip/java/android/net/sip/ISipSession.aidl \
voip/java/android/net/sip/ISipSessionListener.aidl \
- voip/java/android/net/sip/ISipService.aidl
+ voip/java/android/net/sip/ISipService.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IFmReceiver.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IFmTransmitter.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnStateChangedListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnStartedListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnErrorListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnScanListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnForcedPauseListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnForcedResetListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnBlockScanListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnRDSDataFoundListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnSignalStrengthListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnStereoListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnExtraCommandListener.aidl \
+ fmradio/java/com/stericsson/hardware/fm/IOnAutomaticSwitchListener.aidl
#
@@ -269,6 +283,8 @@ aidl_files := \
frameworks/base/core/java/android/accounts/IAccountAuthenticator.aidl \
frameworks/base/core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
frameworks/base/core/java/android/app/Notification.aidl \
+ frameworks/base/core/java/android/app/NotificationGroup.aidl \
+ frameworks/base/core/java/android/app/Profile.aidl \
frameworks/base/core/java/android/app/PendingIntent.aidl \
frameworks/base/core/java/android/bluetooth/BluetoothDevice.aidl \
frameworks/base/core/java/android/bluetooth/BluetoothHealthAppConfiguration.aidl \
@@ -554,7 +570,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
-LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES) framework
LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
@@ -789,7 +805,6 @@ LOCAL_DX_FLAGS := --core-library
include $(BUILD_JAVA_LIBRARY)
-
# Include subdirectory makefiles
# ============================================================
diff --git a/api/current.txt b/api/current.txt
index 6b893d5..c57a541 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9804,6 +9804,7 @@ package android.hardware {
method public int getJpegQuality();
method public int getJpegThumbnailQuality();
method public android.hardware.Camera.Size getJpegThumbnailSize();
+ method public java.lang.String getPowerMode();
method public int getMaxExposureCompensation();
method public int getMaxNumDetectedFaces();
method public int getMaxNumFocusAreas();
@@ -9840,6 +9841,7 @@ package android.hardware {
method public java.util.List<java.lang.Integer> getZoomRatios();
method public boolean isAutoExposureLockSupported();
method public boolean isAutoWhiteBalanceLockSupported();
+ method public boolean isPowerModeSupported();
method public boolean isSmoothZoomSupported();
method public boolean isVideoSnapshotSupported();
method public boolean isVideoStabilizationSupported();
@@ -9867,6 +9869,7 @@ package android.hardware {
method public void setMeteringAreas(java.util.List<android.hardware.Camera.Area>);
method public void setPictureFormat(int);
method public void setPictureSize(int, int);
+ method public void setPowerMode(java.lang.String);
method public void setPreviewFormat(int);
method public void setPreviewFpsRange(int, int);
method public deprecated void setPreviewFrameRate(int);
@@ -9906,6 +9909,8 @@ package android.hardware {
field public static final java.lang.String FOCUS_MODE_FIXED = "fixed";
field public static final java.lang.String FOCUS_MODE_INFINITY = "infinity";
field public static final java.lang.String FOCUS_MODE_MACRO = "macro";
+ field public static final java.lang.String LOW_POWER = "Low_Power";
+ field public static final java.lang.String NORMAL_POWER = "Normal_Power";
field public static final int PREVIEW_FPS_MAX_INDEX = 1; // 0x1
field public static final int PREVIEW_FPS_MIN_INDEX = 0; // 0x0
field public static final java.lang.String SCENE_MODE_ACTION = "action";
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 387f33d..d19db32 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -24,6 +24,7 @@
/* Directory records that are used in execution of commands. */
dir_rec_t android_data_dir;
+dir_rec_t android_datadata_dir;
dir_rec_t android_asec_dir;
dir_rec_t android_app_dir;
dir_rec_t android_app_private_dir;
@@ -600,6 +601,7 @@ int create_cache_path(char path[PKG_PATH_MAX], const char *src)
char *tmp;
int srclen;
int dstlen;
+ char dexopt_data_only[PROPERTY_VALUE_MAX];
srclen = strlen(src);
@@ -612,7 +614,15 @@ int create_cache_path(char path[PKG_PATH_MAX], const char *src)
return -1;
}
- dstlen = srclen + strlen(DALVIK_CACHE_PREFIX) +
+ const char *cache_path = DALVIK_CACHE_PREFIX;
+ if (!strncmp(src, "/system", 7)) {
+ property_get("dalvik.vm.dexopt-data-only", dexopt_data_only, "");
+ if (strcmp(dexopt_data_only, "1") != 0) {
+ cache_path = DALVIK_SYSTEM_CACHE_PREFIX;
+ }
+ }
+
+ dstlen = srclen + strlen(cache_path) +
strlen(DALVIK_CACHE_POSTFIX) + 1;
if (dstlen > PKG_PATH_MAX) {
@@ -620,11 +630,11 @@ int create_cache_path(char path[PKG_PATH_MAX], const char *src)
}
sprintf(path,"%s%s%s",
- DALVIK_CACHE_PREFIX,
+ cache_path,
src + 1, /* skip the leading / */
DALVIK_CACHE_POSTFIX);
- for(tmp = path + strlen(DALVIK_CACHE_PREFIX); *tmp; tmp++) {
+ for(tmp = path + strlen(cache_path); *tmp; tmp++) {
if (*tmp == '/') {
*tmp = '@';
}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 21d674a..17a1a1f 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -274,6 +274,11 @@ int initialize_globals() {
return -1;
}
+ // Get the android datadata directory.
+ if (copy_and_append(&android_datadata_dir, &android_data_dir, DATA_SUBDIR) < 0) {
+ return -1;
+ }
+
// Get the android app directory.
if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) {
return -1;
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 0500c23..a8461eb 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -60,6 +60,8 @@
#define CACHE_DIR_POSTFIX "/cache"
+#define DATA_SUBDIR "data/" // sub-directory under ANDROID_DATA
+
#define APP_SUBDIR "app/" // sub-directory under ANDROID_DATA
#define APP_LIB_SUBDIR "app-lib/" // sub-directory under ANDROID_DATA
@@ -72,6 +74,7 @@
#define DALVIK_CACHE_PREFIX "/data/dalvik-cache/"
#define DALVIK_CACHE_POSTFIX "/classes.dex"
+#define DALVIK_SYSTEM_CACHE_PREFIX "/cache/dalvik-cache/"
#define UPDATE_COMMANDS_DIR_PREFIX "/system/etc/updatecmds/"
@@ -97,6 +100,7 @@ extern dir_rec_t android_app_dir;
extern dir_rec_t android_app_private_dir;
extern dir_rec_t android_app_lib_dir;
extern dir_rec_t android_data_dir;
+extern dir_rec_t android_datadata_dir;
extern dir_rec_t android_asec_dir;
extern dir_rec_t android_media_dir;
extern dir_rec_array_t android_system_dirs;
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 625a35e..154a2f8 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -362,7 +362,11 @@ int lookup_media_dir(char basepath[PATH_MAX], const char *dir)
int64_t data_disk_free()
{
struct statfs sfs;
- if (statfs(android_data_dir.path, &sfs) == 0) {
+ /* Scanning /data/data because on some devices, it's on a different partition
+ * and scanning /data will yield the incorrect result. (This function is only
+ * used for freeing space on /data/data so it is okay to be more specific.)
+ */
+ if (statfs(android_datadata_dir.path, &sfs) == 0) {
return sfs.f_bavail * sfs.f_bsize;
} else {
ALOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno));
diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk
index 8840867..07860e5 100644
--- a/cmds/servicemanager/Android.mk
+++ b/cmds/servicemanager/Android.mk
@@ -9,4 +9,10 @@ include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := service_manager.c binder.c
LOCAL_MODULE := servicemanager
+ifeq ($(BOARD_USE_YAMAHAPLAYER),true)
+ LOCAL_CFLAGS += -DYAMAHAPLAYER
+endif
+ifeq ($(BOARD_USE_SECTVOUT),true)
+ LOCAL_CFLAGS += -DSECTVOUT
+endif
include $(BUILD_EXECUTABLE)
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 3314dc3..63823a3 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -31,6 +31,13 @@ static struct {
{ AID_MEDIA, "media.player" },
{ AID_MEDIA, "media.camera" },
{ AID_MEDIA, "media.audio_policy" },
+ { AID_MEDIA, "media.nvidia.audio_alsa" },
+#ifdef YAMAHAPLAYER
+ { AID_MEDIA, "media.yamahaplayer" },
+#endif
+#ifdef SECTVOUT
+ { AID_MEDIA, "SecTVOutService" },
+#endif
{ AID_DRM, "drm.drmManager" },
{ AID_NFC, "nfc" },
{ AID_BLUETOOTH, "bluetooth" },
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index acc8549..5b3b553 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -134,7 +134,6 @@ public class ChooseAccountTypeActivity extends Activity {
if (sequence != null) {
name = sequence.toString();
}
- name = sequence.toString();
} catch (PackageManager.NameNotFoundException e) {
// Nothing we can do much here, just log
if (Log.isLoggable(TAG, Log.WARN)) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 594be68..e4e0d8e 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +29,7 @@ import android.content.pm.ConfigurationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
@@ -1620,6 +1622,16 @@ public class ActivityManager {
return null;
}
}
+ /**
+ * @hide
+ */
+ public Configuration getConfiguration() {
+ try {
+ return ActivityManagerNative.getDefault().getConfiguration();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
/**
* Returns a list of application processes that are running on the device.
@@ -1986,4 +1998,17 @@ public class ActivityManager {
return false;
}
}
+
+ /**
+ * @throws SecurityException Throws SecurityException if the caller does
+ * not hold the {@link android.Manifest.permission#CHANGE_CONFIGURATION} permission.
+ *
+ * @hide
+ */
+ public void updateConfiguration(Configuration values) throws SecurityException {
+ try {
+ ActivityManagerNative.getDefault().updateConfiguration(values);
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d880817..7d448cb 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +17,23 @@
package android.app;
+import com.android.internal.app.IAssetRedirectionManager;
+import com.android.internal.os.BinderInternal;
+import com.android.internal.os.RuntimeInit;
+import com.android.internal.os.SamplingProfilerIntegration;
+
+import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
+
import android.app.backup.BackupAgent;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.IContentProvider;
-import android.content.Intent;
import android.content.IIntentReceiver;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
@@ -37,6 +46,8 @@ import android.content.pm.ServiceInfo;
import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.content.res.CustomTheme;
+import android.content.res.PackageRedirectionMap;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDebug;
@@ -50,6 +61,7 @@ import android.net.Proxy;
import android.net.ProxyProperties;
import android.opengl.GLUtils;
import android.os.AsyncTask;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -69,6 +81,7 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -79,6 +92,7 @@ import android.util.Slog;
import android.view.CompatibilityInfoHolder;
import android.view.Display;
import android.view.HardwareRenderer;
+import android.view.InflateException;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewManager;
@@ -88,13 +102,8 @@ import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.renderscript.RenderScript;
-import com.android.internal.os.BinderInternal;
-import com.android.internal.os.RuntimeInit;
-import com.android.internal.os.SamplingProfilerIntegration;
import com.android.internal.util.Objects;
-import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
@@ -161,6 +170,7 @@ public final class ActivityThread {
static ContextImpl mSystemContext = null;
static IPackageManager sPackageManager;
+ static IAssetRedirectionManager sAssetRedirectionManager;
final ApplicationThread mAppThread = new ApplicationThread();
final Looper mLooper = Looper.myLooper();
@@ -1510,9 +1520,10 @@ public final class ActivityThread {
final private int mDisplayId;
final private Configuration mOverrideConfiguration;
final private float mScale;
+ final private boolean mIsThemeable;
final private int mHash;
- ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
+ ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale, boolean isThemeable) {
mResDir = resDir;
mDisplayId = displayId;
if (overrideConfiguration != null) {
@@ -1522,12 +1533,14 @@ public final class ActivityThread {
}
mOverrideConfiguration = overrideConfiguration;
mScale = scale;
+ mIsThemeable = isThemeable;
int hash = 17;
hash = 31 * hash + mResDir.hashCode();
hash = 31 * hash + mDisplayId;
hash = 31 * hash + (mOverrideConfiguration != null
? mOverrideConfiguration.hashCode() : 0);
hash = 31 * hash + Float.floatToIntBits(mScale);
+ hash = 31 * hash + (mIsThemeable ? 1 : 0);
mHash = hash;
}
@@ -1559,7 +1572,7 @@ public final class ActivityThread {
if (mScale != peer.mScale) {
return false;
}
- return true;
+ return mIsThemeable == peer.mIsThemeable;
}
}
@@ -1594,6 +1607,18 @@ public final class ActivityThread {
mDefaultDisplayMetrics.clear();
}
+ // NOTE: this method can return null if the SystemServer is still
+ // initializing (for example, of another SystemServer component is accessing
+ // a resources object)
+ public static IAssetRedirectionManager getAssetRedirectionManager() {
+ if (sAssetRedirectionManager != null) {
+ return sAssetRedirectionManager;
+ }
+ IBinder b = ServiceManager.getService("assetredirection");
+ sAssetRedirectionManager = IAssetRedirectionManager.Stub.asInterface(b);
+ return sAssetRedirectionManager;
+ }
+
DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
@@ -1657,7 +1682,8 @@ public final class ActivityThread {
CompatibilityInfo compInfo) {
ResourcesKey key = new ResourcesKey(resDir,
displayId, overrideConfiguration,
- compInfo.applicationScale);
+ compInfo.applicationScale,
+ compInfo.isThemeable);
Resources r;
synchronized (mPackages) {
// Resources is app scale dependent.
@@ -1683,6 +1709,7 @@ public final class ActivityThread {
//}
AssetManager assets = new AssetManager();
+ assets.setThemeSupport(compInfo.isThemeable);
if (assets.addAssetPath(resDir) == 0) {
return null;
}
@@ -1702,6 +1729,18 @@ public final class ActivityThread {
} else {
config = getConfiguration();
}
+
+ /* Attach theme information to the resulting AssetManager when appropriate. */
+ if (compInfo.isThemeable && config != null) {
+ if (config.customTheme == null) {
+ config.customTheme = CustomTheme.getBootTheme();
+ }
+
+ if (!TextUtils.isEmpty(config.customTheme.getThemePackageName())) {
+ attachThemeAssets(assets, config.customTheme);
+ }
+ }
+
r = new Resources(assets, dm, config, compInfo);
if (false) {
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
@@ -1725,6 +1764,81 @@ public final class ActivityThread {
}
}
+ private void detachThemeAssets(AssetManager assets) {
+ String themePackageName = assets.getThemePackageName();
+ int themeCookie = assets.getThemeCookie();
+ if (!TextUtils.isEmpty(themePackageName) && themeCookie != 0) {
+ assets.detachThemePath(themePackageName, themeCookie);
+ assets.setThemePackageName(null);
+ assets.setThemeCookie(0);
+ assets.clearRedirections();
+ }
+ }
+
+ /**
+ * Attach the necessary theme asset paths and meta information to convert an
+ * AssetManager to being globally "theme-aware".
+ *
+ * @param assets
+ * @param theme
+ * @return true if the AssetManager is now theme-aware; false otherwise.
+ * This can fail, for example, if the theme package has been been
+ * removed and the theme manager has yet to revert formally back to
+ * the framework default.
+ */
+ private boolean attachThemeAssets(AssetManager assets, CustomTheme theme) {
+ IAssetRedirectionManager rm = getAssetRedirectionManager();
+ if (rm == null) {
+ return false;
+ }
+ PackageInfo pi = null;
+ try {
+ pi = getPackageManager().getPackageInfo(theme.getThemePackageName(), 0, 0);
+ } catch (RemoteException e) {
+ }
+ if (pi != null && pi.applicationInfo != null && pi.themeInfos != null) {
+ String themeResDir = pi.applicationInfo.publicSourceDir;
+ int cookie = assets.attachThemePath(themeResDir);
+ if (cookie != 0) {
+ String themePackageName = theme.getThemePackageName();
+ String themeId = theme.getThemeId();
+ int N = assets.getBasePackageCount();
+ for (int i = 0; i < N; i++) {
+ String packageName = assets.getBasePackageName(i);
+ int packageId = assets.getBasePackageId(i);
+
+ /*
+ * For now, we only consider redirections coming from the
+ * framework or regular android packages. This excludes
+ * themes and other specialty APKs we are not aware of.
+ */
+ if (packageId != 0x01 && packageId != 0x7f) {
+ continue;
+ }
+
+ try {
+ PackageRedirectionMap map = rm.getPackageRedirectionMap(themePackageName, themeId,
+ packageName);
+ if (map != null) {
+ assets.addRedirections(map);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure accessing package redirection map, removing theme support.");
+ assets.detachThemePath(themePackageName, cookie);
+ return false;
+ }
+ }
+
+ assets.setThemePackageName(theme.getThemePackageName());
+ assets.setThemeCookie(cookie);
+ return true;
+ } else {
+ Log.e(TAG, "Unable to attach theme assets at " + themeResDir);
+ }
+ }
+ return false;
+ }
+
/**
* Creates the top level resources for the given package.
*/
@@ -2177,6 +2291,16 @@ public final class ActivityThread {
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
+ if (e instanceof InflateException) {
+ Log.e(TAG, "Failed to inflate", e);
+ String pkg = null;
+ if (r.packageInfo != null && !TextUtils.isEmpty(r.packageInfo.getPackageName())) {
+ pkg = r.packageInfo.getPackageName();
+ }
+ Intent intent = new Intent(Intent.ACTION_APP_LAUNCH_FAILURE,
+ (pkg != null)? Uri.fromParts("package", pkg, null) : null);
+ getSystemContext().sendBroadcast(intent);
+ }
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
@@ -3817,7 +3941,7 @@ public final class ActivityThread {
}
}
- final boolean applyConfigurationToResourcesLocked(Configuration config,
+ final int applyConfigurationToResourcesLocked(Configuration config,
CompatibilityInfo compat) {
if (mResConfiguration == null) {
mResConfiguration = new Configuration();
@@ -3825,7 +3949,7 @@ public final class ActivityThread {
if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
+ mResConfiguration.seq + ", newSeq=" + config.seq);
- return false;
+ return 0;
}
int changes = mResConfiguration.updateFrom(config);
flushDisplayMetricsLocked();
@@ -3864,6 +3988,16 @@ public final class ActivityThread {
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
DisplayMetrics dm = defaultDisplayMetrics;
Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
+ boolean themeChanged = (changes & ActivityInfo.CONFIG_THEME_RESOURCE) != 0;
+ if (themeChanged) {
+ AssetManager am = r.getAssets();
+ if (am.hasThemeSupport()) {
+ detachThemeAssets(am);
+ if (!TextUtils.isEmpty(config.customTheme.getThemePackageName())) {
+ attachThemeAssets(am, config.customTheme);
+ }
+ }
+ }
if (!isDefaultDisplay || overrideConfig != null) {
if (tmpConfig == null) {
tmpConfig = new Configuration();
@@ -3880,6 +4014,9 @@ public final class ActivityThread {
} else {
r.updateConfiguration(config, dm, compat);
}
+ if (themeChanged) {
+ r.updateStringCache();
+ }
//Slog.i(TAG, "Updated app resources " + v.getKey()
// + " " + r + ": " + r.getConfiguration());
} else {
@@ -3888,7 +4025,7 @@ public final class ActivityThread {
}
}
- return changes != 0;
+ return changes;
}
final void applyNonDefaultDisplayMetricsToConfigurationLocked(
@@ -3930,6 +4067,8 @@ public final class ActivityThread {
int configDiff = 0;
+ int diff = 0;
+
synchronized (mPackages) {
if (mPendingConfiguration != null) {
if (!mPendingConfiguration.isOtherSeqNewer(config)) {
@@ -3947,7 +4086,7 @@ public final class ActivityThread {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
+ config);
- applyConfigurationToResourcesLocked(config, compat);
+ diff = applyConfigurationToResourcesLocked(config, compat);
if (mConfiguration == null) {
mConfiguration = new Configuration();
@@ -3970,7 +4109,20 @@ public final class ActivityThread {
if (callbacks != null) {
final int N = callbacks.size();
for (int i=0; i<N; i++) {
- performConfigurationChanged(callbacks.get(i), config);
+ ComponentCallbacks2 cb = callbacks.get(i);
+
+ // We removed the old resources object from the mActiveResources
+ // cache, now we need to trigger an update for each application.
+ if ((diff & ActivityInfo.CONFIG_THEME_RESOURCE) != 0) {
+ if (cb instanceof ContextWrapper) {
+ Context context = ((ContextWrapper)cb).getBaseContext();
+ if (context instanceof ContextImpl) {
+ ((ContextImpl)context).refreshResourcesIfNecessary();
+ }
+ }
+ }
+
+ performConfigurationChanged(cb, config);
}
}
}
@@ -4939,7 +5091,7 @@ public final class ActivityThread {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
- if (applyConfigurationToResourcesLocked(newConfig, null)) {
+ if (applyConfigurationToResourcesLocked(newConfig, null) != 0) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
diff --git a/core/java/android/app/AirplaneModeSettings.java b/core/java/android/app/AirplaneModeSettings.java
new file mode 100644
index 0000000..6861e66
--- /dev/null
+++ b/core/java/android/app/AirplaneModeSettings.java
@@ -0,0 +1,133 @@
+package android.app;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+
+import java.io.IOException;
+
+/** @hide */
+public final class AirplaneModeSettings implements Parcelable {
+
+ private int mValue;
+ private boolean mOverride;
+ private boolean mDirty;
+
+ /** @hide */
+ public static final Parcelable.Creator<AirplaneModeSettings> CREATOR = new Parcelable.Creator<AirplaneModeSettings>() {
+ public AirplaneModeSettings createFromParcel(Parcel in) {
+ return new AirplaneModeSettings(in);
+ }
+
+ @Override
+ public AirplaneModeSettings[] newArray(int size) {
+ return new AirplaneModeSettings[size];
+ }
+ };
+
+
+ public AirplaneModeSettings(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ public AirplaneModeSettings() {
+ this(0, false);
+ }
+
+ public AirplaneModeSettings(int value, boolean override) {
+ mValue = value;
+ mOverride = override;
+ mDirty = false;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ public void setValue(int value) {
+ mValue = value;
+ mDirty = true;
+ }
+
+ public void setOverride(boolean override) {
+ mOverride = override;
+ mDirty = true;
+ }
+
+ public boolean isOverride() {
+ return mOverride;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ public void processOverride(Context context) {
+ if (isOverride()) {
+ int current = Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
+ if (current != mValue) {
+ Settings.Global.putInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, mValue);
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", mValue == 1);
+ context.sendBroadcast(intent);
+ }
+ }
+ }
+
+ /** @hide */
+ public static AirplaneModeSettings fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ int event = xpp.next();
+ AirplaneModeSettings airplaneModeDescriptor = new AirplaneModeSettings();
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("airplaneModeDescriptor")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("value")) {
+ airplaneModeDescriptor.mValue = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("override")) {
+ airplaneModeDescriptor.mOverride = Boolean.parseBoolean(xpp.nextText());
+ }
+ }
+ event = xpp.next();
+ }
+ return airplaneModeDescriptor;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<airplaneModeDescriptor>\n<value>");
+ builder.append(mValue);
+ builder.append("</value>\n<override>");
+ builder.append(mOverride);
+ builder.append("</override>\n</airplaneModeDescriptor>\n");
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mOverride ? 1 : 0);
+ dest.writeInt(mValue);
+ dest.writeInt(mDirty ? 1 : 0);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mOverride = in.readInt() != 0;
+ mValue = in.readInt();
+ mDirty = in.readInt() != 0;
+ }
+
+
+}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 7431765..b93771f 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -429,6 +429,16 @@ final class ApplicationPackageManager extends PackageManager {
@SuppressWarnings("unchecked")
@Override
+ public List<PackageInfo> getInstalledThemePackages() {
+ try {
+ return mPM.getInstalledThemePackages();
+ } catch (RemoteException e) {
+ throw new RuntimeException("Package manager has died", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
public List<ApplicationInfo> getInstalledApplications(int flags) {
final int userId = mContext.getUserId();
try {
diff --git a/core/java/android/app/ConnectionSettings.java b/core/java/android/app/ConnectionSettings.java
new file mode 100755
index 0000000..00af439
--- /dev/null
+++ b/core/java/android/app/ConnectionSettings.java
@@ -0,0 +1,216 @@
+package android.app;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.location.LocationManager;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.net.wimax.WimaxHelper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.Settings;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/** @hide */
+public final class ConnectionSettings implements Parcelable {
+
+ private int mConnectionId;
+ private int mValue;
+ private boolean mOverride;
+ private boolean mDirty;
+
+ public static final int PROFILE_CONNECTION_MOBILEDATA = 0;
+ public static final int PROFILE_CONNECTION_WIFI = 1;
+ public static final int PROFILE_CONNECTION_WIFIAP = 2;
+ public static final int PROFILE_CONNECTION_WIMAX = 3;
+ public static final int PROFILE_CONNECTION_GPS = 4;
+ public static final int PROFILE_CONNECTION_SYNC = 5;
+ public static final int PROFILE_CONNECTION_BLUETOOTH = 7;
+
+ /** @hide */
+ public static final Parcelable.Creator<ConnectionSettings> CREATOR = new Parcelable.Creator<ConnectionSettings>() {
+ public ConnectionSettings createFromParcel(Parcel in) {
+ return new ConnectionSettings(in);
+ }
+
+ @Override
+ public ConnectionSettings[] newArray(int size) {
+ return new ConnectionSettings[size];
+ }
+ };
+
+
+ public ConnectionSettings(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ public ConnectionSettings(int connectionId) {
+ this(connectionId, 0, false);
+ }
+
+ public ConnectionSettings(int connectionId, int value, boolean override) {
+ mConnectionId = connectionId;
+ mValue = value;
+ mOverride = override;
+ mDirty = false;
+ }
+
+ public int getConnectionId() {
+ return mConnectionId;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ public void setValue(int value) {
+ mValue = value;
+ mDirty = true;
+ }
+
+ public void setOverride(boolean override) {
+ mOverride = override;
+ mDirty = true;
+ }
+
+ public boolean isOverride() {
+ return mOverride;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ public void processOverride(Context context) {
+ BluetoothAdapter bta = BluetoothAdapter.getDefaultAdapter();
+ LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ boolean forcedState = getValue() == 1;
+ boolean currentState;
+
+ switch (getConnectionId()) {
+ case PROFILE_CONNECTION_MOBILEDATA:
+ currentState = cm.getMobileDataEnabled();
+ if (forcedState != currentState) {
+ cm.setMobileDataEnabled(forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_BLUETOOTH:
+ currentState = bta.isEnabled();
+ if (forcedState && !currentState) {
+ bta.enable();
+ } else if (!forcedState && currentState) {
+ bta.disable();
+ }
+ break;
+ case PROFILE_CONNECTION_GPS:
+ currentState = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
+ if (currentState != forcedState) {
+ Settings.Secure.setLocationProviderEnabled(context.getContentResolver(),
+ LocationManager.GPS_PROVIDER, forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_SYNC:
+ currentState = ContentResolver.getMasterSyncAutomatically();
+ if (forcedState != currentState) {
+ ContentResolver.setMasterSyncAutomatically(forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_WIFI:
+ int wifiApState = wm.getWifiApState();
+ currentState = wm.isWifiEnabled();
+ if (currentState != forcedState) {
+ // Disable wifi tether
+ if (forcedState && (wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
+ (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED)) {
+ wm.setWifiApEnabled(null, false);
+ }
+ wm.setWifiEnabled(forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_WIFIAP:
+ int wifiState = wm.getWifiState();
+ currentState = wm.isWifiApEnabled();
+ if (currentState != forcedState) {
+ // Disable wifi
+ if (forcedState && (wifiState == WifiManager.WIFI_STATE_ENABLING) || (wifiState == WifiManager.WIFI_STATE_ENABLED)) {
+ wm.setWifiEnabled(false);
+ }
+ wm.setWifiApEnabled(null, forcedState);
+ }
+ break;
+ case PROFILE_CONNECTION_WIMAX:
+ if (WimaxHelper.isWimaxSupported(context)) {
+ currentState = WimaxHelper.isWimaxEnabled(context);
+ if (currentState != forcedState) {
+ WimaxHelper.setWimaxEnabled(context, forcedState);
+ }
+ }
+ break;
+ }
+ }
+
+ /** @hide */
+ public static ConnectionSettings fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ int event = xpp.next();
+ ConnectionSettings connectionDescriptor = new ConnectionSettings(0);
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("connectionDescriptor")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("connectionId")) {
+ connectionDescriptor.mConnectionId = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("value")) {
+ connectionDescriptor.mValue = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("override")) {
+ connectionDescriptor.mOverride = Boolean.parseBoolean(xpp.nextText());
+ }
+ }
+ event = xpp.next();
+ }
+ return connectionDescriptor;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<connectionDescriptor>\n<connectionId>");
+ builder.append(mConnectionId);
+ builder.append("</connectionId>\n<value>");
+ builder.append(mValue);
+ builder.append("</value>\n<override>");
+ builder.append(mOverride);
+ builder.append("</override>\n</connectionDescriptor>\n");
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mConnectionId);
+ dest.writeInt(mOverride ? 1 : 0);
+ dest.writeInt(mValue);
+ dest.writeInt(mDirty ? 1 : 0);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mConnectionId = in.readInt();
+ mOverride = in.readInt() != 0;
+ mValue = in.readInt();
+ mDirty = in.readInt() != 0;
+ }
+
+
+}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f895ccc..4d9f11e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +20,8 @@ package android.app;
import com.android.internal.policy.PolicyManager;
import com.android.internal.util.Preconditions;
+import android.accounts.AccountManager;
+import android.accounts.IAccountManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -26,9 +29,9 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.IContentProvider;
+import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.IIntentReceiver;
import android.content.IntentSender;
import android.content.ReceiverCallNotAllowedException;
import android.content.ServiceConnection;
@@ -40,6 +43,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.content.res.CustomTheme;
import android.content.res.Resources;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
@@ -74,6 +78,8 @@ import android.net.wifi.IWifiManager;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.IWifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wimax.WimaxHelper;
+import android.net.wimax.WimaxManagerConstants;
import android.nfc.NfcManager;
import android.os.Binder;
import android.os.Bundle;
@@ -120,6 +126,13 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import com.stericsson.hardware.fm.IFmReceiver;
+import com.stericsson.hardware.fm.IFmTransmitter;
+import com.stericsson.hardware.fm.FmReceiver;
+import com.stericsson.hardware.fm.FmTransmitter;
+import com.stericsson.hardware.fm.FmReceiverImpl;
+import com.stericsson.hardware.fm.FmTransmitterImpl;
+
class ReceiverRestrictedContext extends ContextWrapper {
ReceiverRestrictedContext(Context base) {
super(base);
@@ -535,6 +548,31 @@ class ContextImpl extends Context {
IUserManager service = IUserManager.Stub.asInterface(b);
return new UserManager(ctx, service);
}});
+
+ registerService(PROFILE_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ final Context outerContext = ctx.getOuterContext();
+ return new ProfileManager (outerContext, ctx.mMainThread.getHandler());
+ }});
+
+ registerService(WimaxManagerConstants.WIMAX_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return WimaxHelper.createWimaxService(ctx, ctx.mMainThread.getHandler());
+ }});
+
+ registerService("fm_receiver", new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService("fm_receiver");
+ IFmReceiver service = IFmReceiver.Stub.asInterface(b);
+ return new FmReceiverImpl(service);
+ }});
+
+ registerService("fm_transmitter", new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService("fm_transmitter");
+ IFmTransmitter service = IFmTransmitter.Stub.asInterface(b);
+ return new FmTransmitterImpl(service);
+ }});
}
static ContextImpl getImpl(Context context) {
@@ -561,6 +599,20 @@ class ContextImpl extends Context {
return mResources;
}
+ /**
+ * Refresh resources object which may have been changed by a theme
+ * configuration change.
+ */
+ /* package */ void refreshResourcesIfNecessary() {
+ if (mResources == Resources.getSystem()) {
+ return;
+ }
+
+ if (mPackageInfo.mCompatibilityInfo.get().isThemeable) {
+ mTheme = null;
+ }
+ }
+
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
diff --git a/core/java/android/app/IProfileManager.aidl b/core/java/android/app/IProfileManager.aidl
new file mode 100644
index 0000000..c7c6744
--- /dev/null
+++ b/core/java/android/app/IProfileManager.aidl
@@ -0,0 +1,50 @@
+/* //device/java/android/android/app/IProfileManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.app;
+
+import android.app.Profile;
+import android.app.NotificationGroup;
+import android.os.ParcelUuid;
+
+/** {@hide} */
+interface IProfileManager
+{
+ boolean setActiveProfile(in ParcelUuid profileParcelUuid);
+ boolean setActiveProfileByName(String profileName);
+ Profile getActiveProfile();
+
+ boolean addProfile(in Profile profile);
+ boolean removeProfile(in Profile profile);
+ void updateProfile(in Profile profile);
+
+ Profile getProfile(in ParcelUuid profileParcelUuid);
+ Profile getProfileByName(String profileName);
+ Profile[] getProfiles();
+ boolean profileExists(in ParcelUuid profileUuid);
+ boolean profileExistsByName(String profileName);
+ boolean notificationGroupExistsByName(String notificationGroupName);
+
+ NotificationGroup[] getNotificationGroups();
+ void addNotificationGroup(in NotificationGroup group);
+ void removeNotificationGroup(in NotificationGroup group);
+ void updateNotificationGroup(in NotificationGroup group);
+ NotificationGroup getNotificationGroupForPackage(in String pkg);
+ NotificationGroup getNotificationGroup(in ParcelUuid groupParcelUuid);
+
+ void resetAll();
+}
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index a1a147a..28786b7 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -175,7 +175,7 @@ public class MediaRouteButton extends View {
Toast cheatSheet = Toast.makeText(context, contentDesc, Toast.LENGTH_SHORT);
if (midy < displayFrame.height()) {
// Show along the top; follow action buttons
- cheatSheet.setGravity(Gravity.TOP | Gravity.END,
+ cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT,
screenWidth - screenPos[0] - width / 2, height);
} else {
// Show along the bottom center
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3f8e16c..8e920cc 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -437,6 +437,15 @@ public class Notification implements Parcelable
*/
public static final String EXTRA_PEOPLE = "android.people";
+ /**
+ * Bit to be bitwise-ored into the {@link #flags} field that should be
+ * set if this notification should force the led to pulse even if the
+ * screen has been shut off while the notification was active.
+ *
+ * @hide
+ */
+ public static final int FLAG_FORCE_LED_SCREEN_OFF = 0x00000100;
+
private Bundle extras;
/**
diff --git a/core/java/android/app/NotificationGroup.aidl b/core/java/android/app/NotificationGroup.aidl
new file mode 100644
index 0000000..44b6290
--- /dev/null
+++ b/core/java/android/app/NotificationGroup.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2012, The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+parcelable NotificationGroup;
diff --git a/core/java/android/app/NotificationGroup.java b/core/java/android/app/NotificationGroup.java
new file mode 100644
index 0000000..bcb70d3
--- /dev/null
+++ b/core/java/android/app/NotificationGroup.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+/** @hide */
+public class NotificationGroup implements Parcelable {
+ private static final String TAG = "NotificationGroup";
+
+ private String mName;
+ private int mNameResId;
+
+ private UUID mUuid;
+
+ private Set<String> mPackages = new HashSet<String>();
+
+ private boolean mDirty;
+
+ public static final Parcelable.Creator<NotificationGroup> CREATOR = new Parcelable.Creator<NotificationGroup>() {
+ public NotificationGroup createFromParcel(Parcel in) {
+ return new NotificationGroup(in);
+ }
+
+ @Override
+ public NotificationGroup[] newArray(int size) {
+ return new NotificationGroup[size];
+ }
+ };
+
+ public NotificationGroup(String name) {
+ this(name, -1, null);
+ }
+
+ public NotificationGroup(String name, int nameResId, UUID uuid) {
+ mName = name;
+ mNameResId = nameResId;
+ mUuid = (uuid != null) ? uuid : UUID.randomUUID();
+ mDirty = uuid == null;
+ }
+
+ private NotificationGroup(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ mNameResId = -1;
+ mDirty = true;
+ }
+
+ public UUID getUuid() {
+ return mUuid;
+ }
+
+ public void addPackage(String pkg) {
+ mPackages.add(pkg);
+ mDirty = true;
+ }
+
+ public String[] getPackages() {
+ return mPackages.toArray(new String[mPackages.size()]);
+ }
+
+ public void removePackage(String pkg) {
+ mPackages.remove(pkg);
+ mDirty = true;
+ }
+
+ public boolean hasPackage(String pkg) {
+ return mPackages.contains(pkg);
+ }
+
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mName);
+ dest.writeInt(mNameResId);
+ dest.writeInt(mDirty ? 1 : 0);
+ new ParcelUuid(mUuid).writeToParcel(dest, 0);
+ dest.writeStringArray(getPackages());
+ }
+
+ public void readFromParcel(Parcel in) {
+ mName = in.readString();
+ mNameResId = in.readInt();
+ mDirty = in.readInt() != 0;
+ mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid();
+ mPackages.addAll(Arrays.asList(in.readStringArray()));
+ }
+
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<notificationGroup ");
+ if (mNameResId > 0) {
+ builder.append("nameres=\"");
+ builder.append(context.getResources().getResourceEntryName(mNameResId));
+ } else {
+ builder.append("name=\"");
+ builder.append(TextUtils.htmlEncode(getName()));
+ }
+ builder.append("\" uuid=\"");
+ builder.append(TextUtils.htmlEncode(getUuid().toString()));
+ builder.append("\">\n");
+ for (String pkg : mPackages) {
+ builder.append("<package>" + TextUtils.htmlEncode(pkg) + "</package>\n");
+ }
+ builder.append("</notificationGroup>\n");
+ mDirty = false;
+ }
+
+ public static NotificationGroup fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ String value = xpp.getAttributeValue(null, "nameres");
+ int nameResId = -1;
+ String name = null;
+ UUID uuid = null;
+
+ if (value != null) {
+ nameResId = context.getResources().getIdentifier(value, "string", "android");
+ if (nameResId > 0) {
+ name = context.getResources().getString(nameResId);
+ }
+ }
+
+ if (name == null) {
+ name = xpp.getAttributeValue(null, "name");
+ }
+
+ value = xpp.getAttributeValue(null, "uuid");
+ if (value != null) {
+ try {
+ uuid = UUID.fromString(value);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "UUID not recognized for " + name + ", using new one.");
+ }
+ }
+
+ NotificationGroup notificationGroup = new NotificationGroup(name, nameResId, uuid);
+ int event = xpp.next();
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("notificationGroup")) {
+ if (event == XmlPullParser.START_TAG) {
+ if (xpp.getName().equals("package")) {
+ String pkg = xpp.nextText();
+ notificationGroup.addPackage(pkg);
+ }
+ }
+ event = xpp.next();
+ }
+
+ /* we just loaded from XML, no need to save */
+ notificationGroup.mDirty = false;
+
+ return notificationGroup;
+ }
+}
diff --git a/core/java/android/app/Profile.aidl b/core/java/android/app/Profile.aidl
new file mode 100644
index 0000000..d75bd76
--- /dev/null
+++ b/core/java/android/app/Profile.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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 android.app;
+
+parcelable Profile;
diff --git a/core/java/android/app/Profile.java b/core/java/android/app/Profile.java
new file mode 100644
index 0000000..41250eb
--- /dev/null
+++ b/core/java/android/app/Profile.java
@@ -0,0 +1,554 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * @hide
+ */
+public final class Profile implements Parcelable, Comparable {
+
+ private String mName;
+
+ private int mNameResId;
+
+ private UUID mUuid;
+
+ private ArrayList<UUID> mSecondaryUuids = new ArrayList<UUID>();
+
+ private Map<UUID, ProfileGroup> profileGroups = new HashMap<UUID, ProfileGroup>();
+
+ private ProfileGroup mDefaultGroup;
+
+ private boolean mStatusBarIndicator = false;
+
+ private boolean mDirty;
+
+ private static final String TAG = "Profile";
+
+ private int mProfileType;
+
+ private static final int CONDITIONAL_TYPE = 1;
+
+ private static final int TOGGLE_TYPE = 0;
+
+ private Map<Integer, StreamSettings> streams = new HashMap<Integer, StreamSettings>();
+
+ private Map<Integer, ConnectionSettings> connections = new HashMap<Integer, ConnectionSettings>();
+
+ private RingModeSettings mRingMode = new RingModeSettings();
+
+ private AirplaneModeSettings mAirplaneMode = new AirplaneModeSettings();
+
+ private int mScreenLockMode = LockMode.DEFAULT;
+
+ /** @hide */
+ public static class LockMode {
+ public static final int DEFAULT = 0;
+ public static final int INSECURE = 1;
+ public static final int DISABLE = 2;
+ }
+
+ /** @hide */
+ public static final Parcelable.Creator<Profile> CREATOR = new Parcelable.Creator<Profile>() {
+ public Profile createFromParcel(Parcel in) {
+ return new Profile(in);
+ }
+
+ @Override
+ public Profile[] newArray(int size) {
+ return new Profile[size];
+ }
+ };
+
+ /** @hide */
+ public Profile(String name) {
+ this(name, -1, UUID.randomUUID());
+ }
+
+ private Profile(String name, int nameResId, UUID uuid) {
+ mName = name;
+ mNameResId = nameResId;
+ mUuid = uuid;
+ mProfileType = TOGGLE_TYPE; //Default to toggle type
+ mDirty = false;
+ }
+
+ private Profile(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int compareTo(Object obj)
+ {
+ Profile tmp = (Profile) obj;
+ if (mName.compareTo(tmp.mName) < 0) {
+ return -1;
+ } else if (mName.compareTo(tmp.mName) > 0) {
+ return 1;
+ }
+ return 0;
+ }
+
+ /** @hide */
+ public void addProfileGroup(ProfileGroup value) {
+ if (value.isDefaultGroup()) {
+ /* we must not have more than one default group */
+ if (mDefaultGroup != null) {
+ return;
+ }
+ mDefaultGroup = value;
+ }
+ profileGroups.put(value.getUuid(), value);
+ mDirty = true;
+ }
+
+ /** @hide */
+ public void removeProfileGroup(UUID uuid) {
+ if (!profileGroups.get(uuid).isDefaultGroup()) {
+ profileGroups.remove(uuid);
+ } else {
+ Log.e(TAG, "Cannot remove default group: " + uuid);
+ }
+ }
+
+ public ProfileGroup[] getProfileGroups() {
+ return profileGroups.values().toArray(new ProfileGroup[profileGroups.size()]);
+ }
+
+ public ProfileGroup getProfileGroup(UUID uuid) {
+ return profileGroups.get(uuid);
+ }
+
+ public ProfileGroup getDefaultGroup() {
+ return mDefaultGroup;
+ }
+
+ /** @hide */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mName);
+ dest.writeInt(mNameResId);
+ new ParcelUuid(mUuid).writeToParcel(dest, 0);
+ ArrayList<ParcelUuid> uuids = new ArrayList<ParcelUuid>(mSecondaryUuids.size());
+ for (UUID u : mSecondaryUuids) {
+ uuids.add(new ParcelUuid(u));
+ }
+ dest.writeParcelableArray(uuids.toArray(new Parcelable[uuids.size()]), flags);
+ dest.writeInt(mStatusBarIndicator ? 1 : 0);
+ dest.writeInt(mProfileType);
+ dest.writeInt(mDirty ? 1 : 0);
+ dest.writeParcelableArray(
+ profileGroups.values().toArray(new Parcelable[profileGroups.size()]), flags);
+ dest.writeParcelableArray(
+ streams.values().toArray(new Parcelable[streams.size()]), flags);
+ dest.writeParcelableArray(
+ connections.values().toArray(new Parcelable[connections.size()]), flags);
+ dest.writeParcelable(mRingMode, flags);
+ dest.writeParcelable(mAirplaneMode, flags);
+ dest.writeInt(mScreenLockMode);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mName = in.readString();
+ mNameResId = in.readInt();
+ mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid();
+ for (Parcelable parcel : in.readParcelableArray(null)) {
+ ParcelUuid u = (ParcelUuid) parcel;
+ mSecondaryUuids.add(u.getUuid());
+ }
+ mStatusBarIndicator = (in.readInt() == 1);
+ mProfileType = in.readInt();
+ mDirty = (in.readInt() == 1);
+ for (Parcelable group : in.readParcelableArray(null)) {
+ ProfileGroup grp = (ProfileGroup) group;
+ profileGroups.put(grp.getUuid(), grp);
+ if (grp.isDefaultGroup()) {
+ mDefaultGroup = grp;
+ }
+ }
+ for (Parcelable parcel : in.readParcelableArray(null)) {
+ StreamSettings stream = (StreamSettings) parcel;
+ streams.put(stream.getStreamId(), stream);
+ }
+ for (Parcelable parcel : in.readParcelableArray(null)) {
+ ConnectionSettings connection = (ConnectionSettings) parcel;
+ connections.put(connection.getConnectionId(), connection);
+ }
+ mRingMode = (RingModeSettings) in.readParcelable(null);
+ mAirplaneMode = (AirplaneModeSettings) in.readParcelable(null);
+ mScreenLockMode = in.readInt();
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ /** @hide */
+ public void setName(String name) {
+ mName = name;
+ mNameResId = -1;
+ mDirty = true;
+ }
+
+ public int getProfileType() {
+ return mProfileType;
+ }
+
+ /** @hide */
+ public void setProfileType(int type) {
+ mProfileType = type;
+ mDirty = true;
+ }
+
+ public UUID getUuid() {
+ if (this.mUuid == null) this.mUuid = UUID.randomUUID();
+ return this.mUuid;
+ }
+
+ public UUID[] getSecondaryUuids() {
+ return mSecondaryUuids.toArray(new UUID[mSecondaryUuids.size()]);
+ }
+
+ public void setSecondaryUuids(List<UUID> uuids) {
+ mSecondaryUuids.clear();
+ if (uuids != null) {
+ mSecondaryUuids.addAll(uuids);
+ mDirty = true;
+ }
+ }
+
+ public void addSecondaryUuid(UUID uuid) {
+ if (uuid != null) {
+ mSecondaryUuids.add(uuid);
+ mDirty = true;
+ }
+ }
+
+ public boolean getStatusBarIndicator() {
+ return mStatusBarIndicator;
+ }
+
+ public void setStatusBarIndicator(boolean newStatusBarIndicator) {
+ mStatusBarIndicator = newStatusBarIndicator;
+ mDirty = true;
+ }
+
+ public boolean isConditionalType() {
+ return(mProfileType == CONDITIONAL_TYPE ? true : false);
+ }
+
+ public void setConditionalType() {
+ mProfileType = CONDITIONAL_TYPE;
+ mDirty = true;
+ }
+
+ public RingModeSettings getRingMode() {
+ return mRingMode;
+ }
+
+ public void setRingMode(RingModeSettings descriptor) {
+ mRingMode = descriptor;
+ mDirty = true;
+ }
+
+ public int getScreenLockMode() {
+ return mScreenLockMode;
+ }
+
+ public void setScreenLockMode(int screenLockMode) {
+ if (screenLockMode < LockMode.DEFAULT || screenLockMode > LockMode.DISABLE) {
+ mScreenLockMode = LockMode.DEFAULT;
+ } else {
+ mScreenLockMode = screenLockMode;
+ }
+ mDirty = true;
+ }
+
+ public AirplaneModeSettings getAirplaneMode() {
+ return mAirplaneMode;
+ }
+
+ public void setAirplaneMode(AirplaneModeSettings descriptor) {
+ mAirplaneMode = descriptor;
+ mDirty = true;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ if (mDirty) {
+ return true;
+ }
+ for (ProfileGroup group : profileGroups.values()) {
+ if (group.isDirty()) {
+ return true;
+ }
+ }
+ for (StreamSettings stream : streams.values()) {
+ if (stream.isDirty()) {
+ return true;
+ }
+ }
+ for (ConnectionSettings conn : connections.values()) {
+ if (conn.isDirty()) {
+ return true;
+ }
+ }
+ if (mRingMode.isDirty()) {
+ return true;
+ }
+ if (mAirplaneMode.isDirty()) {
+ return true;
+ }
+ return false;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<profile ");
+ if (mNameResId > 0) {
+ builder.append("nameres=\"");
+ builder.append(context.getResources().getResourceEntryName(mNameResId));
+ } else {
+ builder.append("name=\"");
+ builder.append(TextUtils.htmlEncode(getName()));
+ }
+ builder.append("\" uuid=\"");
+ builder.append(TextUtils.htmlEncode(getUuid().toString()));
+ builder.append("\">\n");
+
+ builder.append("<uuids>");
+ for (UUID u : mSecondaryUuids) {
+ builder.append("<uuid>");
+ builder.append(TextUtils.htmlEncode(u.toString()));
+ builder.append("</uuid>");
+ }
+ builder.append("</uuids>\n");
+
+ builder.append("<profiletype>");
+ builder.append(getProfileType() == TOGGLE_TYPE ? "toggle" : "conditional");
+ builder.append("</profiletype>\n");
+
+ builder.append("<statusbar>");
+ builder.append(getStatusBarIndicator() ? "yes" : "no");
+ builder.append("</statusbar>\n");
+
+ builder.append("<screen-lock-mode>");
+ builder.append(mScreenLockMode);
+ builder.append("</screen-lock-mode>\n");
+
+ mAirplaneMode.getXmlString(builder, context);
+
+ mRingMode.getXmlString(builder, context);
+
+ for (ProfileGroup pGroup : profileGroups.values()) {
+ pGroup.getXmlString(builder, context);
+ }
+ for (StreamSettings sd : streams.values()) {
+ sd.getXmlString(builder, context);
+ }
+ for (ConnectionSettings cs : connections.values()) {
+ cs.getXmlString(builder, context);
+ }
+ builder.append("</profile>\n");
+ mDirty = false;
+ }
+
+ private static List<UUID> readSecondaryUuidsFromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException,
+ IOException {
+ ArrayList<UUID> uuids = new ArrayList<UUID>();
+ int event = xpp.next();
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("uuids")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("uuid")) {
+ try {
+ uuids.add(UUID.fromString(xpp.nextText()));
+ } catch (NullPointerException e) {
+ Log.w(TAG, "Null Pointer - invalid UUID");
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "UUID not recognized");
+ }
+ }
+ }
+ event = xpp.next();
+ }
+ return uuids;
+ }
+
+ /** @hide */
+ public static Profile fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ String value = xpp.getAttributeValue(null, "nameres");
+ int profileNameResId = -1;
+ String profileName = null;
+
+ if (value != null) {
+ profileNameResId = context.getResources().getIdentifier(value, "string", "android");
+ if (profileNameResId > 0) {
+ profileName = context.getResources().getString(profileNameResId);
+ }
+ }
+
+ if (profileName == null) {
+ profileName = xpp.getAttributeValue(null, "name");
+ }
+
+ UUID profileUuid = UUID.randomUUID();
+ try {
+ profileUuid = UUID.fromString(xpp.getAttributeValue(null, "uuid"));
+ } catch (NullPointerException e) {
+ Log.w(TAG,
+ "Null Pointer - UUID not found for "
+ + profileName
+ + ". New UUID generated: "
+ + profileUuid.toString()
+ );
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG,
+ "UUID not recognized for "
+ + profileName
+ + ". New UUID generated: "
+ + profileUuid.toString()
+ );
+ }
+
+ Profile profile = new Profile(profileName, profileNameResId, profileUuid);
+ int event = xpp.next();
+ while (event != XmlPullParser.END_TAG) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("uuids")) {
+ profile.setSecondaryUuids(readSecondaryUuidsFromXml(xpp, context));
+ }
+ if (name.equals("statusbar")) {
+ profile.setStatusBarIndicator(xpp.nextText().equals("yes"));
+ }
+ if (name.equals("profiletype")) {
+ profile.setProfileType(xpp.nextText().equals("toggle") ? TOGGLE_TYPE : CONDITIONAL_TYPE);
+ }
+ if (name.equals("ringModeDescriptor")) {
+ RingModeSettings smd = RingModeSettings.fromXml(xpp, context);
+ profile.setRingMode(smd);
+ }
+ if (name.equals("airplaneModeDescriptor")) {
+ AirplaneModeSettings amd = AirplaneModeSettings.fromXml(xpp, context);
+ profile.setAirplaneMode(amd);
+ }
+ if (name.equals("screen-lock-mode")) {
+ profile.setScreenLockMode(Integer.valueOf(xpp.nextText()));
+ }
+ if (name.equals("profileGroup")) {
+ ProfileGroup pg = ProfileGroup.fromXml(xpp, context);
+ profile.addProfileGroup(pg);
+ }
+ if (name.equals("streamDescriptor")) {
+ StreamSettings sd = StreamSettings.fromXml(xpp, context);
+ profile.setStreamSettings(sd);
+ }
+ if (name.equals("connectionDescriptor")) {
+ ConnectionSettings cs = ConnectionSettings.fromXml(xpp, context);
+ profile.connections.put(cs.getConnectionId(), cs);
+ }
+ }
+ event = xpp.next();
+ }
+
+ /* we just loaded from XML, so nothing needs saving */
+ profile.mDirty = false;
+
+ return profile;
+ }
+
+ /** @hide */
+ public void doSelect(Context context) {
+ // Set stream volumes
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ for (StreamSettings sd : streams.values()) {
+ if (sd.isOverride()) {
+ am.setStreamVolume(sd.getStreamId(), sd.getValue(), 0);
+ }
+ }
+ // Set connections
+ for (ConnectionSettings cs : connections.values()) {
+ if (cs.isOverride()) {
+ cs.processOverride(context);
+ }
+ }
+ // Set ring mode
+ mRingMode.processOverride(context);
+ // Set airplane mode
+ mAirplaneMode.processOverride(context);
+ }
+
+ /** @hide */
+ public StreamSettings getSettingsForStream(int streamId){
+ return streams.get(streamId);
+ }
+
+ /** @hide */
+ public void setStreamSettings(StreamSettings descriptor){
+ streams.put(descriptor.getStreamId(), descriptor);
+ mDirty = true;
+ }
+
+ /** @hide */
+ public Collection<StreamSettings> getStreamSettings(){
+ return streams.values();
+ }
+
+ /** @hide */
+ public ConnectionSettings getSettingsForConnection(int connectionId){
+ return connections.get(connectionId);
+ }
+
+ /** @hide */
+ public void setConnectionSettings(ConnectionSettings descriptor){
+ connections.put(descriptor.getConnectionId(), descriptor);
+ }
+
+ /** @hide */
+ public Collection<ConnectionSettings> getConnectionSettings(){
+ return connections.values();
+ }
+
+}
diff --git a/core/java/android/app/ProfileGroup.java b/core/java/android/app/ProfileGroup.java
new file mode 100644
index 0000000..b3b70d6
--- /dev/null
+++ b/core/java/android/app/ProfileGroup.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelUuid;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.UUID;
+
+/**
+ * @hide
+ */
+public final class ProfileGroup implements Parcelable {
+ private static final String TAG = "ProfileGroup";
+
+ private String mName;
+ private int mNameResId;
+
+ private UUID mUuid;
+
+ private Uri mSoundOverride = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
+ private Uri mRingerOverride = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
+
+ private Mode mSoundMode = Mode.DEFAULT;
+ private Mode mRingerMode = Mode.DEFAULT;
+ private Mode mVibrateMode = Mode.DEFAULT;
+ private Mode mLightsMode = Mode.DEFAULT;
+
+ private boolean mDefaultGroup = false;
+ private boolean mDirty;
+
+ /** @hide */
+ public static final Parcelable.Creator<ProfileGroup> CREATOR = new Parcelable.Creator<ProfileGroup>() {
+ public ProfileGroup createFromParcel(Parcel in) {
+ return new ProfileGroup(in);
+ }
+
+ @Override
+ public ProfileGroup[] newArray(int size) {
+ return new ProfileGroup[size];
+ }
+ };
+
+ /** @hide */
+ public ProfileGroup(UUID uuid, boolean defaultGroup) {
+ this(null, uuid, defaultGroup);
+ }
+
+ private ProfileGroup(String name, UUID uuid, boolean defaultGroup) {
+ mName = name;
+ mUuid = (uuid != null) ? uuid : UUID.randomUUID();
+ mDefaultGroup = defaultGroup;
+ mDirty = uuid == null;
+ }
+
+ /** @hide */
+ private ProfileGroup(Parcel in) {
+ readFromParcel(in);
+ }
+
+ /** @hide */
+ public boolean matches(NotificationGroup group, boolean defaultGroup) {
+ if (mUuid.equals(group.getUuid())) {
+ return true;
+ }
+
+ /* fallback matches for backwards compatibility */
+ boolean matches = false;
+
+ /* fallback attempt 1: match name */
+ if (mName != null && mName.equals(group.getName())) {
+ matches = true;
+ /* fallback attempt 2: match for the 'defaultGroup' flag to match the wildcard group */
+ } else if (mDefaultGroup && defaultGroup) {
+ matches = true;
+ }
+
+ if (!matches) {
+ return false;
+ }
+
+ mName = null;
+ mUuid = group.getUuid();
+ mDirty = true;
+
+ return true;
+ }
+
+ public UUID getUuid() {
+ return mUuid;
+ }
+
+ public boolean isDefaultGroup() {
+ return mDefaultGroup;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ /** @hide */
+ public void setSoundOverride(Uri sound) {
+ mSoundOverride = sound;
+ mDirty = true;
+ }
+
+ public Uri getSoundOverride() {
+ return mSoundOverride;
+ }
+
+ /** @hide */
+ public void setRingerOverride(Uri ringer) {
+ mRingerOverride = ringer;
+ mDirty = true;
+ }
+
+ public Uri getRingerOverride() {
+ return mRingerOverride;
+ }
+
+ /** @hide */
+ public void setSoundMode(Mode soundMode) {
+ mSoundMode = soundMode;
+ mDirty = true;
+ }
+
+ public Mode getSoundMode() {
+ return mSoundMode;
+ }
+
+ /** @hide */
+ public void setRingerMode(Mode ringerMode) {
+ mRingerMode = ringerMode;
+ mDirty = true;
+ }
+
+ public Mode getRingerMode() {
+ return mRingerMode;
+ }
+
+ /** @hide */
+ public void setVibrateMode(Mode vibrateMode) {
+ mVibrateMode = vibrateMode;
+ mDirty = true;
+ }
+
+ public Mode getVibrateMode() {
+ return mVibrateMode;
+ }
+
+ /** @hide */
+ public void setLightsMode(Mode lightsMode) {
+ mLightsMode = lightsMode;
+ mDirty = true;
+ }
+
+ public Mode getLightsMode() {
+ return mLightsMode;
+ }
+
+ // TODO : add support for LEDs / screen etc.
+
+ /** @hide */
+ public Notification processNotification(Notification notification) {
+
+ switch (mSoundMode) {
+ case OVERRIDE:
+ notification.sound = mSoundOverride;
+ break;
+ case SUPPRESS:
+ silenceNotification(notification);
+ break;
+ case DEFAULT:
+ }
+ switch (mVibrateMode) {
+ case OVERRIDE:
+ notification.defaults |= Notification.DEFAULT_VIBRATE;
+ break;
+ case SUPPRESS:
+ suppressVibrate(notification);
+ break;
+ case DEFAULT:
+ }
+ switch (mLightsMode) {
+ case OVERRIDE:
+ notification.defaults |= Notification.DEFAULT_LIGHTS;
+ break;
+ case SUPPRESS:
+ suppressLights(notification);
+ break;
+ case DEFAULT:
+ }
+ return notification;
+ }
+
+ private void silenceNotification(Notification notification) {
+ notification.defaults &= (~Notification.DEFAULT_SOUND);
+ notification.sound = null;
+ }
+
+ private void suppressVibrate(Notification notification) {
+ notification.defaults &= (~Notification.DEFAULT_VIBRATE);
+ notification.vibrate = null;
+ }
+
+ private void suppressLights(Notification notification) {
+ notification.defaults &= (~Notification.DEFAULT_LIGHTS);
+ notification.flags &= (~Notification.FLAG_SHOW_LIGHTS);
+ }
+
+ /** @hide */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mName);
+ new ParcelUuid(mUuid).writeToParcel(dest, 0);
+ dest.writeInt(mDefaultGroup ? 1 : 0);
+ dest.writeInt(mDirty ? 1 : 0);
+ dest.writeParcelable(mSoundOverride, flags);
+ dest.writeParcelable(mRingerOverride, flags);
+
+ dest.writeString(mSoundMode.name());
+ dest.writeString(mRingerMode.name());
+ dest.writeString(mVibrateMode.name());
+ dest.writeString(mLightsMode.name());
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mName = in.readString();
+ mUuid = ParcelUuid.CREATOR.createFromParcel(in).getUuid();
+ mDefaultGroup = in.readInt() != 0;
+ mDirty = in.readInt() != 0;
+ mSoundOverride = in.readParcelable(null);
+ mRingerOverride = in.readParcelable(null);
+
+ mSoundMode = Mode.valueOf(Mode.class, in.readString());
+ mRingerMode = Mode.valueOf(Mode.class, in.readString());
+ mVibrateMode = Mode.valueOf(Mode.class, in.readString());
+ mLightsMode = Mode.valueOf(Mode.class, in.readString());
+ }
+
+ public enum Mode {
+ SUPPRESS, DEFAULT, OVERRIDE;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<profileGroup uuid=\"");
+ builder.append(TextUtils.htmlEncode(mUuid.toString()));
+ if (mName != null) {
+ builder.append("\" name=\"");
+ builder.append(mName);
+ }
+ builder.append("\" default=\"");
+ builder.append(isDefaultGroup());
+ builder.append("\">\n<sound>");
+ builder.append(TextUtils.htmlEncode(mSoundOverride.toString()));
+ builder.append("</sound>\n<ringer>");
+ builder.append(TextUtils.htmlEncode(mRingerOverride.toString()));
+ builder.append("</ringer>\n<soundMode>");
+ builder.append(mSoundMode);
+ builder.append("</soundMode>\n<ringerMode>");
+ builder.append(mRingerMode);
+ builder.append("</ringerMode>\n<vibrateMode>");
+ builder.append(mVibrateMode);
+ builder.append("</vibrateMode>\n<lightsMode>");
+ builder.append(mLightsMode);
+ builder.append("</lightsMode>\n</profileGroup>\n");
+ mDirty = false;
+ }
+
+ /** @hide */
+ public static ProfileGroup fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ String name = xpp.getAttributeValue(null, "name");
+ UUID uuid = null;
+ String value = xpp.getAttributeValue(null, "uuid");
+
+ if (value != null) {
+ try {
+ uuid = UUID.fromString(value);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "UUID not recognized for " + name + ", using new one.");
+ }
+ }
+
+ value = xpp.getAttributeValue(null, "default");
+ boolean defaultGroup = TextUtils.equals(value, "true");
+
+ ProfileGroup profileGroup = new ProfileGroup(name, uuid, defaultGroup);
+ int event = xpp.next();
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("profileGroup")) {
+ if (event == XmlPullParser.START_TAG) {
+ name = xpp.getName();
+ if (name.equals("sound")) {
+ profileGroup.setSoundOverride(Uri.parse(xpp.nextText()));
+ } else if (name.equals("ringer")) {
+ profileGroup.setRingerOverride(Uri.parse(xpp.nextText()));
+ } else if (name.equals("soundMode")) {
+ profileGroup.setSoundMode(Mode.valueOf(xpp.nextText()));
+ } else if (name.equals("ringerMode")) {
+ profileGroup.setRingerMode(Mode.valueOf(xpp.nextText()));
+ } else if (name.equals("vibrateMode")) {
+ profileGroup.setVibrateMode(Mode.valueOf(xpp.nextText()));
+ } else if (name.equals("lightsMode")) {
+ profileGroup.setLightsMode(Mode.valueOf(xpp.nextText()));
+ }
+ }
+ event = xpp.next();
+ }
+
+ /* we just loaded from XML, no need to save */
+ profileGroup.mDirty = false;
+
+ return profileGroup;
+ }
+}
diff --git a/core/java/android/app/ProfileManager.java b/core/java/android/app/ProfileManager.java
new file mode 100644
index 0000000..5ce52d5
--- /dev/null
+++ b/core/java/android/app/ProfileManager.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import java.util.UUID;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.internal.R;
+
+
+/**
+ * @hide
+ */
+public class ProfileManager {
+
+ private static IProfileManager sService;
+
+ private Context mContext;
+
+ private static final String TAG = "ProfileManager";
+
+ private static final String SYSTEM_PROFILES_ENABLED = "system_profiles_enabled";
+
+ // A blank profile that is created to be returned if profiles disabled
+ private static Profile mEmptyProfile;
+
+ /** @hide */
+ static public IProfileManager getService() {
+ if (sService != null) {
+ return sService;
+ }
+ IBinder b = ServiceManager.getService(Context.PROFILE_SERVICE);
+ sService = IProfileManager.Stub.asInterface(b);
+ return sService;
+ }
+
+ /** @hide */
+ ProfileManager(Context context, Handler handler) {
+ mContext = context;
+ mEmptyProfile = new Profile("EmptyProfile");
+ }
+
+ @Deprecated
+ public void setActiveProfile(String profileName) {
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ SYSTEM_PROFILES_ENABLED, 1) == 1) {
+ // Profiles are enabled, return active profile
+ try {
+ getService().setActiveProfileByName(profileName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+ }
+
+ public void setActiveProfile(UUID profileUuid) {
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ SYSTEM_PROFILES_ENABLED, 1) == 1) {
+ // Profiles are enabled, return active profile
+ try {
+ getService().setActiveProfile(new ParcelUuid(profileUuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+ }
+
+ public Profile getActiveProfile() {
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ SYSTEM_PROFILES_ENABLED, 1) == 1) {
+ // Profiles are enabled, return active profile
+ try {
+ return getService().getActiveProfile();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+
+ } else {
+ // Profiles are not enabled, return the empty profile
+ return mEmptyProfile;
+ }
+
+ }
+
+ /** @hide */
+ public void addProfile(Profile profile) {
+ try {
+ getService().addProfile(profile);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void removeProfile(Profile profile) {
+ try {
+ getService().removeProfile(profile);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void updateProfile(Profile profile) {
+ try {
+ getService().updateProfile(profile);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ @Deprecated
+ public Profile getProfile(String profileName) {
+ try {
+ return getService().getProfileByName(profileName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public Profile getProfile(UUID profileUuid) {
+ try {
+ return getService().getProfile(new ParcelUuid(profileUuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public String[] getProfileNames() {
+ try {
+ Profile[] profiles = getService().getProfiles();
+ String[] names = new String[profiles.length];
+ for (int i = 0; i < profiles.length; i++) {
+ names[i] = profiles[i].getName();
+ }
+ return names;
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public Profile[] getProfiles() {
+ try {
+ return getService().getProfiles();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ public boolean profileExists(String profileName) {
+ try {
+ return getService().profileExistsByName(profileName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ // To be on the safe side, we'll return "true", to prevent duplicate profiles
+ // from being created.
+ return true;
+ }
+ }
+
+ public boolean profileExists(UUID profileUuid) {
+ try {
+ return getService().profileExists(new ParcelUuid(profileUuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ // To be on the safe side, we'll return "true", to prevent duplicate profiles
+ // from being created.
+ return true;
+ }
+ }
+
+ public boolean notificationGroupExists(String notificationGroupName) {
+ try {
+ return getService().notificationGroupExistsByName(notificationGroupName);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ // To be on the safe side, we'll return "true", to prevent duplicate notification
+ // groups from being created.
+ return true;
+ }
+ }
+
+ /** @hide */
+ public NotificationGroup[] getNotificationGroups() {
+ try {
+ return getService().getNotificationGroups();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ /** @hide */
+ public void addNotificationGroup(NotificationGroup group) {
+ try {
+ getService().addNotificationGroup(group);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void removeNotificationGroup(NotificationGroup group) {
+ try {
+ getService().removeNotificationGroup(group);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public void updateNotificationGroup(NotificationGroup group) {
+ try {
+ getService().updateNotificationGroup(group);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /** @hide */
+ public NotificationGroup getNotificationGroupForPackage(String pkg) {
+ try {
+ return getService().getNotificationGroupForPackage(pkg);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ /** @hide */
+ public NotificationGroup getNotificationGroup(UUID uuid) {
+ try {
+ return getService().getNotificationGroup(new ParcelUuid(uuid));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ return null;
+ }
+
+ /** @hide */
+ public ProfileGroup getActiveProfileGroup(String packageName) {
+ NotificationGroup notificationGroup = getNotificationGroupForPackage(packageName);
+ if(notificationGroup == null){
+ ProfileGroup defaultGroup = getActiveProfile().getDefaultGroup();
+ return defaultGroup;
+ }
+ return getActiveProfile().getProfileGroup(notificationGroup.getUuid());
+ }
+
+ /** @hide */
+ public void resetAll() {
+ try {
+ getService().resetAll();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ } catch (SecurityException e) {
+ Log.e(TAG, e.getLocalizedMessage(), e);
+ }
+ }
+}
diff --git a/core/java/android/app/RingModeSettings.java b/core/java/android/app/RingModeSettings.java
new file mode 100644
index 0000000..788bcbd
--- /dev/null
+++ b/core/java/android/app/RingModeSettings.java
@@ -0,0 +1,135 @@
+package android.app;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/** @hide */
+public final class RingModeSettings implements Parcelable {
+ private static final String RING_MODE_NORMAL = "normal";
+ private static final String RING_MODE_VIBRATE = "vibrate";
+ private static final String RING_MODE_MUTE = "mute";
+
+ private String mValue;
+ private boolean mOverride;
+ private boolean mDirty;
+
+ /** @hide */
+ public static final Parcelable.Creator<RingModeSettings> CREATOR = new Parcelable.Creator<RingModeSettings>() {
+ public RingModeSettings createFromParcel(Parcel in) {
+ return new RingModeSettings(in);
+ }
+
+ @Override
+ public RingModeSettings[] newArray(int size) {
+ return new RingModeSettings[size];
+ }
+ };
+
+
+ public RingModeSettings(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ public RingModeSettings() {
+ this(RING_MODE_NORMAL, false);
+ }
+
+ public RingModeSettings(String value, boolean override) {
+ mValue = value;
+ mOverride = override;
+ mDirty = false;
+ }
+
+ public String getValue() {
+ return mValue;
+ }
+
+ public void setValue(String value) {
+ mValue = value;
+ mDirty = true;
+ }
+
+ public void setOverride(boolean override) {
+ mOverride = override;
+ mDirty = true;
+ }
+
+ public boolean isOverride() {
+ return mOverride;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ public void processOverride(Context context) {
+ if (isOverride()) {
+ int ringerMode = AudioManager.RINGER_MODE_NORMAL;
+ if (mValue.equals(RING_MODE_MUTE)) {
+ ringerMode = AudioManager.RINGER_MODE_SILENT;
+ } else if (mValue.equals(RING_MODE_VIBRATE)) {
+ ringerMode = AudioManager.RINGER_MODE_VIBRATE;
+ }
+ AudioManager amgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ amgr.setRingerMode(ringerMode);
+ }
+ }
+
+ /** @hide */
+ public static RingModeSettings fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ int event = xpp.next();
+ RingModeSettings ringModeDescriptor = new RingModeSettings();
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("ringModeDescriptor")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("value")) {
+ ringModeDescriptor.mValue = xpp.nextText();
+ } else if (name.equals("override")) {
+ ringModeDescriptor.mOverride = Boolean.parseBoolean(xpp.nextText());
+ }
+ }
+ event = xpp.next();
+ }
+ return ringModeDescriptor;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<ringModeDescriptor>\n<value>");
+ builder.append(mValue);
+ builder.append("</value>\n<override>");
+ builder.append(mOverride);
+ builder.append("</override>\n</ringModeDescriptor>\n");
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mOverride ? 1 : 0);
+ dest.writeString(mValue);
+ dest.writeInt(mDirty ? 1 : 0);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mOverride = in.readInt() != 0;
+ mValue = in.readString();
+ mDirty = in.readInt() != 0;
+ }
+
+
+}
diff --git a/core/java/android/app/StreamSettings.java b/core/java/android/app/StreamSettings.java
new file mode 100644
index 0000000..2f3bf27
--- /dev/null
+++ b/core/java/android/app/StreamSettings.java
@@ -0,0 +1,130 @@
+
+package android.app;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.IOException;
+
+/** @hide */
+public final class StreamSettings implements Parcelable{
+
+ private int mStreamId;
+ private int mValue;
+ private boolean mOverride;
+ private boolean mDirty;
+
+ /** @hide */
+ public static final Parcelable.Creator<StreamSettings> CREATOR = new Parcelable.Creator<StreamSettings>() {
+ public StreamSettings createFromParcel(Parcel in) {
+ return new StreamSettings(in);
+ }
+
+ @Override
+ public StreamSettings[] newArray(int size) {
+ return new StreamSettings[size];
+ }
+ };
+
+
+ public StreamSettings(Parcel parcel) {
+ readFromParcel(parcel);
+ }
+
+ public StreamSettings(int streamId) {
+ this(streamId, 0, false);
+ }
+
+ public StreamSettings(int streamId, int value, boolean override) {
+ mStreamId = streamId;
+ mValue = value;
+ mOverride = override;
+ mDirty = false;
+ }
+
+ public int getStreamId() {
+ return mStreamId;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ public void setValue(int value) {
+ mValue = value;
+ mDirty = true;
+ }
+
+ public void setOverride(boolean override) {
+ mOverride = override;
+ mDirty = true;
+ }
+
+ public boolean isOverride() {
+ return mOverride;
+ }
+
+ /** @hide */
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ /** @hide */
+ public static StreamSettings fromXml(XmlPullParser xpp, Context context)
+ throws XmlPullParserException, IOException {
+ int event = xpp.next();
+ StreamSettings streamDescriptor = new StreamSettings(0);
+ while (event != XmlPullParser.END_TAG || !xpp.getName().equals("streamDescriptor")) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("streamId")) {
+ streamDescriptor.mStreamId = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("value")) {
+ streamDescriptor.mValue = Integer.parseInt(xpp.nextText());
+ } else if (name.equals("override")) {
+ streamDescriptor.mOverride = Boolean.parseBoolean(xpp.nextText());
+ }
+ }
+ event = xpp.next();
+ }
+ return streamDescriptor;
+ }
+
+ /** @hide */
+ public void getXmlString(StringBuilder builder, Context context) {
+ builder.append("<streamDescriptor>\n<streamId>");
+ builder.append(mStreamId);
+ builder.append("</streamId>\n<value>");
+ builder.append(mValue);
+ builder.append("</value>\n<override>");
+ builder.append(mOverride);
+ builder.append("</override>\n</streamDescriptor>\n");
+ mDirty = false;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mStreamId);
+ dest.writeInt(mOverride ? 1 : 0);
+ dest.writeInt(mValue);
+ dest.writeInt(mDirty ? 1 : 0);
+ }
+
+ /** @hide */
+ public void readFromParcel(Parcel in) {
+ mStreamId = in.readInt();
+ mOverride = in.readInt() != 0;
+ mValue = in.readInt();
+ mDirty = in.readInt() != 0;
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 4cc22b4..74d50f1 100755
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -322,6 +322,9 @@ public final class BluetoothDevice implements Parcelable {
/**@hide*/
public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
+ /**@hide*/
+ public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
+
/**
* Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
* Contains package name to return reply intent to.
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 5962235..1a0bd02 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -56,6 +56,10 @@ public final class BluetoothUuid {
ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid Hid =
ParcelUuid.fromString("00001124-0000-1000-8000-00805f9b34fb");
+ public static final ParcelUuid MessageAccessServer =
+ ParcelUuid.fromString("00001132-0000-1000-8000-00805f9b34fb");
+ public static final ParcelUuid MessageNotificationServer =
+ ParcelUuid.fromString("00001133-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid PANU =
ParcelUuid.fromString("00001115-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid NAP =
@@ -67,7 +71,7 @@ public final class BluetoothUuid {
public static final ParcelUuid[] RESERVED_UUIDS = {
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
- ObexObjectPush, PANU, NAP};
+ ObexObjectPush, MessageAccessServer, MessageNotificationServer, PANU, NAP};
public static boolean isAudioSource(ParcelUuid uuid) {
return uuid.equals(AudioSource);
@@ -131,6 +135,14 @@ public final class BluetoothUuid {
return false;
}
+ public static boolean isMessageAccessServer(ParcelUuid uuid) {
+ return uuid.equals(MessageAccessServer);
+ }
+
+ public static boolean isMessageNotificationServer(ParcelUuid uuid) {
+ return uuid.equals(MessageNotificationServer);
+ }
+
/**
* Returns true if there any common ParcelUuids in uuidA and uuidB.
*
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7aa2507..f0c6ce8 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1890,6 +1890,18 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
+ * {@link android.app.ProfileManager} for setting
+ * notification profiles.
+ *
+ * @see #getSystemService
+ * @see android.app.ProfileManager
+ *
+ * @hide
+ */
+ public static final String PROFILE_SERVICE = "profile";
+
+ /**
+ * Use with {@link #getSystemService} to retrieve a
* {@link android.view.accessibility.AccessibilityManager} for giving the user
* feedback for UI events through the registered event listeners.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index cf0603e..519eb36 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -2137,6 +2138,31 @@ public class Intent implements Parcelable, Cloneable {
"android.intent.action.HEADSET_PLUG";
/**
+ * Broadcast Action: WiFi Display audio is enabled or disabled
+ *
+ * <p>The intent will have the following extra values:
+ * <ul>
+ * <li><em>state</em> - 0 for disabled, 1 for enabled. </li>
+ * </ul>
+ * @hide
+ */
+ public static final String ACTION_WIFI_DISPLAY_AUDIO =
+ "qualcomm.intent.action.WIFI_DISPLAY_AUDIO";
+
+ /**
+ * Broadcast Action: WiFi Display video is enabled or disabled
+ *
+ * <p>The intent will have the following extra values:
+ * <ul>
+ * <li><em>state</em> - 0 for disabled, 1 for enabled. </li>
+ * </ul>
+ * @hide
+ */
+
+ public static final String ACTION_WIFI_DISPLAY_VIDEO =
+ "qualcomm.intent.action.WIFI_DISPLAY_VIDEO";
+
+ /**
* Broadcast Action: An analog audio speaker/headset plugged in or unplugged.
*
* <p>The intent will have the following extra values:
@@ -2465,6 +2491,19 @@ public class Intent implements Parcelable, Cloneable {
public static final String ACTION_QUICK_CLOCK =
"android.intent.action.QUICK_CLOCK";
+ /**
+ * Broadcast Action: Indicate that unrecoverable error happened during app launch.
+ * Could indicate that curently applied theme is malicious.
+ * @hide
+ */
+ public static final String ACTION_APP_LAUNCH_FAILURE = "com.tmobile.intent.action.APP_LAUNCH_FAILURE";
+
+ /**
+ * Broadcast Action: Request to reset the unrecoverable errors count to 0.
+ * @hide
+ */
+ public static final String ACTION_APP_LAUNCH_FAILURE_RESET = "com.tmobile.intent.action.APP_LAUNCH_FAILURE_RESET";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent categories (see addCategory()).
@@ -2597,6 +2636,7 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST =
"android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST";
+
/**
* An activity to run when device is inserted into a car dock.
* Used with {@link #ACTION_MAIN} to launch an activity. For more
@@ -2633,6 +2673,14 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE";
+ /**
+ * Used to indicate that a theme package has been installed or un-installed.
+ *
+ * @hide
+ */
+ public static final String CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE =
+ "com.tmobile.intent.category.THEME_PACKAGE_INSTALL_STATE_CHANGE";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Application launch intent categories (see addCategory()).
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index e4b4b97..03c1c95 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -16,6 +16,7 @@
package android.content;
+import com.android.internal.app.ThemeUtils;
import android.accounts.Account;
import android.accounts.AccountAndUser;
import android.accounts.AccountManager;
@@ -140,6 +141,7 @@ public class SyncManager {
private static final int MAX_SIMULTANEOUS_INITIALIZATION_SYNCS;
private Context mContext;
+ private Context mUiContext;
private static final AccountAndUser[] INITIAL_ACCOUNTS_ARRAY = new AccountAndUser[0];
@@ -198,6 +200,12 @@ public class SyncManager {
}
};
+ private BroadcastReceiver mThemeChangeReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ };
+
private BroadcastReceiver mBackgroundDataSettingChanged = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (getConnectivityManager().getBackgroundDataSetting()) {
@@ -404,6 +412,8 @@ public class SyncManager {
mContext.registerReceiverAsUser(
mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
+ ThemeUtils.registerThemeChangeReceiver(mContext, mThemeChangeReceiver);
+
if (!factoryTest) {
mNotificationMgr = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -938,6 +948,13 @@ public class SyncManager {
}
}
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
+
/**
* @hide
*/
@@ -2567,7 +2584,7 @@ public class SyncManager {
new Notification(R.drawable.stat_notify_sync_error,
mContext.getString(R.string.contentServiceSync),
System.currentTimeMillis());
- notification.setLatestEventInfo(mContext,
+ notification.setLatestEventInfo(getUiContext(),
mContext.getString(R.string.contentServiceSyncNotificationTitle),
String.format(tooManyDeletesDescFormat.toString(), authorityName),
pendingIntent);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index e2ca1dd..f1d678c 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -341,6 +342,10 @@ public class ActivityInfo extends ComponentInfo
*/
public static final int CONFIG_ORIENTATION = 0x0080;
/**
+ * @hide
+ */
+ public static final int CONFIG_THEME_RESOURCE = 0x008000;
+ /**
* Bit in {@link #configChanges} that indicates that the activity
* can itself handle changes to the screen layout. Set from the
* {@link android.R.attr#configChanges} attribute.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 32cc7fd..fa85145 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -444,6 +445,30 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* @hide
*/
public int enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ /**
+ * Is given application theme agnostic, i.e. behaves properly when default theme is changed.
+ * {@hide}
+ */
+ public boolean isThemeable = false;
+
+ private static final String PLUTO_SCHEMA = "http://www.w3.org/2001/pluto.html";
+
+ /**
+ * @hide
+ */
+ public static final String PLUTO_ISTHEMEABLE_ATTRIBUTE_NAME = "isThemeable";
+
+ /**
+ * @hide
+ */
+ public static final String PLUTO_HANDLE_THEME_CONFIG_CHANGES_ATTRIBUTE_NAME = "handleThemeConfigChanges";
+
+ /**
+ * @hide
+ */
+ public static boolean isPlutoNamespace(String namespace) {
+ return namespace != null && namespace.equalsIgnoreCase(PLUTO_SCHEMA);
+ }
/**
* For convenient access to package's install location.
@@ -555,6 +580,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
descriptionRes = orig.descriptionRes;
uiOptions = orig.uiOptions;
backupAgentName = orig.backupAgentName;
+ isThemeable = orig.isThemeable;
}
@@ -594,6 +620,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeString(backupAgentName);
dest.writeInt(descriptionRes);
dest.writeInt(uiOptions);
+ dest.writeInt(isThemeable? 1 : 0);
}
public static final Parcelable.Creator<ApplicationInfo> CREATOR
@@ -632,6 +659,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
backupAgentName = source.readString();
descriptionRes = source.readInt();
uiOptions = source.readInt();
+ isThemeable = source.readInt() != 0;
}
/**
diff --git a/core/java/android/content/pm/BaseThemeInfo.java b/core/java/android/content/pm/BaseThemeInfo.java
new file mode 100644
index 0000000..0171137b
--- /dev/null
+++ b/core/java/android/content/pm/BaseThemeInfo.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2010, T-Mobile USA, Inc.
+ *
+ * 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.content.pm;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+import android.util.AttributeSet;
+import android.content.res.Resources;
+
+/**
+ * @hide
+ */
+public class BaseThemeInfo implements Parcelable {
+
+ /**
+ * Wallpaper drawable.
+ *
+ * @see wallpaperImage attribute
+ */
+ public int wallpaperResourceId;
+
+ /**
+ * The resource id of theme thumbnail.
+ * Specifies a theme thumbnail image resource as @drawable/foo.
+ *
+ * @see thumbnail attribute
+ *
+ */
+ public int thumbnailResourceId;
+
+ /**
+ * The theme id, which does not change when the theme is modified.
+ * Specifies an Android UI Style using style name.
+ *
+ * @see themeId attribute
+ *
+ */
+ public String themeId;
+
+ /**
+ * The style resource id of Android UI Style, supplied by the resource commpiler.
+ * Specifies an Android UI Style id.
+ *
+ * @see styleId attribute
+ *
+ */
+ public int styleResourceId = 0;
+
+ /**
+ * The name of the theme (as displayed by UI).
+ *
+ * @see name attribute
+ *
+ */
+ public String name;
+
+ /**
+ * The name of the call ringtone audio file.
+ * Specifies a relative path in assets subfolder.
+ * If the parent's name is "locked" - DRM protected.
+ *
+ * @see ringtoneFileName attribute
+ *
+ */
+ public String ringtoneFileName;
+
+ /**
+ * The name of the call ringtone as shown to user.
+ *
+ * @see ringtoneName attribute
+ *
+ */
+ public String ringtoneName;
+
+ /**
+ * The name of the notification ringtone audio file.
+ * Specifies a relative path in assets subfolder.
+ * If the parent's name is "locked" - DRM protected.
+ *
+ * @see notificationRingtoneFileName attribute
+ *
+ */
+ public String notificationRingtoneFileName;
+
+ /**
+ * The name of the notification ringtone as shown to user.
+ *
+ * @see notificationRingtoneName attribute
+ *
+ */
+ public String notificationRingtoneName;
+
+ /**
+ * The author name of the theme package.
+ *
+ * @see author attribute
+ *
+ */
+ public String author;
+
+ /**
+ * The copyright text.
+ *
+ * @see copyright attribute
+ *
+ */
+ public String copyright;
+
+ /**
+ * {@hide}
+ */
+ // There is no corresposponding flag in manifest file
+ // This flag is set to true iff any media resource is DRM protected
+ public boolean isDrmProtected = false;
+
+ /**
+ * The name of the "main" theme style (as displayed by UI).
+ *
+ * @see themeStyleName attribute
+ *
+ */
+ public String themeStyleName;
+
+ /**
+ * Preview image drawable.
+ *
+ * @see preview attribute
+ */
+ public int previewResourceId;
+
+ /**
+ * The name of a sound pack.
+ *
+ * @see soundpack attribute
+ *
+ */
+ public String soundPackName;
+
+
+ private static final String LOCKED_NAME = "locked/";
+
+ /*
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return a bitmask indicating the set of special object types marshalled
+ * by the Parcelable.
+ *
+ * @see android.os.Parcelable#describeContents()
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /*
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ *
+ * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
+ */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(wallpaperResourceId);
+ dest.writeInt(thumbnailResourceId);
+ dest.writeString(themeId);
+ dest.writeInt(styleResourceId);
+ dest.writeString(name);
+ dest.writeString(ringtoneFileName);
+ dest.writeString(notificationRingtoneFileName);
+ dest.writeString(ringtoneName);
+ dest.writeString(notificationRingtoneName);
+ dest.writeString(author);
+ dest.writeString(copyright);
+ dest.writeInt(isDrmProtected? 1 : 0);
+ dest.writeString(soundPackName);
+ dest.writeString(themeStyleName);
+ dest.writeInt(previewResourceId);
+ }
+
+ /** @hide */
+ public static final Parcelable.Creator<BaseThemeInfo> CREATOR
+ = new Parcelable.Creator<BaseThemeInfo>() {
+ public BaseThemeInfo createFromParcel(Parcel source) {
+ return new BaseThemeInfo(source);
+ }
+
+ public BaseThemeInfo[] newArray(int size) {
+ return new BaseThemeInfo[size];
+ }
+ };
+
+ /** @hide */
+ public final String getResolvedString(Resources res, AttributeSet attrs, int index) {
+ int resId = attrs.getAttributeResourceValue(index, 0);
+ if (resId !=0 ) {
+ return res.getString(resId);
+ }
+ return attrs.getAttributeValue(index);
+ }
+
+ protected BaseThemeInfo() {
+ }
+
+ protected BaseThemeInfo(Parcel source) {
+ wallpaperResourceId = source.readInt();
+ thumbnailResourceId = source.readInt();
+ themeId = source.readString();
+ styleResourceId = source.readInt();
+ name = source.readString();
+ ringtoneFileName = source.readString();
+ notificationRingtoneFileName = source.readString();
+ ringtoneName = source.readString();
+ notificationRingtoneName = source.readString();
+ author = source.readString();
+ copyright = source.readString();
+ isDrmProtected = (source.readInt() != 0);
+ soundPackName = source.readString();
+ themeStyleName = source.readString();
+ previewResourceId = source.readInt();
+ }
+
+ protected void changeDrmFlagIfNeeded(String resourcePath) {
+ if (resourcePath != null && resourcePath.contains(LOCKED_NAME)) {
+ isDrmProtected = true;
+ }
+ }
+}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index b9e432c..d24bf6e 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -42,6 +42,7 @@ import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.ThemeInfo;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.content.IntentSender;
@@ -129,6 +130,8 @@ interface IPackageManager {
*/
ParceledListSlice getInstalledPackages(int flags, in String lastRead, in int userId);
+ List<PackageInfo> getInstalledThemePackages();
+
/**
* This implements getInstalledApplications via a "last returned row"
* mechanism that is not exposed in the API. This is to get around the IPC
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 85f7aa5..79cc528 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -218,9 +219,69 @@ public class PackageInfo implements Parcelable {
*/
public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
+ // Is Theme Apk
+ /**
+ * {@hide}
+ */
+ public boolean isThemeApk = false;
+
+ // ThemeInfo
+ /**
+ * {@hide}
+ */
+ public ThemeInfo [] themeInfos;
+
public PackageInfo() {
}
+ /*
+ * Is Theme Apk is DRM protected (contains DRM-protected resources)
+ *
+ */
+ private boolean drmProtectedThemeApk = false;
+
+ /**
+ * @hide
+ *
+ * @return Is Theme Apk is DRM protected (contains DRM-protected resources)
+ */
+ public boolean isDrmProtectedThemeApk() {
+ return drmProtectedThemeApk;
+ }
+
+ /**
+ * @hide
+ *
+ * @param value if Theme Apk is DRM protected (contains DRM-protected resources)
+ */
+ public void setDrmProtectedThemeApk(boolean value) {
+ drmProtectedThemeApk = value;
+ }
+
+ /*
+ * If isThemeApk and isDrmProtectedThemeApk are true - path to hidden locked zip file
+ *
+ */
+ private String lockedZipFilePath;
+
+ /**
+ * @hide
+ *
+ * @return path for hidden locked zip file
+ */
+ public String getLockedZipFilePath() {
+ return lockedZipFilePath;
+ }
+
+ /**
+ * @hide
+ *
+ * @param value path for hidden locked zip file
+ */
+ public void setLockedZipFilePath(String value) {
+ lockedZipFilePath = value;
+ }
+
public String toString() {
return "PackageInfo{"
+ Integer.toHexString(System.identityHashCode(this))
@@ -258,6 +319,12 @@ public class PackageInfo implements Parcelable {
dest.writeTypedArray(configPreferences, parcelableFlags);
dest.writeTypedArray(reqFeatures, parcelableFlags);
dest.writeInt(installLocation);
+
+ /* Theme-specific. */
+ dest.writeInt((isThemeApk)? 1 : 0);
+ dest.writeInt((drmProtectedThemeApk)? 1 : 0);
+ dest.writeTypedArray(themeInfos, parcelableFlags);
+ dest.writeString(lockedZipFilePath);
}
public static final Parcelable.Creator<PackageInfo> CREATOR
@@ -296,5 +363,11 @@ public class PackageInfo implements Parcelable {
configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR);
reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
installLocation = source.readInt();
+
+ /* Theme-specific. */
+ isThemeApk = (source.readInt() != 0);
+ drmProtectedThemeApk = (source.readInt() != 0);
+ themeInfos = source.createTypedArray(ThemeInfo.CREATOR);
+ lockedZipFilePath = source.readString();
}
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 8ba1988..eb6e640 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -857,6 +858,22 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device is able to receive FM radio.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_RADIO_FM_RECEIVER = "com.stericsson.hardware.fm.receiver";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device is able to transmit FM radio.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_RADIO_FM_TRANSMITTER = "com.stericsson.hardware.fm.transmitter";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports one or more methods of
* reporting current location.
*/
@@ -1540,6 +1557,17 @@ public abstract class PackageManager {
public abstract List<PackageInfo> getInstalledPackages(int flags, int userId);
/**
+ * Return a List of all theme packages that are installed
+ * on the device.
+ *
+ * @return A List of PackageInfo objects, one for each theme package
+ * that is installed on the device.
+ *
+ * @hide
+ */
+ public abstract List<PackageInfo> getInstalledThemePackages();
+
+ /**
* Check whether a particular package has been granted a particular
* permission.
*
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3e8c2a8..452a74d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -256,6 +257,17 @@ public class PackageParser {
}
*/
+ public static String getLockedZipFilePath(String path) {
+ if (path == null) {
+ return null;
+ }
+ if (isPackageFilename(path)) {
+ return path.substring(0, path.length() - 4) + ".locked.zip";
+ } else {
+ return path + ".locked.zip";
+ }
+ }
+
/**
* Generate and return the {@link PackageInfo} for a parsed package.
*
@@ -287,6 +299,21 @@ public class PackageParser {
pi.versionName = p.mVersionName;
pi.sharedUserId = p.mSharedUserId;
pi.sharedUserLabel = p.mSharedUserLabel;
+ pi.isThemeApk = p.mIsThemeApk;
+ pi.setDrmProtectedThemeApk(false);
+ if (pi.isThemeApk) {
+ int N = p.mThemeInfos.size();
+ if (N > 0) {
+ pi.themeInfos = new ThemeInfo[N];
+ for (int i = 0; i < N; i++) {
+ pi.themeInfos[i] = p.mThemeInfos.get(i);
+ pi.setDrmProtectedThemeApk(pi.isDrmProtectedThemeApk() || pi.themeInfos[i].isDrmProtected);
+ }
+ if (pi.isDrmProtectedThemeApk()) {
+ pi.setLockedZipFilePath(PackageParser.getLockedZipFilePath(p.mPath));
+ }
+ }
+ }
pi.applicationInfo = generateApplicationInfo(p, flags, state, userId);
pi.installLocation = p.installLocation;
pi.firstInstallTime = firstInstallTime;
@@ -1287,7 +1314,10 @@ public class PackageParser {
// Just skip this tag
XmlUtils.skipCurrentTag(parser);
continue;
-
+ } else if (tagName.equals("theme")) {
+ // this is a theme apk.
+ pkg.mIsThemeApk = true;
+ pkg.mThemeInfos.add(new ThemeInfo(parser, res, attrs));
} else if (RIGID_PARSER) {
outError[0] = "Bad element under <manifest>: "
+ parser.getName();
@@ -1378,6 +1408,9 @@ public class PackageParser {
>= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
}
+ if (pkg.mIsThemeApk) {
+ pkg.applicationInfo.isThemeable = false;
+ }
return pkg;
}
@@ -1683,12 +1716,43 @@ public class PackageParser {
return a;
}
+ private void parseApplicationThemeAttributes(XmlPullParser parser, AttributeSet attrs,
+ ApplicationInfo appInfo) {
+ for (int i = 0; i < attrs.getAttributeCount(); i++) {
+ if (!ApplicationInfo.isPlutoNamespace(parser.getAttributeNamespace(i))) {
+ continue;
+ }
+ String attrName = attrs.getAttributeName(i);
+ if (attrName.equalsIgnoreCase(ApplicationInfo.PLUTO_ISTHEMEABLE_ATTRIBUTE_NAME)) {
+ appInfo.isThemeable = attrs.getAttributeBooleanValue(i, false);
+ return;
+ }
+ }
+ }
+
+ private void parseActivityThemeAttributes(XmlPullParser parser, AttributeSet attrs,
+ ActivityInfo ai) {
+ for (int i = 0; i < attrs.getAttributeCount(); i++) {
+ if (!ApplicationInfo.isPlutoNamespace(parser.getAttributeNamespace(i))) {
+ continue;
+ }
+ String attrName = attrs.getAttributeName(i);
+ if (attrName.equalsIgnoreCase(ApplicationInfo.PLUTO_HANDLE_THEME_CONFIG_CHANGES_ATTRIBUTE_NAME)) {
+ ai.configChanges |= ActivityInfo.CONFIG_THEME_RESOURCE;
+ }
+ }
+ }
+
private boolean parseApplication(Package owner, Resources res,
XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
throws XmlPullParserException, IOException {
final ApplicationInfo ai = owner.applicationInfo;
final String pkgName = owner.applicationInfo.packageName;
+ // assume that this package is themeable unless explicitly set to false.
+ ai.isThemeable = true;
+ parseApplicationThemeAttributes(parser, attrs, ai);
+
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestApplication);
@@ -2229,6 +2293,8 @@ public class PackageParser {
return null;
}
+ parseActivityThemeAttributes(parser, attrs, a.info);
+
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -3222,6 +3288,12 @@ public class PackageParser {
// For use by package manager to keep track of where it has done dexopt.
public boolean mDidDexOpt;
+
+ // Is Theme Apk
+ public boolean mIsThemeApk = false;
+
+ // Theme info
+ public final ArrayList<ThemeInfo> mThemeInfos = new ArrayList<ThemeInfo>(0);
// // User set enabled state.
// public int mSetEnabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
diff --git a/core/java/android/content/pm/ThemeInfo.aidl b/core/java/android/content/pm/ThemeInfo.aidl
new file mode 100755
index 0000000..acbc85e
--- /dev/null
+++ b/core/java/android/content/pm/ThemeInfo.aidl
@@ -0,0 +1,3 @@
+package android.content.pm;
+
+parcelable ThemeInfo;
diff --git a/core/java/android/content/pm/ThemeInfo.java b/core/java/android/content/pm/ThemeInfo.java
new file mode 100644
index 0000000..e51dbb6
--- /dev/null
+++ b/core/java/android/content/pm/ThemeInfo.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2010, T-Mobile USA, Inc.
+ *
+ * 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.content.pm;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParser;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.content.res.Resources;
+
+/**
+ * Overall information about "theme" package. This corresponds
+ * to the information collected from AndroidManifest.xml (theme tag).
+ *
+ * Below is an example of theme tag
+ * <theme
+ * pluto:name="Pluto Default"
+ * pluto:preview="@drawable/preview"
+ * pluto:author="John Doe"
+ * pluto:ringtoneFileName="media/audio/ringtone.mp3"
+ * pluto:notificationRingtoneFileName="media/audio/locked/notification.mp3"
+ * pluto:copyright="T-Mobile, 2009"
+ * />
+ *
+ * @hide
+ */
+public final class ThemeInfo extends BaseThemeInfo {
+ private enum AttributeIndex {
+ THEME_PACKAGE_INDEX,
+ PREVIEW_INDEX,
+ AUTHOR_INDEX,
+ THEME_INDEX,
+ THEME_STYLE_NAME_INDEX,
+ THUMBNAIL_INDEX,
+ RINGTONE_FILE_NAME_INDEX,
+ NOTIFICATION_RINGTONE_FILE_NAME_INDEX,
+ WALLPAPER_IMAGE_INDEX,
+ COPYRIGHT_INDEX,
+ RINGTONE_NAME_INDEX,
+ NOTIFICATION_RINGTONE_NAME_INDEX,
+ STYLE_INDEX;
+
+ public static AttributeIndex get(int ordinal) {
+ return values()[ordinal];
+ }
+ };
+
+ private static final String [] compulsoryAttributes = new String [] {
+ "name",
+ "preview",
+ "author",
+ "themeId",
+ "styleName",
+ };
+
+ private static final String [] optionalAttributes = new String [] {
+ "thumbnail",
+ "ringtoneFileName",
+ "notificationRingtoneFileName",
+ "wallpaperImage",
+ "copyright",
+ "ringtoneName",
+ "notificationRingtoneName",
+ "styleId",
+ };
+
+ private static final Map<String, AttributeIndex> sAttributesLookupTable;
+
+ static {
+ sAttributesLookupTable = new HashMap<String, AttributeIndex>();
+ for (int i = 0; i < compulsoryAttributes.length; i++) {
+ sAttributesLookupTable.put(compulsoryAttributes[i], AttributeIndex.get(i));
+ }
+
+ for (int i = 0; i < optionalAttributes.length; i++) {
+ sAttributesLookupTable.put(optionalAttributes[i],
+ AttributeIndex.get(compulsoryAttributes.length + i));
+ }
+ }
+
+ public ThemeInfo(XmlPullParser parser, Resources res, AttributeSet attrs) throws XmlPullParserException {
+ super();
+
+ Map<String, AttributeIndex> tempMap =
+ new HashMap<String, AttributeIndex>(sAttributesLookupTable);
+ int numberOfCompulsoryAttributes = 0;
+ for (int i = 0; i < attrs.getAttributeCount(); i++) {
+ if (!ApplicationInfo.isPlutoNamespace(parser.getAttributeNamespace(i))) {
+ continue;
+ }
+ String key = attrs.getAttributeName(i);
+ if (tempMap.containsKey(key)) {
+ AttributeIndex index = tempMap.get(key);
+ tempMap.remove(key);
+
+ if (index.ordinal() < compulsoryAttributes.length) {
+ numberOfCompulsoryAttributes++;
+ }
+ switch (index) {
+ case THEME_PACKAGE_INDEX:
+ // theme name
+ name = getResolvedString(res, attrs, i);
+ break;
+
+ case THUMBNAIL_INDEX:
+ // theme thumbprint
+ thumbnailResourceId = attrs.getAttributeResourceValue(i, 0);
+ break;
+
+ case AUTHOR_INDEX:
+ // theme author
+ author = getResolvedString(res, attrs, i);
+ break;
+
+ case THEME_INDEX:
+ // androidUiStyle attribute
+ themeId = attrs.getAttributeValue(i);
+ break;
+
+ case THEME_STYLE_NAME_INDEX:
+ themeStyleName = getResolvedString(res, attrs, i);
+ break;
+
+ case RINGTONE_FILE_NAME_INDEX:
+ // ringtone
+ ringtoneFileName = attrs.getAttributeValue(i);
+ changeDrmFlagIfNeeded(ringtoneFileName);
+ break;
+
+ case NOTIFICATION_RINGTONE_FILE_NAME_INDEX:
+ // notification ringtone
+ notificationRingtoneFileName = attrs.getAttributeValue(i);
+ changeDrmFlagIfNeeded(notificationRingtoneFileName);
+ break;
+
+ case WALLPAPER_IMAGE_INDEX:
+ // wallpaperImage attribute
+ wallpaperResourceId = attrs.getAttributeResourceValue(i, 0);
+ break;
+
+ case COPYRIGHT_INDEX:
+ // themeCopyright attribute
+ copyright = getResolvedString(res, attrs, i);
+ break;
+
+ case RINGTONE_NAME_INDEX:
+ // ringtone UI name
+ ringtoneName = attrs.getAttributeValue(i);
+ break;
+
+ case NOTIFICATION_RINGTONE_NAME_INDEX:
+ // notification ringtone UI name
+ notificationRingtoneName = attrs.getAttributeValue(i);
+ break;
+
+ case STYLE_INDEX:
+ styleResourceId = attrs.getAttributeResourceValue(i, 0);
+ break;
+
+ case PREVIEW_INDEX:
+ // theme thumbprint
+ previewResourceId = attrs.getAttributeResourceValue(i, 0);
+ break;
+ }
+ }
+ }
+ if (numberOfCompulsoryAttributes < compulsoryAttributes.length) {
+ throw new XmlPullParserException("Not all compulsory attributes are specified in <theme>");
+ }
+ }
+
+ public static final Parcelable.Creator<ThemeInfo> CREATOR
+ = new Parcelable.Creator<ThemeInfo>() {
+ public ThemeInfo createFromParcel(Parcel source) {
+ return new ThemeInfo(source);
+ }
+
+ public ThemeInfo[] newArray(int size) {
+ return new ThemeInfo[size];
+ }
+ };
+
+ private ThemeInfo(Parcel source) {
+ super(source);
+ }
+}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index ffefaa2..80d0946 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +19,7 @@ package android.content.res;
import android.os.ParcelFileDescriptor;
import android.util.Log;
+import android.util.SparseArray;
import android.util.TypedValue;
import java.io.FileNotFoundException;
@@ -77,6 +79,20 @@ public final class AssetManager {
private boolean mOpen = true;
private HashMap<Integer, RuntimeException> mRefStacks;
+ private String mAssetDir;
+ private String mAppName;
+
+ private boolean mThemeSupport;
+ private String mThemePackageName;
+ private int mThemeCookie;
+
+ /**
+ * Organize all added redirection maps using Java strong references to keep
+ * the native layer cleanup simple (that is, finalize() in Java will be
+ * responsible for delete in C++).
+ */
+ private SparseArray<PackageRedirectionMap> mRedirections;
+
/**
* Create a new AssetManager containing only the basic system assets.
* Applications will not generally use this method, instead retrieving the
@@ -252,6 +268,12 @@ public final class AssetManager {
}
}
+ /*package*/ final void recreateStringBlocks() {
+ synchronized (this) {
+ makeStringBlocks(true);
+ }
+ }
+
/*package*/ final void makeStringBlocks(boolean copyFromSystem) {
final int sysNum = copyFromSystem ? sSystem.mStringBlocks.length : 0;
final int num = getStringBlockCount();
@@ -460,6 +482,18 @@ public final class AssetManager {
/**
* {@hide}
+ * Split a theme package with DRM-protected resources into two files.
+ *
+ * @param packageFileName Original theme package file name.
+ * @param lockedFileName Name of the new "locked" file with DRM resources.
+ * @param drmProtectedresources Array of names of DRM-protected assets.
+ */
+ public final int splitDrmProtectedThemePackage(String packageFileName, String lockedFileName, String [] drmProtectedresources) {
+ return splitThemePackage(packageFileName, lockedFileName, drmProtectedresources);
+ }
+
+ /**
+ * {@hide}
* Retrieve a non-asset as a compiled XML file. Not for use by
* applications.
*
@@ -625,6 +659,110 @@ public final class AssetManager {
}
/**
+ * Delete a set of theme assets from the asset manager. Not for use by
+ * applications. Returns true if succeeded or false on failure.
+ *
+ * @hide
+ */
+ public native final boolean detachThemePath(String packageName, int cookie);
+
+ /**
+ * Attach a set of theme assets to the asset manager. If necessary, this
+ * method will forcefully update the internal ResTable data structure.
+ *
+ * @return Cookie of the added asset or 0 on failure.
+ * @hide
+ */
+ public native final int attachThemePath(String path);
+
+ /**
+ * Sets a flag indicating that this AssetManager should have themes
+ * attached, according to the initial request to create it by the
+ * ApplicationContext.
+ *
+ * {@hide}
+ */
+ public final void setThemeSupport(boolean themeSupport) {
+ mThemeSupport = themeSupport;
+ }
+
+ /**
+ * Should this AssetManager have themes attached, according to the initial
+ * request to create it by the ApplicationContext?
+ *
+ * {@hide}
+ */
+ public final boolean hasThemeSupport() {
+ return mThemeSupport;
+ }
+
+ /**
+ * Apply a heuristic to match-up all attributes from the source style with
+ * attributes in the destination style. For each match, an entry in the
+ * package redirection map will be inserted.
+ *
+ * {@hide}
+ */
+ public native final boolean generateStyleRedirections(int resMapNative, int sourceStyle,
+ int destStyle);
+
+ /**
+ * Get package name of current theme (may return null).
+ * {@hide}
+ */
+ public String getThemePackageName() {
+ return mThemePackageName;
+ }
+
+ /**
+ * Sets package name and highest level style id for current theme (null, 0 is allowed).
+ * {@hide}
+ */
+ public void setThemePackageName(String packageName) {
+ mThemePackageName = packageName;
+ }
+
+ /**
+ * Get asset cookie for current theme (may return 0).
+ * {@hide}
+ */
+ public int getThemeCookie() {
+ return mThemeCookie;
+ }
+
+ /**
+ * Sets asset cookie for current theme (0 if not a themed asset manager).
+ * {@hide}
+ */
+ public void setThemeCookie(int cookie) {
+ mThemeCookie = cookie;
+ }
+
+ /**
+ * Add a redirection map to the asset manager. All future resource lookups
+ * will consult this map.
+ * {@hide}
+ */
+ public void addRedirections(PackageRedirectionMap map) {
+ if (mRedirections == null) {
+ mRedirections = new SparseArray<PackageRedirectionMap>(2);
+ }
+ mRedirections.append(map.getPackageId(), map);
+ addRedirectionsNative(map.getNativePointer());
+ }
+
+ /**
+ * Clear redirection map for the asset manager.
+ * {@hide}
+ */
+ public void clearRedirections() {
+ if (mRedirections != null) {
+ mRedirections.clear();
+ }
+ clearRedirectionsNative();
+ }
+
+ /**
* Determine whether the state in this asset manager is up-to-date with
* the files on the filesystem. If false is returned, you need to
* instantiate a new AssetManager class to see the new data.
@@ -741,6 +879,26 @@ public final class AssetManager {
private native final int[] getArrayStringInfo(int arrayRes);
/*package*/ native final int[] getArrayIntResource(int arrayRes);
+ private native final int splitThemePackage(String srcFileName, String dstFileName, String [] drmProtectedAssetNames);
+
+ /**
+ * {@hide}
+ */
+ public native final int getBasePackageCount();
+
+ /**
+ * {@hide}
+ */
+ public native final String getBasePackageName(int index);
+
+ /**
+ * {@hide}
+ */
+ public native final int getBasePackageId(int index);
+
+ private native final void addRedirectionsNative(int redirectionMapNativePointer);
+ private native final void clearRedirectionsNative();
+
private native final void init();
private native final void destroy();
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 28c751c..789d25e 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -92,9 +92,15 @@ public class CompatibilityInfo implements Parcelable {
*/
public final float applicationInvertedScale;
+ /**
+ * Whether the application supports third-party theming.
+ */
+ public final boolean isThemeable;
+
public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
boolean forceCompat) {
int compatFlags = 0;
+ isThemeable = appInfo.isThemeable;
if (appInfo.requiresSmallestWidthDp != 0 || appInfo.compatibleWidthLimitDp != 0
|| appInfo.largestWidthLimitDp != 0) {
@@ -242,17 +248,19 @@ public class CompatibilityInfo implements Parcelable {
}
private CompatibilityInfo(int compFlags,
- int dens, float scale, float invertedScale) {
+ int dens, float scale, float invertedScale, boolean isThemeable) {
mCompatibilityFlags = compFlags;
applicationDensity = dens;
applicationScale = scale;
applicationInvertedScale = invertedScale;
+ this.isThemeable = isThemeable;
}
private CompatibilityInfo() {
this(NEVER_NEEDS_COMPAT, DisplayMetrics.DENSITY_DEVICE,
1.0f,
- 1.0f);
+ 1.0f,
+ true);
}
/**
@@ -524,6 +532,7 @@ public class CompatibilityInfo implements Parcelable {
if (applicationDensity != oc.applicationDensity) return false;
if (applicationScale != oc.applicationScale) return false;
if (applicationInvertedScale != oc.applicationInvertedScale) return false;
+ if (isThemeable != oc.isThemeable) return false;
return true;
} catch (ClassCastException e) {
return false;
@@ -561,6 +570,7 @@ public class CompatibilityInfo implements Parcelable {
result = 31 * result + applicationDensity;
result = 31 * result + Float.floatToIntBits(applicationScale);
result = 31 * result + Float.floatToIntBits(applicationInvertedScale);
+ result = 31 * result + (isThemeable ? 1 : 0);
return result;
}
@@ -575,6 +585,7 @@ public class CompatibilityInfo implements Parcelable {
dest.writeInt(applicationDensity);
dest.writeFloat(applicationScale);
dest.writeFloat(applicationInvertedScale);
+ dest.writeInt(isThemeable ? 1 : 0);
}
public static final Parcelable.Creator<CompatibilityInfo> CREATOR
@@ -593,5 +604,6 @@ public class CompatibilityInfo implements Parcelable {
applicationDensity = source.readInt();
applicationScale = source.readFloat();
applicationInvertedScale = source.readFloat();
+ isThemeable = source.readInt() == 1 ? true : false;
}
}
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 86d6ee7..3a6d307 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +22,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.view.View;
+import android.util.Log;
+import android.os.SystemProperties;
+import android.text.TextUtils;
import java.util.Locale;
@@ -66,6 +70,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
public Locale locale;
/**
+ * @hide
+ */
+ public CustomTheme customTheme;
+
+ /**
* Locale should persist on setting. This is hidden because it is really
* questionable whether this is the right way to expose the functionality.
* @hide
@@ -396,6 +405,22 @@ public final class Configuration implements Parcelable, Comparable<Configuration
public static final int ORIENTATION_LANDSCAPE = 2;
/** @deprecated Not currently supported or used. */
@Deprecated public static final int ORIENTATION_SQUARE = 3;
+
+
+ /**
+ * @hide
+ */
+ public static final int THEME_UNDEFINED = 0;
+
+ /**
+ * @hide
+ */
+ public static final String THEME_ID_PERSISTENCE_PROPERTY = "persist.sys.themeId";
+
+ /**
+ * @hide
+ */
+ public static final String THEME_PACKAGE_NAME_PERSISTENCE_PROPERTY = "persist.sys.themePackageName";
/**
* Overall orientation of the screen. May be one of
@@ -578,6 +603,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
compatScreenHeightDp = o.compatScreenHeightDp;
compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
seq = o.seq;
+ if (o.customTheme != null) {
+ customTheme = (CustomTheme) o.customTheme.clone();
+ }
}
public String toString() {
@@ -713,6 +741,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
sb.append(" s.");
sb.append(seq);
}
+ sb.append(" themeResource=");
+ sb.append(customTheme);
sb.append('}');
return sb.toString();
}
@@ -739,6 +769,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
densityDpi = DENSITY_DPI_UNDEFINED;
seq = 0;
+ customTheme = null;
}
/** {@hide} */
@@ -873,7 +904,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration
if (delta.seq != 0) {
seq = delta.seq;
}
-
+
+ if (delta.customTheme != null
+ && (customTheme == null || !customTheme.equals(delta.customTheme))) {
+ changed |= ActivityInfo.CONFIG_THEME_RESOURCE;
+ customTheme = (CustomTheme)delta.customTheme.clone();
+ }
+
return changed;
}
@@ -978,7 +1015,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
&& densityDpi != delta.densityDpi) {
changed |= ActivityInfo.CONFIG_DENSITY;
}
-
+ if (delta.customTheme != null &&
+ (customTheme == null || !customTheme.equals(delta.customTheme))) {
+ changed |= ActivityInfo.CONFIG_THEME_RESOURCE;
+ }
return changed;
}
@@ -994,7 +1034,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
* @return Return true if the resource needs to be loaded, else false.
*/
public static boolean needNewResources(int configChanges, int interestingChanges) {
- return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
+ return (configChanges & (interestingChanges |
+ ActivityInfo.CONFIG_FONT_SCALE |
+ ActivityInfo.CONFIG_THEME_RESOURCE)) != 0;
}
/**
@@ -1067,6 +1109,14 @@ public final class Configuration implements Parcelable, Comparable<Configuration
dest.writeInt(compatScreenHeightDp);
dest.writeInt(compatSmallestScreenWidthDp);
dest.writeInt(seq);
+
+ if (customTheme == null) {
+ dest.writeInt(0);
+ } else {
+ dest.writeInt(1);
+ dest.writeString(customTheme.getThemeId());
+ dest.writeString(customTheme.getThemePackageName());
+ }
}
public void readFromParcel(Parcel source) {
@@ -1095,6 +1145,12 @@ public final class Configuration implements Parcelable, Comparable<Configuration
compatScreenHeightDp = source.readInt();
compatSmallestScreenWidthDp = source.readInt();
seq = source.readInt();
+
+ if (source.readInt() != 0) {
+ String themeId = source.readString();
+ String themePackage = source.readString();
+ customTheme = new CustomTheme(themeId, themePackage);
+ }
}
public static final Parcelable.Creator<Configuration> CREATOR
@@ -1163,6 +1219,17 @@ public final class Configuration implements Parcelable, Comparable<Configuration
if (n != 0) return n;
n = this.densityDpi - that.densityDpi;
//if (n != 0) return n;
+ if (this.customTheme == null) {
+ if (that.customTheme != null) return 1;
+ } else if (that.customTheme == null) {
+ return -1;
+ } else {
+ n = this.customTheme.getThemeId().compareTo(that.customTheme.getThemeId());
+ if (n != 0) return n;
+ n = this.customTheme.getThemePackageName().compareTo(that.customTheme.getThemePackageName());
+ if (n != 0) return n;
+ }
+
return n;
}
@@ -1199,6 +1266,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
result = 31 * result + screenHeightDp;
result = 31 * result + smallestScreenWidthDp;
result = 31 * result + densityDpi;
+ result = 31 * result + (this.customTheme != null ?
+ this.customTheme.hashCode() : 0);
return result;
}
diff --git a/core/java/android/content/res/CustomTheme.java b/core/java/android/content/res/CustomTheme.java
new file mode 100644
index 0000000..364fb11
--- /dev/null
+++ b/core/java/android/content/res/CustomTheme.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2010, T-Mobile USA, Inc.
+ *
+ * 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.content.res;
+
+import android.os.SystemProperties;
+import android.text.TextUtils;
+
+/**
+ * @hide
+ */
+public final class CustomTheme implements Cloneable {
+ private final String mThemeId;
+ private final String mThemePackageName;
+
+ private static final CustomTheme sBootTheme = new CustomTheme();
+ private static final CustomTheme sSystemTheme = new CustomTheme("", "");
+
+ private CustomTheme() {
+ mThemeId = SystemProperties.get("persist.sys.themeId");
+ mThemePackageName = SystemProperties.get("persist.sys.themePackageName");
+ }
+
+ public CustomTheme(String themeId, String packageName) {
+ mThemeId = themeId;
+ mThemePackageName = packageName;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof CustomTheme) {
+ CustomTheme o = (CustomTheme) object;
+ if (!mThemeId.equals(o.mThemeId)) {
+ return false;
+ }
+ String currentPackageName = (mThemePackageName == null)? "" : mThemePackageName;
+ String newPackageName = (o.mThemePackageName == null)? "" : o.mThemePackageName;
+ String currentThemeId = (mThemeId == null)? "" : mThemeId;
+ String newThemeId = (o.mThemeId == null)? "" : o.mThemeId;
+
+ /* uhh, why are we trimming here instead of when the object is
+ * constructed? actually, why are we trimming at all? */
+ return (currentPackageName.trim().equalsIgnoreCase(newPackageName.trim())) &&
+ (currentThemeId.trim().equalsIgnoreCase(newThemeId.trim()));
+ }
+ return false;
+ }
+
+ @Override
+ public final String toString() {
+ StringBuilder result = new StringBuilder();
+ if (!TextUtils.isEmpty(mThemePackageName) && !TextUtils.isEmpty(mThemeId)) {
+ result.append(mThemePackageName);
+ result.append('(');
+ result.append(mThemeId);
+ result.append(')');
+ } else {
+ result.append("system");
+ }
+ return result.toString();
+ }
+
+ @Override
+ public synchronized int hashCode() {
+ return mThemeId.hashCode() + mThemePackageName.hashCode();
+ }
+
+ public String getThemeId() {
+ return mThemeId;
+ }
+
+ public String getThemePackageName() {
+ return mThemePackageName;
+ }
+
+ /**
+ * Represents the theme that the device booted into. This is used to
+ * simulate a "default" configuration based on the user's last known
+ * preference until the theme is switched at runtime.
+ */
+ public static CustomTheme getBootTheme() {
+ return sBootTheme;
+ }
+
+ /**
+ * Represents the system framework theme, perceived by the system as there
+ * being no theme applied.
+ */
+ public static CustomTheme getSystemTheme() {
+ return sSystemTheme;
+ }
+}
diff --git a/core/java/android/content/res/PackageRedirectionMap.aidl b/core/java/android/content/res/PackageRedirectionMap.aidl
new file mode 100644
index 0000000..4f47525
--- /dev/null
+++ b/core/java/android/content/res/PackageRedirectionMap.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2011, T-Mobile USA, Inc.
+ *
+ * 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.content.res;
+
+/**
+ * @hide
+ */
+parcelable PackageRedirectionMap;
diff --git a/core/java/android/content/res/PackageRedirectionMap.java b/core/java/android/content/res/PackageRedirectionMap.java
new file mode 100644
index 0000000..55c4282
--- /dev/null
+++ b/core/java/android/content/res/PackageRedirectionMap.java
@@ -0,0 +1,90 @@
+package android.content.res;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Native transport for package asset redirection information coming from the
+ * AssetRedirectionManagerService.
+ *
+ * @hide
+ */
+public class PackageRedirectionMap implements Parcelable {
+ private final int mNativePointer;
+
+ public static final Parcelable.Creator<PackageRedirectionMap> CREATOR
+ = new Parcelable.Creator<PackageRedirectionMap>() {
+ public PackageRedirectionMap createFromParcel(Parcel in) {
+ return new PackageRedirectionMap(in);
+ }
+
+ public PackageRedirectionMap[] newArray(int size) {
+ return new PackageRedirectionMap[size];
+ }
+ };
+
+ public PackageRedirectionMap() {
+ this(nativeConstructor());
+ }
+
+ private PackageRedirectionMap(Parcel in) {
+ this(nativeCreateFromParcel(in));
+ }
+
+ private PackageRedirectionMap(int nativePointer) {
+ if (nativePointer == 0) {
+ throw new RuntimeException();
+ }
+ mNativePointer = nativePointer;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ nativeDestructor(mNativePointer);
+ }
+
+ public int getNativePointer() {
+ return mNativePointer;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (!nativeWriteToParcel(mNativePointer, dest)) {
+ throw new RuntimeException();
+ }
+ }
+
+ public int getPackageId() {
+ return nativeGetPackageId(mNativePointer);
+ }
+
+ public void addRedirection(int fromIdent, int toIdent) {
+ nativeAddRedirection(mNativePointer, fromIdent, toIdent);
+ }
+
+ // Used for debugging purposes only.
+ public int[] getRedirectionKeys() {
+ return nativeGetRedirectionKeys(mNativePointer);
+ }
+
+ // Used for debugging purposes only.
+ public int lookupRedirection(int fromIdent) {
+ return nativeLookupRedirection(mNativePointer, fromIdent);
+ }
+
+ private static native int nativeConstructor();
+ private static native void nativeDestructor(int nativePointer);
+
+ private static native int nativeCreateFromParcel(Parcel p);
+ private static native boolean nativeWriteToParcel(int nativePointer, Parcel p);
+
+ private native void nativeAddRedirection(int nativePointer, int fromIdent, int toIdent);
+ private native int nativeGetPackageId(int nativePointer);
+ private native int[] nativeGetRedirectionKeys(int nativePointer);
+ private native int nativeLookupRedirection(int nativePointer, int fromIdent);
+}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index b316f23..c271f85 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1447,7 +1447,15 @@ public class Resources {
mTmpConfig.setLayoutDirection(mTmpConfig.locale);
}
configChanges = mConfiguration.updateFrom(mTmpConfig);
- configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
+
+ /* This is ugly, but modifying the activityInfoConfigToNative
+ * adapter would be messier */
+ if ((configChanges & ActivityInfo.CONFIG_THEME_RESOURCE) != 0) {
+ configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
+ configChanges |= ActivityInfo.CONFIG_THEME_RESOURCE;
+ } else {
+ configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
+ }
}
if (mConfiguration.locale == null) {
mConfiguration.locale = Locale.getDefault();
@@ -1514,6 +1522,18 @@ public class Resources {
private void clearDrawableCache(
LongSparseArray<WeakReference<ConstantState>> cache,
int configChanges) {
+ /*
+ * Quick test to find out if the config change that occurred should
+ * trigger a full cache wipe.
+ */
+ if (Configuration.needNewResources(configChanges, 0)) {
+ if (DEBUG_CONFIG) {
+ Log.d(TAG, "Clear drawable cache from config changes: 0x"
+ + Integer.toHexString(configChanges));
+ }
+ cache.clear();
+ return;
+ }
int N = cache.size();
if (DEBUG_CONFIG) {
Log.d(TAG, "Cleaning up drawables config changes: 0x"
@@ -1886,6 +1906,13 @@ public class Resources {
return true;
}
+ /** @hide */
+ public final void updateStringCache() {
+ synchronized (mTmpValue) {
+ mAssets.recreateStringBlocks();
+ }
+ }
+
/*package*/ Drawable loadDrawable(TypedValue value, int id)
throws NotFoundException {
diff --git a/core/java/android/database/sqlite/SQLiteSession.java b/core/java/android/database/sqlite/SQLiteSession.java
index beb5b3a..d80ab1f 100644
--- a/core/java/android/database/sqlite/SQLiteSession.java
+++ b/core/java/android/database/sqlite/SQLiteSession.java
@@ -926,7 +926,7 @@ public final class SQLiteSession {
}
private void throwIfNestedTransaction() {
- if (mTransactionStack == null && mTransactionStack.mParent != null) {
+ if (hasNestedTransaction()) {
throw new IllegalStateException("Cannot perform this operation because "
+ "a nested transaction is in progress.");
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index a300776..5c074ed 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1685,6 +1685,7 @@ public class Camera {
private static final String KEY_SCENE_MODE = "scene-mode";
private static final String KEY_FLASH_MODE = "flash-mode";
private static final String KEY_FOCUS_MODE = "focus-mode";
+ private static final String KEY_ISO_MODE = "iso";
private static final String KEY_FOCUS_AREAS = "focus-areas";
private static final String KEY_MAX_NUM_FOCUS_AREAS = "max-num-focus-areas";
private static final String KEY_FOCAL_LENGTH = "focal-length";
@@ -1715,6 +1716,9 @@ public class Camera {
private static final String KEY_VIDEO_SNAPSHOT_SUPPORTED = "video-snapshot-supported";
private static final String KEY_VIDEO_STABILIZATION = "video-stabilization";
private static final String KEY_VIDEO_STABILIZATION_SUPPORTED = "video-stabilization-supported";
+ private static final String KEY_POWER_MODE_SUPPORTED = "power-mode-supported";
+
+ private static final String KEY_POWER_MODE = "power-mode";
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -1749,6 +1753,10 @@ public class Camera {
public static final String ANTIBANDING_60HZ = "60hz";
public static final String ANTIBANDING_OFF = "off";
+ // Values for POWER MODE
+ public static final String LOW_POWER = "Low_Power";
+ public static final String NORMAL_POWER = "Normal_Power";
+
// Values for flash mode settings.
/**
* Flash will not be fired.
@@ -1778,6 +1786,32 @@ public class Camera {
*/
public static final String FLASH_MODE_TORCH = "torch";
+ //Values for ISO settings
+ /** @hide */
+ public static final String ISO_AUTO = "auto";
+ /** @hide */
+ public static final String ISO_HJR = "ISO_HJR";
+ /** @hide */
+ public static final String ISO_SPORTS = "ISO_SPORTS";
+ /** @hide */
+ public static final String ISO_NIGHT = "ISO_NIGHT";
+ /** @hide */
+ public static final String ISO_MOVIE = "ISO_MOVIE";
+ /** @hide */
+ public static final String ISO_100 = "ISO100";
+ /** @hide */
+ public static final String ISO_200 = "ISO200";
+ /** @hide */
+ public static final String ISO_400 = "ISO400";
+ /** @hide */
+ public static final String ISO_800 = "ISO800";
+ /** @hide */
+ public static final String ISO_1600 = "ISO1600";
+ /** @hide */
+ public static final String ISO_3200 = "ISO3200";
+ /** @hide */
+ public static final String ISO_6400 = "ISO6400";
+
/**
* Scene mode is off.
*/
@@ -2944,6 +2978,28 @@ public class Camera {
}
/**
+ * Sets the Power mode.
+ *
+ * @param value Power mode.
+ * @see #getPowerMode()
+ */
+ public void setPowerMode(String value) {
+ set(KEY_POWER_MODE, value);
+ }
+
+ /**
+ * Gets the current power mode setting.
+ *
+ * @return current power mode. null if power mode setting is not
+ * supported.
+ * @see #POWER_MODE_LOW
+ * @see #POWER_MODE_NORMAL
+ */
+ public String getPowerMode() {
+ return get(KEY_POWER_MODE);
+ }
+
+ /**
* Gets the current focus mode setting.
*
* @return current focus mode. This method will always return a non-null
@@ -3288,6 +3344,39 @@ public class Camera {
}
/**
+ * Gets the current ISO setting.
+ *
+ * @return one of ISO_XXX string constant. null if ISO
+ * setting is not supported.
+ * @hide
+ */
+ public String getISOValue() {
+ return get(KEY_ISO_MODE);
+ }
+
+ /**
+ * Sets the ISO.
+ *
+ * @param iso ISO_XXX string constant.
+ * @hide
+ */
+ public void setISOValue(String iso) {
+ set(KEY_ISO_MODE, iso);
+ }
+
+ /**
+ * Gets the supported ISO values.
+ *
+ * @return a List of ISO_MODE_XXX string constants. null if iso mode
+ * setting is not supported.
+ * @hide
+ */
+ public List<String> getSupportedIsoValues() {
+ String str = get(KEY_ISO_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /**
* <p>Gets the distances from the camera to where an object appears to be
* in focus. The object is sharpest at the optimal focus distance. The
* depth of field is the far focus distance minus near focus distance.</p>
@@ -3527,6 +3616,14 @@ public class Camera {
}
/**
+ * @return true if full size video snapshot is supported.
+ */
+ public boolean isPowerModeSupported() {
+ String str = get(KEY_POWER_MODE_SUPPORTED);
+ return TRUE.equals(str);
+ }
+
+ /**
* <p>Enables and disables video stabilization. Use
* {@link #isVideoStabilizationSupported} to determine if calling this
* method is valid.</p>
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 6f1cc94..ea4e488 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -248,6 +248,20 @@ public class InputMethodService extends AbstractInputMethodService {
*/
public static final int IME_VISIBLE = 0x2;
+ int mVolumeKeyCursorControl = 0;
+ /**
+ * @hide
+ */
+ public static final int VOLUME_CURSOR_OFF = 0;
+ /**
+ * @hide
+ */
+ public static final int VOLUME_CURSOR_ON = 1;
+ /**
+ * @hide
+ */
+ public static final int VOLUME_CURSOR_ON_REVERSE = 2;
+
InputMethodManager mImm;
int mTheme = 0;
@@ -1760,6 +1774,26 @@ public class InputMethodService extends AbstractInputMethodService {
}
return false;
}
+ if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
+ mVolumeKeyCursorControl = Settings.System.getInt(getContentResolver(),
+ Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0);
+ if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) {
+ sendDownUpKeyEvents((mVolumeKeyCursorControl == VOLUME_CURSOR_ON_REVERSE)
+ ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT);
+ return true;
+ }
+ return false;
+ }
+ if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ mVolumeKeyCursorControl = Settings.System.getInt(getContentResolver(),
+ Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0);
+ if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) {
+ sendDownUpKeyEvents((mVolumeKeyCursorControl == VOLUME_CURSOR_ON_REVERSE)
+ ? KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT);
+ return true;
+ }
+ return false;
+ }
return doMovementKey(keyCode, event, MOVEMENT_DOWN);
}
@@ -1805,7 +1839,15 @@ public class InputMethodService extends AbstractInputMethodService {
&& !event.isCanceled()) {
return handleBack(true);
}
-
+ if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
+ || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ mVolumeKeyCursorControl = Settings.System.getInt(getContentResolver(),
+ Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0);
+ if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) {
+ return true;
+ }
+ return false;
+ }
return doMovementKey(keyCode, event, MOVEMENT_UP);
}
diff --git a/core/java/android/net/wimax/WimaxHelper.java b/core/java/android/net/wimax/WimaxHelper.java
new file mode 100644
index 0000000..f6c7a40
--- /dev/null
+++ b/core/java/android/net/wimax/WimaxHelper.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2011 The CyanogenMod 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.wimax;
+
+import dalvik.system.DexClassLoader;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.provider.Settings;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/**
+ * {@hide}
+ */
+public class WimaxHelper {
+
+ private static final String TAG = "WimaxHelper";
+
+ private static final String WIMAX_CONTROLLER_CLASSNAME = "com.htc.net.wimax.WimaxController";
+ private static final String WIMAX_MANAGER_CLASSNAME = "android.net.fourG.wimax.Wimax4GManager";
+
+ private static DexClassLoader sWimaxClassLoader;
+ private static String sWimaxManagerClassname, sIsWimaxEnabledMethodname,
+ sSetWimaxEnabledMethodname, sGetWimaxStateMethodname;
+
+ public static boolean isWimaxSupported(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_wimaxEnabled);
+ }
+
+ public static DexClassLoader getWimaxClassLoader(Context context) {
+ if (isWimaxSupported(context)) {
+ if (sWimaxClassLoader == null) {
+ sWimaxManagerClassname = context.getResources().getString(
+ com.android.internal.R.string.config_wimaxManagerClassname);
+
+ // WimaxController::getWimaxState == Wimax4GManager::get4GState.
+ // However, Wimax4GManager also implements a different getWimaxState
+ // method, which returns a WimaxState object describing the connection
+ // state, not the enabled state. Other methods are similarly renamed.
+ if (sWimaxManagerClassname.equals(WIMAX_CONTROLLER_CLASSNAME)) {
+ sIsWimaxEnabledMethodname = "isWimaxEnabled";
+ sSetWimaxEnabledMethodname = "setWimaxEnabled";
+ sGetWimaxStateMethodname = "getWimaxState";
+ } else if (sWimaxManagerClassname.equals(WIMAX_MANAGER_CLASSNAME)) {
+ sIsWimaxEnabledMethodname = "is4GEnabled";
+ sSetWimaxEnabledMethodname = "set4GEnabled";
+ sGetWimaxStateMethodname = "get4GState";
+ }
+
+ String wimaxJarLocation = context.getResources().getString(
+ com.android.internal.R.string.config_wimaxServiceJarLocation);
+ String wimaxLibLocation = context.getResources().getString(
+ com.android.internal.R.string.config_wimaxNativeLibLocation);
+ sWimaxClassLoader = new DexClassLoader(wimaxJarLocation,
+ new ContextWrapper(context).getCacheDir().getAbsolutePath(),
+ wimaxLibLocation,ClassLoader.getSystemClassLoader());
+ }
+ return sWimaxClassLoader;
+ }
+ return null;
+ }
+
+ public static Object createWimaxService(Context context, Handler handler) {
+ Object controller = null;
+
+ try {
+ DexClassLoader wimaxClassLoader = getWimaxClassLoader(context);
+ if (sWimaxManagerClassname.equals(WIMAX_CONTROLLER_CLASSNAME)) {
+ // Load supersonic's and speedy's WimaxController.
+ IBinder b = ServiceManager.getService(WimaxManagerConstants.WIMAX_SERVICE);
+ if (b != null) {
+ Class<?> klass = wimaxClassLoader.loadClass("com.htc.net.wimax.IWimaxController$Stub");
+ if (klass != null) {
+ Method asInterface = klass.getMethod("asInterface", IBinder.class);
+ Object wc = asInterface.invoke(null, b);
+ if (wc != null) {
+ klass = wimaxClassLoader.loadClass(WIMAX_CONTROLLER_CLASSNAME);
+ if (klass != null) {
+ Constructor<?> ctor = klass.getDeclaredConstructors()[1];
+ controller = ctor.newInstance(wc, handler);
+ }
+ }
+ }
+ }
+ } else if (sWimaxManagerClassname.equals(WIMAX_MANAGER_CLASSNAME)) {
+ // Load crespo4g's (and epicmtd's) Wimax4GManager.
+ // Note that crespo4g's implementation grabs WIMAX_SERVICE internally, so
+ // it doesn't need to be passed in. Other implementations (may) require
+ // WIMAX_SERVICE to be grabbed externally, so check Wimax4GManager::<init>.
+ Class<?> klass = wimaxClassLoader.loadClass(WIMAX_MANAGER_CLASSNAME);
+ if (klass != null) {
+ Constructor<?> ctor = klass.getDeclaredConstructors()[0];
+ controller = ctor.newInstance();
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to create WimaxController instance", e);
+ }
+
+ return controller;
+ }
+
+ public static boolean isWimaxEnabled(Context context) {
+ boolean ret = false;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method m = wimaxService.getClass().getMethod(sIsWimaxEnabledMethodname);
+ ret = (Boolean) m.invoke(wimaxService);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to get WiMAX enabled state!", e);
+ }
+ return ret;
+ }
+
+ public static boolean setWimaxEnabled(Context context, boolean enabled) {
+ boolean ret = false;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method m = wimaxService.getClass().getMethod(sSetWimaxEnabledMethodname, boolean.class);
+ ret = (Boolean) m.invoke(wimaxService, enabled);
+ if (ret)
+ Settings.Secure.putInt(context.getContentResolver(),
+ Settings.Secure.WIMAX_ON, (Boolean) enabled ? 1 : 0);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to set WiMAX state!", e);
+ }
+ return ret;
+ }
+
+ public static int getWimaxState(Context context) {
+ int ret = 0;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method m = wimaxService.getClass().getMethod(sGetWimaxStateMethodname);
+ ret = (Integer) m.invoke(wimaxService);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to get WiMAX state!", e);
+ }
+ return ret;
+ }
+
+ public static boolean wimaxRescan(Context context) {
+ boolean ret = false;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method wimaxRescan = wimaxService.getClass().getMethod("wimaxRescan");
+ if (wimaxRescan != null) {
+ wimaxRescan.invoke(wimaxService);
+ ret = true;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to perform WiMAX rescan!", e);
+ }
+ return ret;
+ }
+
+ private static Object getWimaxInfo(Context context) {
+ Object wimaxInfo = null;
+ try {
+ Object wimaxService = context.getSystemService(WimaxManagerConstants.WIMAX_SERVICE);
+ Method getConnectionInfo = wimaxService.getClass().getMethod("getConnectionInfo");
+ wimaxInfo = getConnectionInfo.invoke(wimaxService);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to get a WimaxInfo object!", e);
+ }
+ return wimaxInfo;
+ }
+}
diff --git a/core/java/android/net/wimax/WimaxManagerConstants.java b/core/java/android/net/wimax/WimaxManagerConstants.java
index b4aaf5b..adb7166 100644
--- a/core/java/android/net/wimax/WimaxManagerConstants.java
+++ b/core/java/android/net/wimax/WimaxManagerConstants.java
@@ -24,7 +24,7 @@ public class WimaxManagerConstants
* The lookup key for an int that indicates whether Wimax is enabled,
* disabled, enabling, disabling, or unknown.
*/
- public static final String EXTRA_WIMAX_STATUS = "wimax_status";
+ public static final String EXTRA_4G_STATE = "4g_state";
/**
* Broadcast intent action indicating that Wimax state has been changed
@@ -48,7 +48,6 @@ public class WimaxManagerConstants
* initializing, initialized, unknown and ready.
*/
public static final String EXTRA_WIMAX_STATE = "WimaxState";
- public static final String EXTRA_4G_STATE = "4g_state";
public static final String EXTRA_WIMAX_STATE_INT = "WimaxStateInt";
/**
* The lookup key for an int that indicates whether state of Wimax
@@ -67,11 +66,21 @@ public class WimaxManagerConstants
public static final int NET_4G_STATE_DISABLED = 1;
/**
+ * Indicatates Wimax is disabling.
+ */
+ public static final int NET_4G_STATE_DISABLING = 0;
+
+ /**
* Indicatates Wimax is enabled.
*/
public static final int NET_4G_STATE_ENABLED = 3;
/**
+ * Indicatates Wimax is enabling.
+ */
+ public static final int NET_4G_STATE_ENABLING = 2;
+
+ /**
* Indicatates Wimax status is known.
*/
public static final int NET_4G_STATE_UNKNOWN = 4;
@@ -101,4 +110,9 @@ public class WimaxManagerConstants
*/
public static final int WIMAX_STATE_DISCONNECTED = 9;
+ /**
+ * Constants for HTC/SQN WiMAX implementation
+ */
+ public static final String WIMAX_ENABLED_CHANGED_ACTION = "com.htc.net.wimax.WIMAX_ENABLED_CHANGED";
+ public static final String CURRENT_WIMAX_ENABLED_STATE = "curWimaxEnabledState";
}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index f2cd232..d73951d 100644..100755
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -27,6 +27,8 @@ import android.nfc.tech.NfcB;
import android.nfc.tech.NfcBarcode;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
+import android.nfc.tech.IsoPcdA;
+import android.nfc.tech.IsoPcdB;
import android.nfc.tech.TagTechnology;
import android.os.Bundle;
import android.os.Parcel;
@@ -188,6 +190,12 @@ public final class Tag implements Parcelable {
case TagTechnology.NFC_BARCODE:
strings[i] = NfcBarcode.class.getName();
break;
+ case TagTechnology.ISO_PCD_A:
+ strings[i] = IsoPcdA.class.getName();
+ break;
+ case TagTechnology.ISO_PCD_B:
+ strings[i] = IsoPcdB.class.getName();
+ break;
default:
throw new IllegalArgumentException("Unknown tech type " + techList[i]);
}
diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/core/java/android/nfc/tech/BasicTagTechnology.java
index b6b347c..b6b347c 100644..100755
--- a/core/java/android/nfc/tech/BasicTagTechnology.java
+++ b/core/java/android/nfc/tech/BasicTagTechnology.java
diff --git a/core/java/android/nfc/tech/IsoPcdA.java b/core/java/android/nfc/tech/IsoPcdA.java
new file mode 100755
index 0000000..0795fc6
--- /dev/null
+++ b/core/java/android/nfc/tech/IsoPcdA.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * HOST CARD EMULATION PATCH 0.01
+ * Author: doug yeager (doug@simplytapp.com)
+ *
+ * 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.nfc.tech;
+
+import android.nfc.ErrorCodes;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Provides access to ISO-PCD type A (ISO 14443-4) properties and I/O operations on a {@link Tag}.
+ *
+ * <p>Acquire an {@link IsoPcdA} object using {@link #get}.
+ * <p>The primary ISO-PCD type A I/O operation is {@link #transceive}. Applications must
+ * implement their own protocol stack on top of {@link #transceive}.
+ *
+ * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
+ * require the {@link android.Manifest.permission#NFC} permission.
+ * @hide
+ */
+public final class IsoPcdA extends BasicTagTechnology {
+
+ /**
+ * Get an instance of {@link IsoPcdA} for the given tag.
+ * <p>Does not cause any RF activity and does not block.
+ * <p>Returns null if {@link IsoPcdA} was not enumerated in {@link Tag#getTechList}.
+ * This indicates the tag does not support ISO-PCD type A.
+ *
+ * @param tag an ISO-PCD type A compatible PCD
+ * @return ISO-PCD type A object
+ */
+ public static IsoPcdA get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.ISO_PCD_A)) return null;
+ try {
+ return new IsoPcdA(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public IsoPcdA(Tag tag)
+ throws RemoteException {
+ super(tag, TagTechnology.ISO_PCD_A);
+ Bundle extras = tag.getTechExtras(TagTechnology.ISO_PCD_A);
+ }
+
+ /**
+ * Send raw ISO-PCD type A data to the PCD and receive the response.
+ *
+ * <p>Applications must only send the INF payload, and not the start of frame and
+ * end of frame indicators. Applications do not need to fragment the payload, it
+ * will be automatically fragmented and defragmented by {@link #transceive} if
+ * it exceeds FSD/FSC limits.
+ *
+ * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
+ * that can be sent with {@link #transceive}.
+ *
+ * <p>This is an I/O operation and will block until complete. It must
+ * not be called from the main application thread. A blocked call will be canceled with
+ * {@link IOException} if {@link #close} is called from another thread.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param data - on the first call to transceive after PCD activation, the data sent to the method will be ignored
+ * @return response bytes received, will not be null
+ * @throws TagLostException if the tag leaves the field
+ * @throws IOException if there is an I/O failure, or this operation is canceled
+ */
+ public byte[] transceive(byte[] data) throws IOException {
+ return transceive(data, true);
+ }
+
+ /**
+ * Return the maximum number of bytes that can be sent with {@link #transceive}.
+ * @return the maximum number of bytes that can be sent with {@link #transceive}.
+ */
+ public int getMaxTransceiveLength() {
+ return getMaxTransceiveLengthInternal();
+ }
+}
diff --git a/core/java/android/nfc/tech/IsoPcdB.java b/core/java/android/nfc/tech/IsoPcdB.java
new file mode 100755
index 0000000..88f28af
--- /dev/null
+++ b/core/java/android/nfc/tech/IsoPcdB.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * HOST CARD EMULATION PATCH 0.01
+ * Author: doug yeager (doug@simplytapp.com)
+ *
+ * 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.nfc.tech;
+
+import android.nfc.ErrorCodes;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Provides access to ISO-PCD type B (ISO 14443-4) properties and I/O operations on a {@link Tag}.
+ *
+ * <p>Acquire an {@link IsoPcdB} object using {@link #get}.
+ * <p>The primary ISO-PCD type B I/O operation is {@link #transceive}. Applications must
+ * implement their own protocol stack on top of {@link #transceive}.
+ *
+ * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
+ * require the {@link android.Manifest.permission#NFC} permission.
+ * @hide
+ */
+public final class IsoPcdB extends BasicTagTechnology {
+
+ /**
+ * Get an instance of {@link IsoPcdB} for the given tag.
+ * <p>Does not cause any RF activity and does not block.
+ * <p>Returns null if {@link IsoPcdB} was not enumerated in {@link Tag#getTechList}.
+ * This indicates the tag does not support ISO-PCD type B.
+ *
+ * @param tag an ISO-PCD type B compatible PCD
+ * @return ISO-PCD type B object
+ */
+ public static IsoPcdB get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.ISO_PCD_B)) return null;
+ try {
+ return new IsoPcdB(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public IsoPcdB(Tag tag)
+ throws RemoteException {
+ super(tag, TagTechnology.ISO_PCD_B);
+ Bundle extras = tag.getTechExtras(TagTechnology.ISO_PCD_B);
+ }
+
+ /**
+ * Send raw ISO-PCD type B data to the PCD and receive the response.
+ *
+ * <p>Applications must only send the INF payload, and not the start of frame and
+ * end of frame indicators. Applications do not need to fragment the payload, it
+ * will be automatically fragmented and defragmented by {@link #transceive} if
+ * it exceeds FSD/FSC limits.
+ *
+ * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
+ * that can be sent with {@link #transceive}.
+ *
+ * <p>This is an I/O operation and will block until complete. It must
+ * not be called from the main application thread. A blocked call will be canceled with
+ * {@link IOException} if {@link #close} is called from another thread.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param data - on the first call to transceive after PCD activation, the data sent to the method will be ignored
+ * @return response bytes received, will not be null
+ * @throws TagLostException if the tag leaves the field
+ * @throws IOException if there is an I/O failure, or this operation is canceled
+ */
+ public byte[] transceive(byte[] data) throws IOException {
+ return transceive(data, true);
+ }
+
+ /**
+ * Return the maximum number of bytes that can be sent with {@link #transceive}.
+ * @return the maximum number of bytes that can be sent with {@link #transceive}.
+ */
+ public int getMaxTransceiveLength() {
+ return getMaxTransceiveLengthInternal();
+ }
+}
diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java
index 3493ea7..07b81c8 100644..100755
--- a/core/java/android/nfc/tech/TagTechnology.java
+++ b/core/java/android/nfc/tech/TagTechnology.java
@@ -157,6 +157,24 @@ public interface TagTechnology extends Closeable {
public static final int NFC_BARCODE = 10;
/**
+ * This technology is an instance of {@link IsoPcdA}.
+ * <p>Support for this technology type is optional. If a stack doesn't support this technology
+ * type tags using it must still be discovered and present the lower level radio interface
+ * technologies in use.
+ * @hide
+ */
+ public static final int ISO_PCD_A = 11;
+
+ /**
+ * This technology is an instance of {@link IsoPcdB}.
+ * <p>Support for this technology type is optional. If a stack doesn't support this technology
+ * type tags using it must still be discovered and present the lower level radio interface
+ * technologies in use.
+ * @hide
+ */
+ public static final int ISO_PCD_B = 12;
+
+ /**
* Get the {@link Tag} object backing this {@link TagTechnology} object.
* @return the {@link Tag} backing this {@link TagTechnology} object.
*/
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 2e38960..71c6d1e 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -26,7 +26,7 @@ public class BatteryManager {
* integer containing the current status constant.
*/
public static final String EXTRA_STATUS = "status";
-
+
/**
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
* integer containing the current health constant.
@@ -38,14 +38,14 @@ public class BatteryManager {
* boolean indicating whether a battery is present.
*/
public static final String EXTRA_PRESENT = "present";
-
+
/**
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
* integer field containing the current battery level, from 0 to
* {@link #EXTRA_SCALE}.
*/
public static final String EXTRA_LEVEL = "level";
-
+
/**
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
* integer containing the maximum battery level.
@@ -93,6 +93,28 @@ public class BatteryManager {
*/
public static final String EXTRA_INVALID_CHARGER = "invalid_charger";
+ // Dock intents
+ /** @hide **/
+ public static final String EXTRA_DOCK_STATUS = "dock_status";
+ /** @hide **/
+ public static final String EXTRA_DOCK_HEALTH = "dock_health";
+ /** @hide **/
+ public static final String EXTRA_DOCK_PRESENT = "dock_present";
+ /** @hide **/
+ public static final String EXTRA_DOCK_LEVEL = "dock_level";
+ /** @hide **/
+ public static final String EXTRA_DOCK_SCALE = "dock_scale";
+ /** @hide **/
+ public static final String EXTRA_DOCK_ICON_SMALL = "dock_icon-small";
+ /** @hide **/
+ public static final String EXTRA_DOCK_PLUGGED = "dock_plugged";
+ /** @hide **/
+ public static final String EXTRA_DOCK_VOLTAGE = "dock_voltage";
+ /** @hide **/
+ public static final String EXTRA_DOCK_TEMPERATURE = "dock_temperature";
+ /** @hide **/
+ public static final String EXTRA_DOCK_TECHNOLOGY = "dock_technology";
+
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
public static final int BATTERY_STATUS_UNKNOWN = 1;
public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 9821824..122133c 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -826,12 +826,13 @@ public abstract class BatteryStats implements Parcelable {
public static final int DATA_CONNECTION_EVDO_B = 12;
public static final int DATA_CONNECTION_LTE = 13;
public static final int DATA_CONNECTION_EHRPD = 14;
- public static final int DATA_CONNECTION_OTHER = 15;
+ public static final int DATA_CONNECTION_HSPAP = 15;
+ public static final int DATA_CONNECTION_OTHER = 16;
static final String[] DATA_CONNECTION_NAMES = {
"none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
"1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
- "ehrpd", "other"
+ "ehrpd", "hspap", "other"
};
public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 6d6d147..24849bd 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -51,4 +51,8 @@ interface IPowerManager
// sets the attention light (used by phone app only)
void setAttentionLight(boolean on, int color);
+
+ void cpuBoost(int duration);
+
+ void setKeyboardVisibility(boolean visible);
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 736762f..583b366 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -606,6 +606,24 @@ public final class PowerManager {
}
/**
+ * Boost the CPU. Boosts the cpu for the given duration in microseconds.
+ * Requires the {@link android.Manifest.permission#CPU_BOOST} permission.
+ *
+ * @param duration in microseconds to boost the CPU
+ *
+ * @hide
+ */
+ public void cpuBoost(int duration)
+ {
+ try {
+ if (mService != null) {
+ mService.cpuBoost(duration);
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* A wake lock is a mechanism to indicate that your application needs
* to have the device stay on.
* <p>
@@ -824,4 +842,17 @@ public final class PowerManager {
}
}
}
+
+ /**
+ * @hide
+ */
+ public void setKeyboardVisibility(boolean visible)
+ {
+ try {
+ if (mService != null) {
+ mService.setKeyboardVisibility(visible);
+ }
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 156600e..a9584d0 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +33,8 @@ public class SystemProperties
public static final int PROP_NAME_MAX = 31;
public static final int PROP_VALUE_MAX = 91;
+ public static final boolean QCOM_HARDWARE = native_get_boolean("com.qc.hardware", false);
+
private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
private static native String native_get(String key);
@@ -153,4 +156,49 @@ public class SystemProperties
}
}
}
+
+ /**
+ * Get the value for the given key.
+ * @return def string if the key isn't found
+ */
+ public static String getLongString(String key, String def) {
+ if (key.length() + 1 > PROP_NAME_MAX) {
+ throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
+ }
+ int chunks = getInt(key + '0', 0);
+ if (chunks == 0) {
+ return def;
+ }
+ StringBuffer sb = new StringBuffer();
+ for (int i = 1; i <= chunks; i++) {
+ sb.append(native_get(key + Integer.toString(i)));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Set the value for the given key.
+ * @throws IllegalArgumentException if the key exceeds 32 characters
+ */
+ public static void setLongString(String key, String val) {
+ if (key.length() + 1 > PROP_NAME_MAX) {
+ throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
+ }
+ int chunks = 0;
+ if (val != null && val.length() > 0) {
+ chunks = 1 + val.length() / (PROP_VALUE_MAX + 1);
+ }
+ native_set(key + '0', Integer.toString(chunks));
+ if (chunks > 0) {
+ for (int i = 1, start = 0; i <= chunks; i++) {
+ int end = start + PROP_VALUE_MAX;
+ if (end > val.length()) {
+ end = val.length();
+ }
+ native_set(key + Integer.toString(i), val.substring(start, end));
+ start = end;
+ }
+ }
+ }
+
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 0ca9183..812dea7 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -98,7 +98,7 @@ public final class Trace {
private static long cacheEnabledTags() {
long tags = nativeGetEnabledTags();
if (tags == TRACE_TAG_NOT_READY) {
- Log.w(TAG, "Unexpected value from nativeGetEnabledTags: " + tags);
+ //Log.w(TAG, "Unexpected value from nativeGetEnabledTags: " + tags);
// keep going
}
sEnabledTags = tags;
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 09ff7be..3e504e5 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -150,6 +150,10 @@ public abstract class PreferenceActivity extends ListActivity implements
*/
public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":android:show_fragment_title";
+ // fix for title text for startPreferencePanel in a single pane mode
+ /** @hide */
+ public static final String EXTRA_SHOW_FRAGMENT_TITLE_TEXT = ":android:show_fragment_title_text";
+
/**
* When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
* this extra can also be specify to supply the short title to be shown for
@@ -158,6 +162,11 @@ public abstract class PreferenceActivity extends ListActivity implements
public static final String EXTRA_SHOW_FRAGMENT_SHORT_TITLE
= ":android:show_fragment_short_title";
+ // fix for short title text for startPreferencePanel in a single pane mode
+ /** @hide */
+ public static final String EXTRA_SHOW_FRAGMENT_SHORT_TITLE_TEXT
+ = ":android:show_fragment_short_title_text";
+
/**
* When starting this activity, the invoking Intent can contain this extra
* boolean that the header list should not be displayed. This is most often
@@ -542,6 +551,13 @@ public abstract class PreferenceActivity extends ListActivity implements
CharSequence initialShortTitleStr = initialShortTitle != 0
? getText(initialShortTitle) : null;
showBreadCrumbs(initialTitleStr, initialShortTitleStr);
+ } else {
+ CharSequence initialTitleStr = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE_TEXT);
+ if ( initialTitleStr != null ) {
+ CharSequence initialShortTitleStr
+ = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT_SHORT_TITLE_TEXT);
+ showBreadCrumbs(initialTitleStr, initialShortTitleStr);
+ }
}
} else {
@@ -575,6 +591,13 @@ public abstract class PreferenceActivity extends ListActivity implements
CharSequence initialShortTitleStr = initialShortTitle != 0
? getText(initialShortTitle) : null;
showBreadCrumbs(initialTitleStr, initialShortTitleStr);
+ } else {
+ CharSequence initialTitleStr = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE_TEXT);
+ if ( initialTitleStr != null ) {
+ CharSequence initialShortTitleStr
+ = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT_SHORT_TITLE_TEXT);
+ showBreadCrumbs(initialTitleStr, initialShortTitleStr);
+ }
}
} else if (mHeaders.size() > 0) {
setListAdapter(new HeaderAdapter(this, mHeaders));
@@ -1026,7 +1049,21 @@ public abstract class PreferenceActivity extends ListActivity implements
intent.putExtra(EXTRA_NO_HEADERS, true);
return intent;
}
-
+
+ // fix for title text for startPreferencePanel in a single pane mode
+ /** @hide */
+ public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
+ CharSequence titleText, CharSequence shortTitleText) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClass(this, getClass());
+ intent.putExtra(EXTRA_SHOW_FRAGMENT, fragmentName);
+ intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+ intent.putExtra(EXTRA_SHOW_FRAGMENT_TITLE_TEXT, titleText);
+ intent.putExtra(EXTRA_SHOW_FRAGMENT_SHORT_TITLE_TEXT, shortTitleText);
+ intent.putExtra(EXTRA_NO_HEADERS, true);
+ return intent;
+ }
+
/**
* Like {@link #startWithFragment(String, Bundle, Fragment, int, int, int)}
* but uses a 0 titleRes.
@@ -1063,6 +1100,18 @@ public abstract class PreferenceActivity extends ListActivity implements
}
}
+ // fix for title text for startPreferencePanel in a single pane mode
+ /** @hide */
+ public void startWithFragment(String fragmentName, Bundle args, Fragment resultTo,
+ int resultRequestCode, CharSequence titleText, CharSequence shortTitleText) {
+ Intent intent = onBuildStartFragmentIntent(fragmentName, args, titleText, shortTitleText);
+ if (resultTo == null) {
+ startActivity(intent);
+ } else {
+ resultTo.startActivityForResult(intent, resultRequestCode);
+ }
+ }
+
/**
* Change the base title of the bread crumbs for the current preferences.
* This will normally be called for you. See
@@ -1259,7 +1308,12 @@ public abstract class PreferenceActivity extends ListActivity implements
public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
CharSequence titleText, Fragment resultTo, int resultRequestCode) {
if (mSinglePane) {
- startWithFragment(fragmentClass, args, resultTo, resultRequestCode, titleRes, 0);
+ // fix for title text for startPreferencePanel in a single pane mode
+ if (titleRes == 0 && titleText != null) {
+ startWithFragment(fragmentClass, args, resultTo, resultRequestCode, titleText, null);
+ } else {
+ startWithFragment(fragmentClass, args, resultTo, resultRequestCode, titleRes, 0);
+ }
} else {
Fragment f = Fragment.instantiate(this, fragmentClass, args);
if (resultTo != null) {
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index caf55d7..b763022 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -146,6 +146,11 @@ public class VolumePreference extends SeekBarDialogPreference implements
}
}
+ /** @hide */
+ protected boolean onVolumeChange(SeekBarVolumizer volumizer, int value) {
+ return true;
+ }
+
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
@@ -305,10 +310,14 @@ public class VolumePreference extends SeekBarDialogPreference implements
}
void postSetVolume(int progress) {
- // Do the volume changing separately to give responsive UI
- mLastProgress = progress;
- mHandler.removeCallbacks(this);
- mHandler.post(this);
+ if (onVolumeChange(this, progress)) {
+ // Do the volume changing separately to give responsive UI
+ mLastProgress = progress;
+ mHandler.removeCallbacks(this);
+ mHandler.post(this);
+ } else {
+ mSeekBar.setProgress(mLastProgress);
+ }
}
public void onStartTrackingTouch(SeekBar seekBar) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4dbc4b4..4b81ff2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1591,6 +1591,23 @@ public final class Settings {
@Deprecated
public static final String WIFI_STATIC_DNS2 = "wifi_static_dns2";
+ /**
+ * Allows automatic retrieval of mms contents
+ * <p>Type: INT</p>
+ * 0 -- false
+ * 1 -- true
+ * @hide
+ */
+ public static final String MMS_AUTO_RETRIEVAL = "mms_auto_retrieval";
+
+ /**
+ * Allows automatic retrieval of mms contents during roaming
+ * <p>Type: INT</p>
+ * 0 -- false
+ * 1 -- true
+ * @hide
+ */
+ public static final String MMS_AUTO_RETRIEVAL_ON_ROAMING = "mms_auto_on_roaming";
/**
* Determines whether remote devices may discover and/or connect to
@@ -1703,6 +1720,148 @@ public final class Settings {
public static final int SCREEN_BRIGHTNESS_MODE_AUTOMATIC = 1;
/**
+ * Indicates that custom light sensor settings has changed.
+ * The value is random and changes reloads light settings.
+ *
+ * @hide
+ */
+ public static final String LIGHTS_CHANGED = "lights_changed";
+
+ /**
+ * Whether custom light sensor levels & values are enabled. The value is
+ * boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_CUSTOM = "light_sensor_custom";
+
+ /**
+ * Screen dim value to use if LIGHT_SENSOR_CUSTOM is set. The value is int.
+ * Default is android.os.BRIGHTNESS_DIM.
+ *
+ * @hide
+ */
+ public static final String LIGHT_SCREEN_DIM = "light_screen_dim";
+
+ /**
+ * Custom light sensor levels. The value is a comma separated int array
+ * with length N.
+ * Example: "100,300,3000".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_LEVELS = "light_sensor_levels";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_LCD_VALUES = "light_sensor_lcd_values";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_BUTTON_VALUES = "light_sensor_button_values";
+
+ /**
+ * Custom light sensor lcd values. The value is a comma separated int array
+ * with length N+1.
+ * Example: "10,50,100,255".
+ *
+ * @hide
+ */
+ public static final String LIGHT_SENSOR_KEYBOARD_VALUES = "light_sensor_keyboard_values";
+
+ /**
+ * Whether light sensor is allowed to decrease when calculating automatic
+ * backlight. The value is boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_DECREASE = "light_decrease";
+
+ /**
+ * Light sensor hysteresis for decreasing backlight. The value is
+ * int (0-99) representing % (0-0.99 as float). Example:
+ *
+ * Levels Output
+ * 0 - 100 50
+ * 100 - 200 100
+ * 200 - Inf 255
+ *
+ * Current sensor value is 150 which gives light value 100. Hysteresis is 50.
+ * Current level lower bound is 100 and previous lower bound is 0.
+ * Sensor value must drop below 100-(100-0)*(50/100)=50 for output to become 50
+ * (corresponding to the 0 - 100 level).
+ * @hide
+ */
+ public static final String LIGHT_HYSTERESIS = "light_hysteresis";
+
+ /**
+ * Whether light sensor used when calculating automatic backlight should
+ * be filtered through an moving average filter.
+ * The value is boolean (1 or 0).
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER = "light_filter";
+
+ /**
+ * Window length of filter used when calculating automatic backlight.
+ * One minute means that the average sensor value last minute is used.
+ * The value is integer (milliseconds)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_WINDOW = "light_filter_window";
+
+ /**
+ * Reset threshold of filter used when calculating automatic backlight.
+ * Sudden large jumps in sensor value resets the filter. This is used
+ * to make the filter respond quickly to large enough changes in input
+ * while still filtering small changes. Example:
+ *
+ * Current filter value (average) is 100 and sensor value is changing to
+ * 10, 150, 100, 30, 50. The filter is continously taking the average of
+ * the samples. Now the user goes outside and the value jumps over 1000.
+ * The difference between current average and new sample is larger than
+ * the reset threshold and filter is reset. It begins calculating a new
+ * average on samples around 1000 (say, 800, 1200, 1000, 1100 etc.)
+ *
+ * The value is integer (lux)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_RESET = "light_filter_reset";
+
+ /**
+ * Sample interval of filter used when calculating automatic backlight.
+ * The value is integer (milliseconds)
+ *
+ * @hide
+ */
+ public static final String LIGHT_FILTER_INTERVAL = "light_filter_interval";
+
+ /**
+ * Whether to enable the electron beam animation when turning screen on
+ *
+ * @hide */
+ public static final String ELECTRON_BEAM_ANIMATION_ON = "electron_beam_animation_on";
+
+ /**
+ * Whether to enable the electron beam animation when turning screen off
+ *
+ * @hide */
+ public static final String ELECTRON_BEAM_ANIMATION_OFF = "electron_beam_animation_off";
+
+ /**
* Control whether the process CPU usage meter should be shown.
*
* @deprecated Use {@link Global#SHOW_PROCESSES} instead
@@ -1721,6 +1880,22 @@ public final class Settings {
public static final String ALWAYS_FINISH_ACTIVITIES = Global.ALWAYS_FINISH_ACTIVITIES;
/**
+ * Volume Overlay Mode, This is behaviour of the volume overlay panel
+ * Defaults to 0 - which is simple
+ * @hide
+ */
+ public static final String MODE_VOLUME_OVERLAY = "mode_volume_overlay";
+
+ /** @hide */
+ public static final int VOLUME_OVERLAY_SINGLE = 0;
+ /** @hide */
+ public static final int VOLUME_OVERLAY_EXPANDABLE = 1;
+ /** @hide */
+ public static final int VOLUME_OVERLAY_EXPANDED = 2;
+ /** @hide */
+ public static final int VOLUME_OVERLAY_NONE = 3;
+
+ /**
* Determines which streams are affected by ringer mode changes. The
* stream type's bit should be set to 1 if it should be muted when going
* into an inaudible ringer mode.
@@ -1797,6 +1972,12 @@ public final class Settings {
public static final String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
/**
+ * Whether to prevent loud volume levels when headset is first plugged in.
+ * @hide
+ */
+ public static final String SAFE_HEADSET_VOLUME = "safe_headset_volume";
+
+ /**
* Master volume (float in the range 0.0f to 1.0f).
* @hide
*/
@@ -1828,6 +2009,24 @@ public final class Settings {
"notifications_use_ring_volume";
/**
+ * Whether the phone ringtone should be played in an increasing manner
+ * @hide
+ */
+ public static final String INCREASING_RING = "increasing_ring";
+
+ /**
+ * Minimum volume index for increasing ring volume
+ * @hide
+ */
+ public static final String INCREASING_RING_MIN_VOLUME = "increasing_ring_min_vol";
+
+ /**
+ * Time (in ms) between ringtone volume increases
+ * @hide
+ */
+ public static final String INCREASING_RING_INTERVAL = "increasing_ring_interval";
+
+ /**
* Whether silent mode should allow vibration feedback. This is used
* internally in AudioService and the Sound settings activity to
* coordinate decoupling of vibrate and silent modes. This setting
@@ -2023,6 +2222,19 @@ public final class Settings {
public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
/**
+ * Control the type of rotation which can be performed using the accelerometer
+ * if ACCELEROMETER_ROTATION is enabled.
+ * Value is a bitwise combination of
+ * 1 = 0 degrees (portrait)
+ * 2 = 90 degrees (left)
+ * 4 = 180 degrees (inverted portrait)
+ * 8 = 270 degrees (right)
+ * Setting to 0 is effectively orientation lock
+ * @hide
+ */
+ public static final String ACCELEROMETER_ROTATION_ANGLES = "accelerometer_rotation_angles";
+
+ /**
* Default screen rotation when no other policy applies.
* When {@link #ACCELEROMETER_ROTATION} is zero and no on-screen Activity expresses a
* preference, this rotation value will be used. Must be one of the
@@ -2094,6 +2306,13 @@ public final class Settings {
public static final String TTY_MODE = "tty_mode";
/**
+ * Whether noise suppression is enabled. The value is
+ * boolean (1 or 0).
+ * @hide
+ */
+ public static final String NOISE_SUPPRESSION = "noise_suppression";
+
+ /**
* Whether the sounds effects (key clicks, lid open ...) are enabled. The value is
* boolean (1 or 0).
*/
@@ -2120,6 +2339,109 @@ public final class Settings {
public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
/**
+ * What color to use for the notification LED by default
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR = "notification_light_pulse_default_color";
+
+ /**
+ * How long to flash the notification LED by default
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON = "notification_light_pulse_default_led_on";
+
+ /**
+ * How long to wait between flashes for the notification LED by default
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF = "notification_light_pulse_default_led_off";
+
+ /**
+ * What color to use for the missed call notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CALL_COLOR = "notification_light_pulse_call_color";
+
+ /**
+ * How long to flash the missed call notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CALL_LED_ON = "notification_light_pulse_call_led_on";
+
+ /**
+ * How long to wait between flashes for the missed call notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CALL_LED_OFF = "notification_light_pulse_call_led_off";
+
+ /**
+ * What color to use for the voicemail notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_COLOR = "notification_light_pulse_vmail_color";
+
+ /**
+ * How long to flash the voicemail notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_LED_ON = "notification_light_pulse_vmail_led_on";
+
+ /**
+ * How long to wait between flashes for the voicemail notification LED
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_VMAIL_LED_OFF = "notification_light_pulse_vmail_led_off";
+
+ /**
+ * Whether to use the custom LED values for the notification pulse LED.
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE = "notification_light_pulse_custom_enable";
+
+ /**
+ * Which custom LED values to use for the notification pulse LED.
+ * @hide
+ */
+ public static final String NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES = "notification_light_pulse_custom_values";
+
+ /**
+ * Whether the battery light should be enabled (if hardware supports it)
+ * The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_ENABLED = "battery_light_enabled";
+
+ /**
+ * Whether the battery LED should repeatedly flash when the battery is low
+ * on charge. The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_PULSE = "battery_light_pulse";
+
+ /**
+ * What color to use for the battery LED while charging - low
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_LOW_COLOR = "battery_light_low_color";
+
+ /**
+ * What color to use for the battery LED while charging - medium
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_MEDIUM_COLOR = "battery_light_medium_color";
+
+ /**
+ * What color to use for the battery LED while charging - full
+ * @hide
+ */
+ public static final String BATTERY_LIGHT_FULL_COLOR = "battery_light_full_color";
+
+ /** Sprint MWI Quirk: Show message wait indicator notifications
+ * @hide
+ */
+ public static final String ENABLE_MWI_NOTIFICATION = "enable_mwi_notification";
+
+ /**
* Show pointer location on screen?
* 0 = no
* 1 = yes
@@ -2128,6 +2450,14 @@ public final class Settings {
public static final String POINTER_LOCATION = "pointer_location";
/**
+ * Show icon when stylus is used?
+ * 0 = no
+ * 1 = yes
+ * @hide
+ */
+ public static final String STYLUS_ICON_ENABLED = "stylus_icon_enabled";
+
+ /**
* Show touch positions on screen?
* 0 = no
* 1 = yes
@@ -2174,6 +2504,12 @@ public final class Settings {
public static final String LOCKSCREEN_DISABLED = "lockscreen.disabled";
/**
+ * Stores values for custom lockscreen targets
+ * @hide
+ */
+ public static final String LOCKSCREEN_TARGETS = "lockscreen_targets";
+
+ /**
* @deprecated Use {@link android.provider.Settings.Global#LOW_BATTERY_SOUND}
* instead
* @hide
@@ -2265,6 +2601,11 @@ public final class Settings {
public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME";
/**
+ * Torch state (flashlight)
+ * @hide
+ */
+ public static final String TORCH_STATE = "torch_state";
+ /**
* Pointer speed setting.
* This is an integer value in a range between -7 and +7, so there are 15 possible values.
* -7 = slowest
@@ -2275,6 +2616,511 @@ public final class Settings {
public static final String POINTER_SPEED = "pointer_speed";
/**
+ * Quick Settings Panel Tiles to Use
+ *
+ * @hide
+ */
+ public static final String QUICK_SETTINGS_TILES = "quick_settings_tiles";
+
+ /**
+ * Quick Settings Panel Dynamic Tiles
+ *
+ * @hide
+ */
+ public static final String QS_DYNAMIC_ALARM = "qs_dyanmic_alarm";
+
+ /**
+ * Quick Settings Panel Dynamic Tiles
+ *
+ * @hide
+ */
+ public static final String QS_DYNAMIC_BUGREPORT = "qs_dyanmic_bugreport";
+
+ /**
+ * Quick Settings Panel Dynamic Tiles
+ *
+ * @hide
+ */
+ public static final String QS_DYNAMIC_IME = "qs_dyanmic_ime";
+
+ /**
+ * Quick Settings Panel Dynamic Tiles
+ *
+ * @hide
+ */
+ public static final String QS_DYNAMIC_USBTETHER = "qs_dyanmic_usbtether";
+
+ /**
+ * Quick Settings Panel Dynamic Tiles
+ *
+ * @hide
+ */
+ public static final String QS_DYNAMIC_WIFI = "qs_dyanmic_wifi";
+
+ /**
+ * Quick Settings Quick Pulldown
+ *
+ * @hide
+ */
+ public static final String QS_QUICK_PULLDOWN = "qs_quick_pulldown";
+
+ /**
+ * Quick Settings Collapse Pane
+ *
+ * @hide
+ */
+ public static final String QS_COLLAPSE_PANEL = "qs_collapse_panel";
+
+ /**
+ * Use the Notification Power Widget? (Who wouldn't!)
+ *
+ * @hide
+ */
+ public static final String EXPANDED_VIEW_WIDGET = "expanded_view_widget";
+
+ /**
+ * Whether to hide the notification screen after clicking on a widget
+ * button
+ *
+ * @hide
+ */
+ public static final String EXPANDED_HIDE_ONCHANGE = "expanded_hide_onchange";
+
+ /**
+ * Hide scroll bar in power widget
+ *
+ * @hide
+ */
+ public static final String EXPANDED_HIDE_SCROLLBAR = "expanded_hide_scrollbar";
+
+ /**
+ * Haptic feedback in power widget
+ *
+ * @hide
+ */
+ public static final String EXPANDED_HAPTIC_FEEDBACK = "expanded_haptic_feedback";
+
+ /**
+ * Widget Buttons to Use
+ *
+ * @hide
+ */
+ public static final String WIDGET_BUTTONS = "expanded_widget_buttons";
+
+ /**
+ * Widget Buttons to Use - Tablet
+ *
+ * @hide
+ */
+ public static final String WIDGET_BUTTONS_TABLET = "expanded_widget_buttons_tablet";
+
+ /**
+ * Navigation controls to Use
+ *
+ * @hide
+ */
+ public static final String NAV_BUTTONS = "nav_buttons";
+
+ /**
+ * Notification Power Widget - Custom Brightness Mode
+ * @hide
+ */
+ public static final String EXPANDED_BRIGHTNESS_MODE = "expanded_brightness_mode";
+
+ /**
+ * Notification Power Widget - Custom Network Mode
+ * @hide
+ */
+ public static final String EXPANDED_NETWORK_MODE = "expanded_network_mode";
+
+ /**
+ * Notification Power Widget - Custom Screen Timeout
+ * @hide
+ */
+ public static final String EXPANDED_SCREENTIMEOUT_MODE = "expanded_screentimeout_mode";
+
+ /**
+ * Notification Power Widget - Custom Ring Mode
+ * @hide
+ */
+ public static final String EXPANDED_RING_MODE = "expanded_ring_mode";
+
+ /**
+ * Notification Power Widget - Custom Torch Mode
+ * @hide
+ */
+ public static final String EXPANDED_FLASH_MODE = "expanded_flash_mode";
+
+ /**
+ * AutoHide CombinedBar on tablets.
+ * @hide
+ */
+ public static final String COMBINED_BAR_AUTO_HIDE = "combined_bar_auto_hide";
+
+ /**
+ * Display style of AM/PM next to clock in status bar
+ * 0: Normal display (Eclair stock)
+ * 1: Small display (Froyo stock)
+ * 2: No display (Gingerbread/ICS stock)
+ * default: 2
+ * @hide
+ */
+ public static final String STATUS_BAR_AM_PM = "status_bar_am_pm";
+
+ /**
+ * Display style of the status bar battery information
+ * 0: Display the stock battery information
+ * 1: Display cm battery percentage implementation / dont show stock icon
+ * 2: Display cm circle battery implementation without percentage
+ * 3: Display cm circle battery implementation with percentage
+ * 4: Hide the battery information
+ * default: 0
+ * @hide
+ */
+ public static final String STATUS_BAR_BATTERY = "status_bar_battery";
+
+ /**
+ * Whether to show the clock in status bar
+ * of the stock battery icon
+ * 0: don't show the clock
+ * 1: show the clock
+ * default: 1
+ * @hide
+ */
+ public static final String STATUS_BAR_CLOCK = "status_bar_clock";
+
+ /**
+ * Whether to show the signal text or signal bars.
+ * default: 0
+ * 0: show signal bars
+ * 1: show signal text numbers
+ * 2: show signal text numbers w/small dBm appended
+ * @hide
+ */
+ public static final String STATUS_BAR_SIGNAL_TEXT = "status_bar_signal";
+
+ /**
+ * Whether to control brightness from status bar
+ *
+ * @hide
+ */
+ public static final String STATUS_BAR_BRIGHTNESS_CONTROL = "status_bar_brightness_control";
+
+ /**
+ * Whether to show the IME switcher in the status bar
+ * @hide
+ */
+ public static final String STATUS_BAR_IME_SWITCHER = "status_bar_ime_switcher";
+
+ /**
+ * Expanded desktop on/off state
+ * @hide
+ */
+ public static final String EXPANDED_DESKTOP_STATE = "expanded_desktop_state";
+
+ /**
+ * Expanded desktop style (with status bar or without status bar)
+ * @hide
+ */
+ public static final String EXPANDED_DESKTOP_STYLE = "expanded_desktop_style";
+
+ /**
+ * Whether to use a separate delay for "slide to unlock" and security
+ * lock
+ * @hide
+ */
+ public static final String SCREEN_LOCK_SLIDE_DELAY_TOGGLE = "screen_lock_slide_delay_toggle";
+
+ /**
+ * How many ms to delay before enabling the "slide to unlock" screen
+ * lock when the screen goes off due to timeout
+ * @hide
+ */
+ public static final String SCREEN_LOCK_SLIDE_TIMEOUT_DELAY = "screen_lock_slide_timeout_delay";
+
+ /**
+ * How many ms to delay before enabling the "slide to unlock" screen
+ * lock when the screen is turned off by the user
+ * @hide
+ */
+ public static final String SCREEN_LOCK_SLIDE_SCREENOFF_DELAY = "screen_lock_slide_screenoff_delay";
+
+ /**
+ * Whether to use the custom quick unlock screen control
+ * @hide
+ */
+ public static final String LOCKSCREEN_QUICK_UNLOCK_CONTROL = "lockscreen_quick_unlock_control";
+
+ /**
+ * Boolean value whether to link ringtone and notification volumes
+ *
+ * @hide
+ */
+ public static final String VOLUME_LINK_NOTIFICATION = "volume_link_notification";
+
+ /**
+ * Whether to unlock the menu key. The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String MENU_UNLOCK_SCREEN = "menu_unlock_screen";
+
+ /**
+ * Whether to wake the screen with the volume keys, the value is boolean.
+ * @hide
+ */
+ public static final String VOLUME_WAKE_SCREEN = "volume_wake_screen";
+
+ /**
+ * Whether or not volume button music controls should be enabled to seek media tracks
+ * @hide
+ */
+ public static final String VOLBTN_MUSIC_CONTROLS = "volbtn_music_controls";
+
+ /**
+ * Whether or not to launch default music player when headset is connected
+ * @hide
+ */
+ public static final String HEADSET_CONNECT_PLAYER = "headset_connect_player";
+
+ /**
+ * Whether national data roaming should be used.
+ * @hide
+ */
+ public static final String MVNO_ROAMING = "mvno_roaming";
+
+ /**
+ * Whether to enable quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_ENABLED = "quiet_hours_enabled";
+
+ /**
+ * Sets when quiet hours starts. This is stored in minutes from the start of the day.
+ * @hide
+ */
+ public static final String QUIET_HOURS_START = "quiet_hours_start";
+
+ /**
+ * Sets when quiet hours end. This is stored in minutes from the start of the day.
+ * @hide
+ */
+ public static final String QUIET_HOURS_END = "quiet_hours_end";
+
+ /**
+ * Whether to remove the sound from outgoing notifications during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_MUTE = "quiet_hours_mute";
+
+ /**
+ * Whether to disable haptic feedback during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_HAPTIC = "quiet_hours_haptic";
+
+ /**
+ * Whether to remove the vibration from outgoing notifications during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_STILL = "quiet_hours_still";
+
+ /**
+ * Whether to attempt to dim the LED color during quiet hours.
+ * @hide
+ */
+ public static final String QUIET_HOURS_DIM = "quiet_hours_dim";
+
+ /**
+ * Sets the lockscreen background style
+ * @hide
+ */
+ public static final String LOCKSCREEN_BACKGROUND = "lockscreen_background";
+
+ /**
+ * Action for long-pressing back button on lock screen
+ * @hide
+ */
+ public static final String LOCKSCREEN_LONG_BACK_ACTION = "lockscreen_long_back_action";
+
+ /**
+ * Action for long-pressing home button on lock screen
+ * @hide
+ */
+ public static final String LOCKSCREEN_LONG_HOME_ACTION = "lockscreen_long_home_action";
+
+ /**
+ * Action for long-pressing menu button on lock screen
+ * @hide
+ */
+ public static final String LOCKSCREEN_LONG_MENU_ACTION = "lockscreen_long_menu_action";
+
+ /**
+ * Always show the battery status on the lockscreen
+ * @hide
+ */
+ public static final String LOCKSCREEN_ALWAYS_SHOW_BATTERY = "lockscreen_always_show_battery";
+
+ /**
+ * Show the pending notification counts as overlays on the status bar
+ * @hide
+ */
+ public static final String STATUS_BAR_NOTIF_COUNT = "status_bar_notif_count";
+
+ /**
+ * Show the pending notification counts as overlays on the status bar
+ * @hide
+ */
+ public static final String SYSTEM_PROFILES_ENABLED = "system_profiles_enabled";
+
+ /**
+ * Whether the power menu reboot menu is enabled
+ * @hide
+ */
+ public static final String POWER_MENU_REBOOT_ENABLED = "power_menu_reboot_enabled";
+
+ /**
+ * Whether power menu screenshot is enabled
+ * @hide
+ */
+ public static final String POWER_MENU_SCREENSHOT_ENABLED = "power_menu_screenshot_enabled";
+
+ /**
+ * Whether power menu expanded desktop is enabled
+ * @hide
+ */
+ public static final String POWER_MENU_EXPANDED_DESKTOP_ENABLED = "power_menu_expanded_desktop_enabled";
+
+ /**
+ * Whether power menu profiles switcher is enabled
+ * @hide
+ */
+ public static final String POWER_MENU_PROFILES_ENABLED = "power_menu_profiles_enabled";
+
+ /**
+ * Whether power menu airplane toggle is enabled
+ * @hide
+ */
+ public static final String POWER_MENU_AIRPLANE_ENABLED = "power_menu_airplane_enabled";
+
+ /**
+ * Whether power menu user switcher is enabled
+ * @hide
+ */
+ public static final String POWER_MENU_USER_ENABLED = "power_menu_user_enabled";
+
+ /**
+ * Whether power menu silent mode is enabled
+ * @hide
+ */
+ public static final String POWER_MENU_SOUND_ENABLED = "power_menu_silent_enabled";
+
+ /**
+ * Whether to unlock the screen with the home key. The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String HOME_UNLOCK_SCREEN = "home_unlock_screen";
+
+ /**
+ * Whether the lockscreen vibrate should be enabled.
+ * @hide
+ */
+ public static final String LOCKSCREEN_VIBRATE_ENABLED = "lockscreen.vibrate_enabled";
+
+ /**
+ * Show the pending notification counts as overlays on the status bar
+ * Whether to enable custom rebindings of the actions performed on
+ * certain key press events.
+ * @hide
+ */
+ public static final String HARDWARE_KEY_REBINDING = "hardware_key_rebinding";
+
+ /**
+ * Action to perform when the home key is long-pressed. (Default is 2)
+ * 0 - Nothing
+ * 1 - Menu
+ * 2 - App-switch
+ * 3 - Search
+ * 4 - Voice search
+ * 5 - In-app search
+ * @hide
+ */
+ public static final String KEY_HOME_LONG_PRESS_ACTION = "key_home_long_press_action";
+
+ /**
+ * Action to perform when the menu key is pressed. (Default is 1)
+ * (See KEY_HOME_LONG_PRESS_ACTION for valid values)
+ * @hide
+ */
+ public static final String KEY_MENU_ACTION = "key_menu_action";
+
+ /**
+ * Action to perform when the menu key is long-pressed.
+ * (Default is 0 on devices with a search key, 3 on devices without)
+ * (See KEY_HOME_LONG_PRESS_ACTION for valid values)
+ * @hide
+ */
+ public static final String KEY_MENU_LONG_PRESS_ACTION = "key_menu_long_press_action";
+
+ /**
+ * Action to perform when the assistant (search) key is pressed. (Default is 3)
+ * (See KEY_HOME_LONG_PRESS_ACTION for valid values)
+ * @hide
+ */
+ public static final String KEY_ASSIST_ACTION = "key_assist_action";
+
+ /**
+ * Weather to minimize lockscreen challenge on screen turned on
+ * @hide
+ */
+ public static final String LOCKSCREEN_MAXIMIZE_WIDGETS = "lockscreen_maximize_widgets";
+
+ /**
+ * Action to perform when the assistant (search) key is long-pressed. (Default is 4)
+ * (See KEY_HOME_LONG_PRESS_ACTION for valid values)
+ * @hide
+ */
+ public static final String KEY_ASSIST_LONG_PRESS_ACTION = "key_assist_long_press_action";
+
+ /**
+ * Action to perform when the app switch key is pressed. (Default is 2)
+ * (See KEY_HOME_LONG_PRESS_ACTION for valid values)
+ * @hide
+ */
+ public static final String KEY_APP_SWITCH_ACTION = "key_app_switch_action";
+
+ /**
+ * Action to perform when the app switch key is long-pressed. (Default is 0)
+ * (See KEY_HOME_LONG_PRESS_ACTION for valid values)
+ * @hide
+ */
+ public static final String KEY_APP_SWITCH_LONG_PRESS_ACTION = "key_app_switch_long_press_action";
+
+ /**
+ * Control the display of the action overflow button within app UI.
+ * 0 = use system default
+ * 1 = force on
+ * @hide
+ */
+ public static final String UI_FORCE_OVERFLOW_BUTTON = "ui_force_overflow_button";
+
+ /**
+ * Volume keys control cursor in text fields (default is 0)
+ * 0 - Disabled
+ * 1 - Volume up/down moves cursor left/right
+ * 2 - Volume up/down moves cursor right/left
+ * @hide
+ */
+ public static final String VOLUME_KEY_CURSOR_CONTROL = "volume_key_cursor_control";
+
+ /**
+ * toggle to "fix" the following: (found in NotificationManagerService)
+ * new in 4.2: if there was supposed to be a sound and we're in vibrate mode,
+ * we always vibrate, even if no vibration was specified
+ * @hide
+ */
+ public static final String NOTIFICATION_CONVERT_SOUND_TO_VIBRATION = "convert_sound_to_vibration";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
@@ -2292,6 +3138,8 @@ public final class Settings {
WIFI_STATIC_NETMASK,
WIFI_STATIC_DNS1,
WIFI_STATIC_DNS2,
+ MMS_AUTO_RETRIEVAL,
+ MMS_AUTO_RETRIEVAL_ON_ROAMING,
BLUETOOTH_DISCOVERABILITY,
BLUETOOTH_DISCOVERABILITY_TIMEOUT,
DIM_SCREEN,
@@ -2325,10 +3173,13 @@ public final class Settings {
AUTO_TIME_ZONE, // moved to global
TIME_12_24,
DATE_FORMAT,
+ ACCELEROMETER_ROTATION,
+ USER_ROTATION,
DTMF_TONE_WHEN_DIALING,
DTMF_TONE_TYPE_WHEN_DIALING,
HEARING_AID,
TTY_MODE,
+ NOISE_SUPPRESSION,
SOUND_EFFECTS_ENABLED,
HAPTIC_FEEDBACK_ENABLED,
POWER_SOUNDS_ENABLED, // moved to global
@@ -2336,10 +3187,27 @@ public final class Settings {
LOCKSCREEN_SOUNDS_ENABLED,
SHOW_WEB_SUGGESTIONS,
NOTIFICATION_LIGHT_PULSE,
+ NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR,
+ NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON,
+ NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF,
SIP_CALL_OPTIONS,
SIP_RECEIVE_CALLS,
POINTER_SPEED,
- VIBRATE_WHEN_RINGING
+ QUIET_HOURS_ENABLED,
+ QUIET_HOURS_START,
+ QUIET_HOURS_END,
+ QUIET_HOURS_MUTE,
+ QUIET_HOURS_STILL,
+ QUIET_HOURS_DIM,
+ SYSTEM_PROFILES_ENABLED,
+ POWER_MENU_SCREENSHOT_ENABLED,
+ POWER_MENU_REBOOT_ENABLED,
+ POWER_MENU_PROFILES_ENABLED,
+ POWER_MENU_AIRPLANE_ENABLED,
+ POWER_MENU_SOUND_ENABLED,
+ POWER_MENU_USER_ENABLED,
+ LOCKSCREEN_VIBRATE_ENABLED,
+ LOCKSCREEN_ALWAYS_SHOW_BATTERY,
};
// Settings moved to Settings.Secure
@@ -3092,6 +3960,24 @@ public final class Settings {
public static final String ADB_ENABLED = Global.ADB_ENABLED;
/**
+ * The TCP/IP port to run ADB on, or -1 for USB
+ * @hide
+ */
+ public static final String ADB_PORT = "adb_port";
+
+ /**
+ * Whether to display the ADB notification.
+ * @hide
+ */
+ public static final String ADB_NOTIFY = "adb_notify";
+
+ /**
+ * The hostname for this device
+ * @hide
+ */
+ public static final String DEVICE_HOSTNAME = "device_hostname";
+
+ /**
* Setting to allow mock locations and location provider status to be injected into the
* LocationManager service for testing purposes during application development. These
* locations and status values override actual location and status information generated
@@ -3265,6 +4151,21 @@ public final class Settings {
"lock_screen_owner_info_enabled";
/**
+ * Whether the unsecure widget screen will be shown before a secure
+ * lock screen
+ * @hide
+ */
+ public static final String LOCK_BEFORE_UNLOCK =
+ "lock_before_unlock";
+
+ /**
+ * Determines the width and height of the LockPatternView widget
+ * @hide
+ */
+ public static final String LOCK_PATTERN_SIZE =
+ "lock_pattern_size";
+
+ /**
* The Logging ID (a unique 64-bit value) as a hex string.
* Used as a pseudonymous identifier for logging.
* @deprecated This identifier is poorly initialized and has
@@ -3683,6 +4584,12 @@ public final class Settings {
Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS;
/**
+ * Whether the Wimax should be on. Only the WiMAX service should touch this.
+ * @hide
+ */
+ public static final String WIMAX_ON = "wimax_on";
+
+ /**
* Whether background data usage is allowed.
*
* @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH},
@@ -3985,6 +4892,36 @@ public final class Settings {
INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF;
/**
+ * What happens when the user presses the Home button when the
+ * phone is ringing.<br/>
+ * <b>Values:</b><br/>
+ * 1 - Nothing happens. (Default behavior)<br/>
+ * 2 - The Home button answer the current call.<br/>
+ *
+ * @hide
+ */
+ public static final String RING_HOME_BUTTON_BEHAVIOR = "ring_home_button_behavior";
+
+ /**
+ * RING_HOME_BUTTON_BEHAVIOR value for "do nothing".
+ * @hide
+ */
+ public static final int RING_HOME_BUTTON_BEHAVIOR_DO_NOTHING = 0x1;
+
+ /**
+ * RING_HOME_BUTTON_BEHAVIOR value for "answer".
+ * @hide
+ */
+ public static final int RING_HOME_BUTTON_BEHAVIOR_ANSWER = 0x2;
+
+ /**
+ * RING_HOME_BUTTON_BEHAVIOR default value.
+ * @hide
+ */
+ public static final int RING_HOME_BUTTON_BEHAVIOR_DEFAULT =
+ RING_HOME_BUTTON_BEHAVIOR_DO_NOTHING;
+
+ /**
* The current night mode that has been selected by the user. Owned
* and controlled by UiModeManagerService. Constants are as per
* UiModeManager.
@@ -4028,6 +4965,12 @@ public final class Settings {
public static final String SCREENSAVER_DEFAULT_COMPONENT = "screensaver_default_component";
/**
+ * Whether to allow killing of the foreground app by long-pressing the Back button
+ * @hide
+ */
+ public static final String KILL_APP_LONGPRESS_BACK = "kill_app_longpress_back";
+
+ /**
* This are the settings to be backed up.
*
* NOTE: Settings are backed up and restored in the order they appear
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 499075e..73295a2 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -223,6 +223,8 @@ public class ViewConfiguration {
private boolean sHasPermanentMenuKey;
private boolean sHasPermanentMenuKeySet;
+ private Context mContext;
+
static final SparseArray<ViewConfiguration> sConfigurations =
new SparseArray<ViewConfiguration>(2);
@@ -270,6 +272,8 @@ public class ViewConfiguration {
sizeAndDensity = density;
}
+ mContext = context;
+
mEdgeSlop = (int) (sizeAndDensity * EDGE_SLOP + 0.5f);
mFadingEdgeLength = (int) (sizeAndDensity * FADING_EDGE_LENGTH + 0.5f);
mMinimumFlingVelocity = (int) (density * MINIMUM_FLING_VELOCITY + 0.5f);
@@ -678,7 +682,18 @@ public class ViewConfiguration {
* @return true if a permanent menu key is present, false otherwise.
*/
public boolean hasPermanentMenuKey() {
- return sHasPermanentMenuKey;
+ // The action overflow button within app UI can
+ // be controlled with a system setting
+ int showOverflowButton = Settings.System.getInt(
+ mContext.getContentResolver(),
+ Settings.System.UI_FORCE_OVERFLOW_BUTTON, 0);
+ if (showOverflowButton == 1) {
+ // Force overflow button on by reporting that
+ // the device has no permanent menu key
+ return false;
+ } else {
+ return sHasPermanentMenuKey;
+ }
}
/**
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 001d020..d0811a0 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -27,6 +27,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.AudioService;
import android.media.AudioSystem;
@@ -35,7 +36,9 @@ import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
+import android.os.RemoteException;
import android.os.Vibrator;
+import android.provider.Settings;
import android.util.Log;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;
@@ -99,12 +102,19 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
private static final int STREAM_MASTER = -100;
// Pseudo stream type for remote volume is defined in AudioService.STREAM_REMOTE_MUSIC
+ public static final int VOLUME_OVERLAY_SINGLE = 0;
+ public static final int VOLUME_OVERLAY_EXPANDABLE = 1;
+ public static final int VOLUME_OVERLAY_EXPANDED = 2;
+ public static final int VOLUME_OVERLAY_NONE = 3;
+
protected Context mContext;
private AudioManager mAudioManager;
protected AudioService mAudioService;
private boolean mRingIsSilent;
private boolean mShowCombinedVolumes;
private boolean mVoiceCapable;
+ private boolean mVolumeLinkNotification;
+ private int mCurrentOverlayStyle = -1;
// True if we want to play tones on the system stream when the master stream is specified.
private final boolean mPlayMasterStreamTones;
@@ -138,7 +148,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
R.string.volume_icon_description_ringer,
R.drawable.ic_audio_ring_notif,
R.drawable.ic_audio_ring_notif_mute,
- false),
+ true),
VoiceStream(AudioManager.STREAM_VOICE_CALL,
R.string.volume_icon_description_incall,
R.drawable.ic_audio_phone,
@@ -148,7 +158,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
R.string.volume_alarm,
R.drawable.ic_audio_alarm,
R.drawable.ic_audio_alarm_mute,
- false),
+ true),
MediaStream(AudioManager.STREAM_MUSIC,
R.string.volume_icon_description_media,
R.drawable.ic_audio_vol,
@@ -213,6 +223,17 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
private ToneGenerator mToneGenerators[];
private Vibrator mVibrator;
+ private ContentObserver mSettingsObserver = new ContentObserver(this) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mVolumeLinkNotification = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.VOLUME_LINK_NOTIFICATION, 1) == 1;
+ final int overlayStyle = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.MODE_VOLUME_OVERLAY, VOLUME_OVERLAY_EXPANDABLE);
+ changeOverlayStyle(overlayStyle);
+ }
+ };
+
private static AlertDialog sConfirmSafeVolumeDialog;
private static Object sConfirmSafeVolumeLock = new Object();
@@ -262,7 +283,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View view = mView = inflater.inflate(R.layout.volume_adjust, null);
+ mView = inflater.inflate(R.layout.volume_adjust, null);
mView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
resetTimeout();
@@ -309,24 +330,32 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
-
mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
- mShowCombinedVolumes = !mVoiceCapable && !useMasterVolume;
- // If we don't want to show multiple volumes, hide the settings button and divider
- if (!mShowCombinedVolumes) {
- mMoreButton.setVisibility(View.GONE);
- mDivider.setVisibility(View.GONE);
- } else {
- mMoreButton.setOnClickListener(this);
- }
+ // Get the user's preferences
+ mVolumeLinkNotification = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.VOLUME_LINK_NOTIFICATION, 1) == 1;
+ final int chosenStyle = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.MODE_VOLUME_OVERLAY, VOLUME_OVERLAY_EXPANDABLE);
+ changeOverlayStyle(chosenStyle);
+
+ context.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.VOLUME_LINK_NOTIFICATION), false,
+ mSettingsObserver);
+ context.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.MODE_VOLUME_OVERLAY), false,
+ mSettingsObserver);
+
+ // This is new with 4.2 it seems
boolean masterVolumeOnly = context.getResources().getBoolean(
com.android.internal.R.bool.config_useMasterVolume);
boolean masterVolumeKeySounds = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useVolumeKeySounds);
mPlayMasterStreamTones = masterVolumeOnly && masterVolumeKeySounds;
+ // End this is new
+ mMoreButton.setOnClickListener(this);
listenToRingerMode();
}
@@ -346,13 +375,37 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
}, filter);
}
- private boolean isMuted(int streamType) {
- if (streamType == STREAM_MASTER) {
- return mAudioManager.isMasterMute();
- } else if (streamType == AudioService.STREAM_REMOTE_MUSIC) {
- return (mAudioService.getRemoteStreamVolume() <= 0);
- } else {
- return mAudioManager.isStreamMute(streamType);
+ private void changeOverlayStyle(int newStyle) {
+ Log.i("VolumePanel", "changeOverlayStyle : " + newStyle);
+ // Don't change to the same style
+ if (newStyle == mCurrentOverlayStyle) return;
+ switch (newStyle) {
+ case VOLUME_OVERLAY_SINGLE :
+ mMoreButton.setVisibility(View.GONE);
+ mDivider.setVisibility(View.GONE);
+ mShowCombinedVolumes = false;
+ mCurrentOverlayStyle = VOLUME_OVERLAY_SINGLE;
+ break;
+ case VOLUME_OVERLAY_EXPANDABLE :
+ mMoreButton.setVisibility(View.VISIBLE);
+ mDivider.setVisibility(View.VISIBLE);
+ mShowCombinedVolumes = true;
+ mCurrentOverlayStyle = VOLUME_OVERLAY_EXPANDABLE;
+ break;
+ case VOLUME_OVERLAY_EXPANDED :
+ mMoreButton.setVisibility(View.GONE);
+ mDivider.setVisibility(View.GONE);
+ mShowCombinedVolumes = true;
+ if (mCurrentOverlayStyle == VOLUME_OVERLAY_NONE) {
+ addOtherVolumes();
+ expand();
+ }
+ mCurrentOverlayStyle = VOLUME_OVERLAY_EXPANDED;
+ break;
+ case VOLUME_OVERLAY_NONE :
+ mShowCombinedVolumes = false;
+ mCurrentOverlayStyle = VOLUME_OVERLAY_NONE;
+ break;
}
}
@@ -386,6 +439,16 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
}
}
+ private boolean isMuted(int streamType) {
+ if (streamType == STREAM_MASTER) {
+ return mAudioManager.isMasterMute();
+ } else if (streamType == AudioService.STREAM_REMOTE_MUSIC) {
+ return (mAudioService.getRemoteStreamVolume() <= 0);
+ } else {
+ return mAudioManager.isStreamMute(streamType);
+ }
+ }
+
private void createSliders() {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -394,9 +457,6 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
for (int i = 0; i < STREAMS.length; i++) {
StreamResources streamRes = STREAMS[i];
int streamType = streamRes.streamType;
- if (mVoiceCapable && streamRes == StreamResources.NotificationStream) {
- streamRes = StreamResources.RingerStream;
- }
StreamControl sc = new StreamControl();
sc.streamType = streamType;
sc.group = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null);
@@ -407,6 +467,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
sc.iconRes = streamRes.iconRes;
sc.iconMuteRes = streamRes.iconMuteRes;
sc.icon.setImageResource(sc.iconRes);
+ sc.icon.setOnClickListener(this);
sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar);
int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0;
@@ -443,6 +504,15 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
if (!STREAMS[i].show || streamType == mActiveStreamType) {
continue;
}
+ // Skip ring volume for non-phone devices
+ if (!mVoiceCapable && streamType == AudioManager.STREAM_RING) {
+ continue;
+ }
+ // Skip notification volume if linked with ring volume
+ if (mVoiceCapable && mVolumeLinkNotification &&
+ streamType == AudioManager.STREAM_NOTIFICATION) {
+ continue;
+ }
StreamControl sc = mStreamControls.get(streamType);
mSliderGroup.addView(sc.group);
updateSlider(sc);
@@ -476,10 +546,22 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
private void expand() {
final int count = mSliderGroup.getChildCount();
for (int i = 0; i < count; i++) {
- mSliderGroup.getChildAt(i).setVisibility(View.VISIBLE);
+ if (mSliderGroup.getChildAt(i).getVisibility() != View.VISIBLE) {
+ mSliderGroup.getChildAt(i).setVisibility(View.VISIBLE);
+ }
+ }
+ mMoreButton.setVisibility(View.GONE);
+ mDivider.setVisibility(View.GONE);
+ }
+
+ private void hideSlider(int mActiveStreamType) {
+ final int count = mSliderGroup.getChildCount();
+ for (int i = 0; i < count; i++) {
+ StreamControl sc = (StreamControl) mSliderGroup.getChildAt(i).getTag();
+ if (mActiveStreamType == sc.streamType) {
+ mSliderGroup.getChildAt(i).setVisibility(View.GONE);
+ }
}
- mMoreButton.setVisibility(View.INVISIBLE);
- mDivider.setVisibility(View.INVISIBLE);
}
private void collapse() {
@@ -579,7 +661,10 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
synchronized (this) {
- if (mActiveStreamType != streamType) {
+ if (streamType != mActiveStreamType) {
+ if (mCurrentOverlayStyle == VOLUME_OVERLAY_EXPANDABLE) {
+ hideSlider(mActiveStreamType);
+ }
reorderSliders(streamType);
}
onShowVolumeChanged(streamType, flags);
@@ -712,15 +797,20 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
}
}
- if (!mDialog.isShowing()) {
+ // Only Show if style needs it
+ if (!mDialog.isShowing() && mCurrentOverlayStyle != VOLUME_OVERLAY_NONE) {
int stream = (streamType == AudioService.STREAM_REMOTE_MUSIC) ? -1 : streamType;
// when the stream is for remote playback, use -1 to reset the stream type evaluation
mAudioManager.forceVolumeControlStream(stream);
mDialog.setContentView(mView);
// Showing dialog - use collapsed state
- if (mShowCombinedVolumes) {
+ if (mShowCombinedVolumes && mCurrentOverlayStyle != VOLUME_OVERLAY_EXPANDED) {
collapse();
}
+ // If just changed the style and we need to expand
+ if (mCurrentOverlayStyle == VOLUME_OVERLAY_EXPANDED) {
+ expand();
+ }
mDialog.show();
}
@@ -996,8 +1086,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
sendMessage(obtainMessage(MSG_TIMEOUT));
}
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
final Object tag = seekBar.getTag();
if (fromUser && tag instanceof StreamControl) {
StreamControl sc = (StreamControl) tag;
@@ -1028,6 +1117,12 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
public void onClick(View v) {
if (v == mMoreButton) {
expand();
+ } else if (v instanceof ImageView) {
+ Intent volumeSettings = new Intent(android.provider.Settings.ACTION_SOUND_SETTINGS);
+ volumeSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ forceTimeout();
+ mContext.startActivity(volumeSettings);
+ return;
}
resetTimeout();
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 06974d3..fcf0924 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -740,6 +740,10 @@ public abstract class Window {
* @see #clearFlags
*/
public void setFlags(int flags, int mask) {
+ if ((flags & mask & WindowManager.LayoutParams.PREVENT_POWER_KEY) != 0){
+ mContext.enforceCallingOrSelfPermission("android.permission.PREVENT_POWER_KEY",
+ "No permission to prevent power key");
+ }
final WindowManager.LayoutParams attrs = getAttributes();
attrs.flags = (attrs.flags&~mask) | (flags&mask);
if ((mask&WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0) {
@@ -779,6 +783,10 @@ public abstract class Window {
* current values.
*/
public void setAttributes(WindowManager.LayoutParams a) {
+ if ((a.flags & WindowManager.LayoutParams.PREVENT_POWER_KEY) != 0) {
+ mContext.enforceCallingOrSelfPermission("android.permission.PREVENT_POWER_KEY",
+ "No permission to prevent power key");
+ }
mWindowAttributes.copyFrom(a);
if (mCallback != null) {
mCallback.onWindowAttributesChanged(mWindowAttributes);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 6a67d8b..f6e838d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -804,6 +804,10 @@ public interface WindowManager extends ViewManager {
* {@hide} */
public static final int FLAG_SYSTEM_ERROR = 0x40000000;
+ /** Window flag: Overrides default power key behavior
+ * {@hide} */
+ public static final int PREVENT_POWER_KEY = 0x80000000;
+
/**
* Various behavioral options/flags. Default is none.
*
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 26739b3..fd5449c 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -399,6 +399,7 @@ public interface WindowManagerPolicy {
public void shutdown(boolean confirm);
public void rebootSafeMode(boolean confirm);
+ public void reboot();
}
/**
diff --git a/core/java/android/webkit/WebCoreThreadWatchdog.java b/core/java/android/webkit/WebCoreThreadWatchdog.java
index a22e6e8..c27bb5f 100644
--- a/core/java/android/webkit/WebCoreThreadWatchdog.java
+++ b/core/java/android/webkit/WebCoreThreadWatchdog.java
@@ -270,7 +270,7 @@ class WebCoreThreadWatchdog implements Runnable {
SUBSEQUENT_TIMEOUT_PERIOD);
}
})
- .setIcon(android.R.drawable.ic_dialog_alert)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
.show();
}
}
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 1bbe7bb..cda53e1 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -22,6 +22,7 @@ import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemProperties;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.EventLog;
@@ -125,6 +126,7 @@ public class WebSettingsClassic extends WebSettings {
private boolean mEnableSmoothTransition = false;
private boolean mForceUserScalable = false;
private boolean mPasswordEchoEnabled = true;
+ private boolean mWebGLEnabled = true;
// AutoFill Profile data
public static class AutoFillProfile {
@@ -432,6 +434,9 @@ public class WebSettingsClassic extends WebSettings {
buffer.append(" Build/");
buffer.append(id);
}
+ final String cmversion = SystemProperties.get("ro.cm.version");
+ if (cmversion != null && cmversion.length() > 0)
+ buffer.append("; CyanogenMod-" + cmversion.replaceAll("([0-9\\.]+?)-.*","$1"));
String mobile = context.getResources().getText(
com.android.internal.R.string.web_user_agent_target_content).toString();
final String base = context.getResources().getText(
@@ -1253,7 +1258,7 @@ public class WebSettingsClassic extends WebSettings {
@Override
public synchronized void setAppCachePath(String path) {
// We test for a valid path and for repeated setting on the native
- // side, but we can avoid syncing in some simple cases.
+ // side, but we can avoid syncing in some simple cases.
if (mAppCachePath == null && path != null && !path.isEmpty()) {
mAppCachePath = path;
postSync();
@@ -1630,6 +1635,25 @@ public class WebSettingsClassic extends WebSettings {
}
/**
+ * @hide
+ */
+ public synchronized boolean isWebGLAvailable() {
+ return nativeIsWebGLAvailable();
+ }
+
+ /**
+ * Sets whether WebGL is enabled.
+ * @param flag Set to true to enable WebGL.
+ * @hide
+ */
+ public synchronized void setWebGLEnabled(boolean flag) {
+ if (mWebGLEnabled != flag) {
+ mWebGLEnabled = flag;
+ postSync();
+ }
+ }
+
+ /**
* Sets whether viewport metatag can disable zooming.
* @param flag Whether or not to forceably enable user scalable.
*/
@@ -1741,4 +1765,5 @@ public class WebSettingsClassic extends WebSettings {
// Synchronize the native and java settings.
private native void nativeSync(int nativeFrame);
+ private native boolean nativeIsWebGLAvailable();
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index ae56e6b..108c4f7 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -3813,6 +3813,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
invalidate(); // So we draw again
if (!mScroller.isFinished()) {
+ mSendScroll.setPostpone(true);
int rangeX = computeMaxScrollX();
int rangeY = computeMaxScrollY();
int overflingDistance = mOverflingDistance;
@@ -3840,6 +3841,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (mOverScrollGlow != null) {
mOverScrollGlow.absorbGlow(x, y, oldX, oldY, rangeX, rangeY);
}
+ mSendScroll.setPostpone(false);
} else {
if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
// Update the layer position instead of WebView.
@@ -3859,7 +3861,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
}
if (oldX != getScrollX() || oldY != getScrollY()) {
- sendOurVisibleRect();
+ mSendScroll.send(true);
}
}
} else {
@@ -4716,7 +4718,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (oldScrollX != getScrollX() || oldScrollY != getScrollY()) {
mWebViewPrivate.onScrollChanged(getScrollX(), getScrollY(), oldScrollX, oldScrollY);
} else {
- sendOurVisibleRect();
+ mSendScroll.send(true);
}
}
}
@@ -5674,10 +5676,31 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
contentScrollTo(scrollX, scrollY, false);
}
+ private final class SendScrollToWebCore implements Runnable {
+ public void run() {
+ if (!mInOverScrollMode) {
+ sendOurVisibleRect();
+ }
+ }
+ private boolean mPostpone = false;
+ public void setPostpone(boolean set) { mPostpone = set; }
+ public void send(boolean force) {
+ mPrivateHandler.removeCallbacks(this);
+ if (!mPostpone || force) {
+ run();
+ } else {
+ mPrivateHandler.postAtFrontOfQueue(this);
+ }
+ }
+ }
+
+ SendScrollToWebCore mSendScroll = new SendScrollToWebCore();
+
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
+ mSendScroll.send(false);
+
if (!mInOverScrollMode) {
- sendOurVisibleRect();
// update WebKit if visible title bar height changed. The logic is same
// as getVisibleTitleHeightImpl.
int titleHeight = getTitleHeight();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 3fb3ec6..5f48904 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -758,9 +758,9 @@ public final class WebViewCore {
break;
case REDUCE_PRIORITY:
- // 3 is an adjustable number.
+ // 10 is an adjustable number.
Process.setThreadPriority(
- Process.THREAD_PRIORITY_DEFAULT + 3 *
+ Process.THREAD_PRIORITY_DEFAULT + 10 *
Process.THREAD_PRIORITY_LESS_FAVORABLE);
break;
@@ -1278,6 +1278,7 @@ public final class WebViewCore {
mBrowserFrame = null;
mSettings.onDestroyed();
mNativeClass = 0;
+ WebCoreThreadWatchdog.unregisterWebView(mWebViewClassic);
mWebViewClassic = null;
}
break;
@@ -1982,7 +1983,6 @@ public final class WebViewCore {
mEventHub.sendMessageAtFrontOfQueue(
Message.obtain(null, EventHub.DESTROY));
mEventHub.blockMessages();
- WebCoreThreadWatchdog.unregisterWebView(mWebViewClassic);
}
}
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index f218199..47f3a30 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -18,6 +18,7 @@ package android.widget;
import android.content.Context;
import android.hardware.SensorManager;
+import android.os.PowerManager;
import android.util.FloatMath;
import android.util.Log;
import android.view.ViewConfiguration;
@@ -43,6 +44,8 @@ public class OverScroller {
private static final int SCROLL_MODE = 0;
private static final int FLING_MODE = 1;
+ private final PowerManager mPm;
+
/**
* Creates an OverScroller with a viscous fluid scroll interpolator and flywheel.
* @param context
@@ -72,8 +75,11 @@ public class OverScroller {
public OverScroller(Context context, Interpolator interpolator, boolean flywheel) {
mInterpolator = interpolator;
mFlywheel = flywheel;
+
mScrollerX = new SplineOverScroller(context);
mScrollerY = new SplineOverScroller(context);
+
+ mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
}
/**
@@ -373,6 +379,7 @@ public class OverScroller {
*/
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
mMode = SCROLL_MODE;
+ mPm.cpuBoost(1500000);
mScrollerX.startScroll(startX, dx, duration);
mScrollerY.startScroll(startY, dy, duration);
}
@@ -443,6 +450,7 @@ public class OverScroller {
}
}
+ mPm.cpuBoost(1500000);
mMode = FLING_MODE;
mScrollerX.fling(startX, velocityX, minX, maxX, overX);
mScrollerY.fling(startY, velocityY, minY, maxY, overY);
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 3bfd39d..a97a4d7 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -19,6 +19,7 @@ package android.widget;
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Build;
+import android.os.PowerManager;
import android.util.FloatMath;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
@@ -111,6 +112,8 @@ public class Scroller {
// A context-specific coefficient adjusted to physical values.
private float mPhysicalCoeff;
+ private final PowerManager mPm;
+
static {
float x_min = 0.0f;
float y_min = 0.0f;
@@ -184,6 +187,7 @@ public class Scroller {
mFlywheel = flywheel;
mPhysicalCoeff = computeDeceleration(0.84f); // look and feel tuning
+ mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
}
/**
@@ -407,6 +411,7 @@ public class Scroller {
mDeltaX = dx;
mDeltaY = dy;
mDurationReciprocal = 1.0f / (float) mDuration;
+ mPm.cpuBoost(1500000);
}
/**
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 6bced1c..579593e 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -330,28 +330,30 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
return;
}
- final View selectedChild = getChildTabViewAt(mSelectedTab);
-
- final Drawable leftStrip = mLeftStrip;
- final Drawable rightStrip = mRightStrip;
-
- leftStrip.setState(selectedChild.getDrawableState());
- rightStrip.setState(selectedChild.getDrawableState());
-
- if (mStripMoved) {
- final Rect bounds = mBounds;
- bounds.left = selectedChild.getLeft();
- bounds.right = selectedChild.getRight();
- final int myHeight = getHeight();
- leftStrip.setBounds(Math.min(0, bounds.left - leftStrip.getIntrinsicWidth()),
- myHeight - leftStrip.getIntrinsicHeight(), bounds.left, myHeight);
- rightStrip.setBounds(bounds.right, myHeight - rightStrip.getIntrinsicHeight(),
- Math.max(getWidth(), bounds.right + rightStrip.getIntrinsicWidth()), myHeight);
- mStripMoved = false;
+ if(mSelectedTab != -1) {
+ final View selectedChild = getChildTabViewAt(mSelectedTab);
+
+ final Drawable leftStrip = mLeftStrip;
+ final Drawable rightStrip = mRightStrip;
+
+ leftStrip.setState(selectedChild.getDrawableState());
+ rightStrip.setState(selectedChild.getDrawableState());
+
+ if (mStripMoved) {
+ final Rect bounds = mBounds;
+ bounds.left = selectedChild.getLeft();
+ bounds.right = selectedChild.getRight();
+ final int myHeight = getHeight();
+ leftStrip.setBounds(Math.min(0, bounds.left - leftStrip.getIntrinsicWidth()),
+ myHeight - leftStrip.getIntrinsicHeight(), bounds.left, myHeight);
+ rightStrip.setBounds(bounds.right, myHeight - rightStrip.getIntrinsicHeight(),
+ Math.max(getWidth(), bounds.right + rightStrip.getIntrinsicWidth()), myHeight);
+ mStripMoved = false;
+ }
+
+ leftStrip.draw(canvas);
+ rightStrip.draw(canvas);
}
-
- leftStrip.draw(canvas);
- rightStrip.draw(canvas);
}
/**
diff --git a/core/java/com/android/internal/app/ActivityTrigger.java b/core/java/com/android/internal/app/ActivityTrigger.java
new file mode 100644
index 0000000..71aeff3
--- /dev/null
+++ b/core/java/com/android/internal/app/ActivityTrigger.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Code Aurora nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.util.Log;
+
+public class ActivityTrigger
+{
+ private static final String TAG = "ActivityTrigger";
+
+ /** &hide */
+ public ActivityTrigger() {
+ //Log.d(TAG, "ActivityTrigger initialized");
+ }
+
+ /** &hide */
+ protected void finalize() {
+ native_at_deinit();
+ }
+
+ /** &hide */
+ public void activityStartTrigger(Intent intent) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+
+ if (cn != null)
+ activity = cn.flattenToString();
+ native_at_startActivity(activity);
+ }
+
+ /** &hide */
+ public void activityResumeTrigger(Intent intent) {
+ ComponentName cn = intent.getComponent();
+ String activity = null;
+
+ if (cn != null)
+ activity = cn.flattenToString();
+ native_at_resumeActivity(activity);
+ }
+
+ private native void native_at_startActivity(String activity);
+ private native void native_at_resumeActivity(String activity);
+ private native void native_at_deinit();
+}
diff --git a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
index 5ab9217..b1f9d46 100644
--- a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
+++ b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
@@ -26,6 +26,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
/**
* This activity is shown to the user to confirm formatting of external media.
@@ -34,6 +36,10 @@ import android.util.Log;
public class ExternalMediaFormatActivity extends AlertActivity implements DialogInterface.OnClickListener {
private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE;
+ public static final String FORMAT_PATH = "format_path";
+
+ private StorageManager mStorageManager;
+ private StorageVolume mStorageVolume = null;
/** Used to detect when the media state changes, in case we need to call finish() */
private BroadcastReceiver mStorageReceiver = new BroadcastReceiver() {
@@ -50,17 +56,38 @@ public class ExternalMediaFormatActivity extends AlertActivity implements Dialog
}
}
};
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ // This is necessary because this class's caller,
+ // packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java,
+ // supplies the path to be erased/formatted as a String, instead of a
+ // StorageVolume. This for-loop gets the correct StorageVolume from the
+ // given path.
+ mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
+ String path = getIntent().getStringExtra(FORMAT_PATH);
+ StorageVolume[] volumes = mStorageManager.getVolumeList();
+
+ for (StorageVolume sv : volumes) {
+ if (path.equals(sv.getPath())) {
+ mStorageVolume = sv;
+ break;
+ }
+ }
+
Log.d("ExternalMediaFormatActivity", "onCreate!");
+ Log.d("ExternalMediaFormatActivity", "The storage volume to be formatted is : "
+ + mStorageVolume.getPath());
+
// Set up the "dialog"
final AlertController.AlertParams p = mAlertParams;
p.mIconId = com.android.internal.R.drawable.stat_sys_warning;
p.mTitle = getString(com.android.internal.R.string.extmedia_format_title);
- p.mMessage = getString(com.android.internal.R.string.extmedia_format_message);
+ p.mMessage = String.format(
+ getString(com.android.internal.R.string.extmedia_format_message),
+ mStorageVolume.getPath());
p.mPositiveButtonText = getString(com.android.internal.R.string.extmedia_format_button_format);
p.mPositiveButtonListener = this;
p.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
@@ -83,7 +110,7 @@ public class ExternalMediaFormatActivity extends AlertActivity implements Dialog
@Override
protected void onPause() {
super.onPause();
-
+
unregisterReceiver(mStorageReceiver);
}
@@ -95,10 +122,11 @@ public class ExternalMediaFormatActivity extends AlertActivity implements Dialog
if (which == POSITIVE_BUTTON) {
Intent intent = new Intent(ExternalStorageFormatter.FORMAT_ONLY);
intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
+ intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, mStorageVolume);
startService(intent);
}
// No matter what, finish the activity
finish();
}
-}
+} \ No newline at end of file
diff --git a/core/java/com/android/internal/app/IAssetRedirectionManager.aidl b/core/java/com/android/internal/app/IAssetRedirectionManager.aidl
new file mode 100644
index 0000000..8b47f0b
--- /dev/null
+++ b/core/java/com/android/internal/app/IAssetRedirectionManager.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011, T-Mobile USA, Inc.
+ *
+ * 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.internal.app;
+
+import android.content.res.PackageRedirectionMap;
+
+/**
+ * Interface used to interact with the AssetRedirectionManagerService.
+ */
+interface IAssetRedirectionManager {
+ /**
+ * Access the package redirection map for the supplied package name given a
+ * particular theme.
+ */
+ PackageRedirectionMap getPackageRedirectionMap(in String themePackageName,
+ String themeId, in String targetPackageName);
+
+ /**
+ * Clear all redirection maps for the given theme.
+ */
+ void clearRedirectionMapsByTheme(in String themePackageName,
+ in String themeId);
+
+ /**
+ * Clear all redirection maps for the given target package.
+ */
+ void clearPackageRedirectionMap(in String targetPackageName);
+}
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 03d3b22..83eb352 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -33,8 +33,10 @@ interface IMediaContainerService {
boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked);
ObbInfo getObbInfo(in String filename);
long calculateDirectorySize(in String directory);
+ byte[] listDirectory(in String directory);
/** Return file system stats: [0] is total bytes, [1] is available bytes */
long[] getFileSystemStats(in String path);
void clearDirectory(in String directory);
+ void deleteFile(in String file);
long calculateInstalledSize(in String packagePath, boolean isForwardLocked);
}
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 3a2b647..bac8e21 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -84,7 +84,7 @@ public class PlatLogoActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+ final boolean isCid = getIntent().hasExtra("is_cid");
mToast = Toast.makeText(this, "", Toast.LENGTH_LONG);
mToast.setView(makeView());
@@ -92,7 +92,8 @@ public class PlatLogoActivity extends Activity {
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mContent = new ImageView(this);
- mContent.setImageResource(com.android.internal.R.drawable.platlogo_alt);
+ mContent.setImageResource(isCid ? com.android.internal.R.drawable.cidlogo
+ : com.android.internal.R.drawable.platlogo_alt);
mContent.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
final int p = (int)(32 * metrics.density);
@@ -102,7 +103,8 @@ public class PlatLogoActivity extends Activity {
@Override
public void onClick(View v) {
mToast.show();
- mContent.setImageResource(com.android.internal.R.drawable.platlogo);
+ mContent.setImageResource(isCid ? com.android.internal.R.drawable.cidlogo_alt
+ : com.android.internal.R.drawable.platlogo);
}
});
@@ -114,6 +116,7 @@ public class PlatLogoActivity extends Activity {
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .putExtra("is_cid", isCid)
.addCategory("com.android.internal.category.PLATLOGO"));
//.setClassName("com.android.systemui","com.android.systemui.BeanBag"));
} catch (ActivityNotFoundException ex) {
diff --git a/core/java/com/android/internal/app/ThemeUtils.java b/core/java/com/android/internal/app/ThemeUtils.java
new file mode 100644
index 0000000..4265fd5
--- /dev/null
+++ b/core/java/com/android/internal/app/ThemeUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod 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.internal.app;
+
+import android.content.Context;
+import android.content.BroadcastReceiver;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+
+public class ThemeUtils {
+ private static final String TAG = "ThemeUtils";
+ private static final String DATA_TYPE_TMOBILE_STYLE = "vnd.tmobile.cursor.item/style";
+ private static final String DATA_TYPE_TMOBILE_THEME = "vnd.tmobile.cursor.item/theme";
+ private static final String ACTION_TMOBILE_THEME_CHANGED = "com.tmobile.intent.action.THEME_CHANGED";
+
+ public static Context createUiContext(final Context context) {
+ try {
+ return context.createPackageContext("com.android.systemui", Context.CONTEXT_RESTRICTED);
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+
+ return null;
+ }
+
+ public static void registerThemeChangeReceiver(final Context context, final BroadcastReceiver receiver) {
+ IntentFilter filter = new IntentFilter(ACTION_TMOBILE_THEME_CHANGED);
+ try {
+ filter.addDataType(DATA_TYPE_TMOBILE_THEME);
+ filter.addDataType(DATA_TYPE_TMOBILE_STYLE);
+ } catch (IntentFilter.MalformedMimeTypeException e) {
+ Log.e(TAG, "Could not add MIME types to filter", e);
+ }
+
+ context.registerReceiver(receiver, filter);
+ }
+}
+
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 94e7a06..201e1de 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -2015,6 +2015,9 @@ public final class BatteryStatsImpl extends BatteryStats {
case TelephonyManager.NETWORK_TYPE_EHRPD:
bin = DATA_CONNECTION_EHRPD;
break;
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ bin = DATA_CONNECTION_HSPAP;
+ break;
default:
bin = DATA_CONNECTION_OTHER;
break;
diff --git a/core/java/com/android/internal/os/DeviceDockBatteryHandler.java b/core/java/com/android/internal/os/DeviceDockBatteryHandler.java
new file mode 100644
index 0000000..ef5a8b2
--- /dev/null
+++ b/core/java/com/android/internal/os/DeviceDockBatteryHandler.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.internal.os;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+public interface DeviceDockBatteryHandler {
+
+ /**
+ * Invoked when the system request an update of the dock battery status. Device should
+ * access specific sysfs and read status, present and level of the device dock battery.
+ */
+ public void update();
+
+ /**
+ * Invoked after {@link #update()} for processing the values prior to notify them.
+ */
+ public void process();
+
+ /**
+ * Method that returns the data to notify to {@link Intent#ACTION_BATTERY_CHANGED} action.
+ */
+ public Bundle getNotifyData();
+
+ /**
+ * Method that returns if this handler has new battery data to notify
+ *
+ * @return If this handler has new battery data to notify.
+ */
+ public boolean hasNewData();
+
+ /**
+ * Method that returns if the dock battery is plugged (is powering device main battery)
+ *
+ * @return If the dock battery is plugged
+ */
+ public boolean isPlugged();
+}
diff --git a/core/java/com/android/internal/os/DeviceKeyHandler.java b/core/java/com/android/internal/os/DeviceKeyHandler.java
new file mode 100644
index 0000000..e7d103d
--- /dev/null
+++ b/core/java/com/android/internal/os/DeviceKeyHandler.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod 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.internal.os;
+
+import android.view.KeyEvent;
+
+public interface DeviceKeyHandler {
+
+ /**
+ * Invoked when an unknown key was detected by the system, letting the device handle
+ * this special keys prior to pass the key to the active app.
+ *
+ * @param event The key event to be handled
+ * @return If the event is consume
+ */
+ public boolean handleKeyEvent(KeyEvent event);
+}
diff --git a/core/java/com/android/internal/os/IDeviceHandler.java b/core/java/com/android/internal/os/IDeviceHandler.java
new file mode 100644
index 0000000..f6e196f
--- /dev/null
+++ b/core/java/com/android/internal/os/IDeviceHandler.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.internal.os;
+
+/**
+ * @hide
+ */
+public interface IDeviceHandler {
+ public DeviceKeyHandler getDeviceKeyHandler();
+ public DeviceDockBatteryHandler getDeviceDockBatteryHandler();
+}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9e43749..13a8972 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -99,7 +99,7 @@ public class ZygoteInit {
private static final String PRELOADED_CLASSES = "preloaded-classes";
/** Controls whether we should preload resources during zygote init. */
- private static final boolean PRELOAD_RESOURCES = true;
+ private static final boolean PRELOAD_RESOURCES = false;
/**
* Invokes a static "main(argv[]) method on class "className".
@@ -361,6 +361,8 @@ public class ZygoteInit {
ar.recycle();
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
+ } else {
+ Log.i(TAG, "Preload resources disabled, skipped.");
}
mResources.finishPreloading();
} catch (RuntimeException e) {
@@ -483,7 +485,7 @@ public class ZygoteInit {
String args[] = {
"--setuid=1000",
"--setgid=1000",
- "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
+ "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,3001,3002,3003,3004,3006,3007,3009",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
diff --git a/core/java/com/android/internal/policy/IPolicy.java b/core/java/com/android/internal/policy/IPolicy.java
index d08b3b4..ad679d2 100644
--- a/core/java/com/android/internal/policy/IPolicy.java
+++ b/core/java/com/android/internal/policy/IPolicy.java
@@ -22,6 +22,8 @@ import android.view.LayoutInflater;
import android.view.Window;
import android.view.WindowManagerPolicy;
+import com.android.internal.os.IDeviceHandler;
+
/**
* {@hide}
*/
@@ -33,7 +35,7 @@ public interface IPolicy {
public LayoutInflater makeNewLayoutInflater(Context context);
- public WindowManagerPolicy makeNewWindowManager();
+ public WindowManagerPolicy makeNewWindowManager(IDeviceHandler device);
public FallbackEventHandler makeNewFallbackEventHandler(Context context);
}
diff --git a/core/java/com/android/internal/policy/PolicyManager.java b/core/java/com/android/internal/policy/PolicyManager.java
index 5274e54..8b09564 100644
--- a/core/java/com/android/internal/policy/PolicyManager.java
+++ b/core/java/com/android/internal/policy/PolicyManager.java
@@ -22,6 +22,7 @@ import android.view.LayoutInflater;
import android.view.Window;
import android.view.WindowManagerPolicy;
+import com.android.internal.os.IDeviceHandler;
import com.android.internal.policy.IPolicy;
/**
@@ -63,8 +64,8 @@ public final class PolicyManager {
return sPolicy.makeNewLayoutInflater(context);
}
- public static WindowManagerPolicy makeNewWindowManager() {
- return sPolicy.makeNewWindowManager();
+ public static WindowManagerPolicy makeNewWindowManager(IDeviceHandler device) {
+ return sPolicy.makeNewWindowManager(device);
}
public static FallbackEventHandler makeNewFallbackEventHandler(Context context) {
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 95130c8..a86c323 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -58,7 +58,9 @@ public final class RotationPolicy {
return isRotationLockToggleSupported(context) &&
Settings.System.getIntForUser(context.getContentResolver(),
Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0,
- UserHandle.USER_CURRENT) == 0;
+ UserHandle.USER_CURRENT) == 0 &&
+ !context.getResources().getBoolean(com.android
+ .internal.R.bool.config_hasRotationLockSwitch);
}
/**
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index 238a9c0..98f635c 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -240,7 +240,7 @@ public class ActionMenuItemView extends TextView
Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT);
if (midy < displayFrame.height()) {
// Show along the top; follow action buttons
- cheatSheet.setGravity(Gravity.TOP | Gravity.END,
+ cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT,
screenWidth - screenPos[0] - width / 2, height);
} else {
// Show along the bottom center
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 4bb6d06..0267db3 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -34,6 +34,8 @@ import android.view.ViewGroup;
import android.widget.ImageButton;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
/**
* MenuPresenter for building action menus as seen in the action bar and action modes.
@@ -351,7 +353,27 @@ public class ActionMenuPresenter extends BaseMenuPresenter
}
public boolean flagActionItems() {
- final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
+ // Items must be sorted always in base to his showAsAction type
+ // always -> ifRoom -> Others
+ // Create an internal sorted array based in this priority (items must keep
+ // his original order)
+ final ArrayList<MenuItemImpl> visibleItems =
+ new ArrayList<MenuItemImpl>(mMenu.getVisibleItems());
+ Collections.sort(visibleItems, new Comparator<MenuItemImpl>() {
+ @Override
+ public int compare(MenuItemImpl lhs, MenuItemImpl rhs) {
+ boolean lhsRequires = lhs.requiresActionButton();
+ boolean lhsRequest = lhs.requestsActionButton();
+ boolean rhsRequires = rhs.requiresActionButton();
+ boolean rhsRequest = rhs.requestsActionButton();
+ if (lhsRequires && rhsRequires) return 0;
+ if (lhsRequires) return -1;
+ if (rhsRequires) return 1;
+ if (lhsRequest && rhsRequest) return 0;
+ if (lhsRequest) return -1;
+ return 1;
+ }
+ });
final int itemsSize = visibleItems.size();
int maxActions = mMaxItems;
int widthLimit = mActionItemWidthLimit;
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index c72c770..59a21fc 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -24,6 +24,7 @@ interface ILockSettings {
boolean getBoolean(in String key, in boolean defaultValue, in int userId);
long getLong(in String key, in long defaultValue, in int userId);
String getString(in String key, in String defaultValue, in int userId);
+ byte getLockPatternSize(int userId);
void setLockPattern(in byte[] hash, int userId);
boolean checkPattern(in byte[] hash, int userId);
void setLockPassword(in byte[] hash, int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 907b52a..a381ae9 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2012 The CyanogenMod Project (Calendar)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +24,8 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -30,10 +33,13 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.storage.IMountService;
+import android.provider.CalendarContract;
import android.provider.Settings;
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.text.format.Time;
import android.util.Log;
import android.view.IWindowManager;
import android.view.View;
@@ -46,7 +52,10 @@ import com.google.android.collect.Lists;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.util.Date;
import java.util.List;
+import java.util.TimeZone;
/**
* Utilities for the lock pattern and its settings.
@@ -91,6 +100,11 @@ public class LockPatternUtils {
public static final int MIN_LOCK_PATTERN_SIZE = 4;
/**
+ * The default size of the pattern lockscreen. Ex: 3x3
+ */
+ public static final byte PATTERN_SIZE_DEFAULT = 3;
+
+ /**
* The minimum number of dots the user must include in a wrong pattern
* attempt for it to be counted against the counts that affect
* {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET}
@@ -493,7 +507,7 @@ public class LockPatternUtils {
*/
public void saveLockPattern(List<LockPatternView.Cell> pattern, boolean isFallback) {
// Compute the hash
- final byte[] hash = LockPatternUtils.patternToHash(pattern);
+ final byte[] hash = patternToHash(pattern);
try {
getLockSettings().setLockPattern(hash, getCurrentOrCallingUserId());
DevicePolicyManager dpm = getDevicePolicyManager();
@@ -737,13 +751,16 @@ public class LockPatternUtils {
* @param string The pattern serialized with {@link #patternToString}
* @return The pattern.
*/
- public static List<LockPatternView.Cell> stringToPattern(String string) {
+ public List<LockPatternView.Cell> stringToPattern(String string) {
List<LockPatternView.Cell> result = Lists.newArrayList();
+ final byte size = getLockPatternSize();
+ LockPatternView.Cell.updateSize(size);
+
final byte[] bytes = string.getBytes();
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
- result.add(LockPatternView.Cell.of(b / 3, b % 3));
+ result.add(LockPatternView.Cell.of(b / size, b % size, size));
}
return result;
}
@@ -753,7 +770,7 @@ public class LockPatternUtils {
* @param pattern The pattern.
* @return The pattern in string form.
*/
- public static String patternToString(List<LockPatternView.Cell> pattern) {
+ public String patternToString(List<LockPatternView.Cell> pattern) {
if (pattern == null) {
return "";
}
@@ -762,7 +779,7 @@ public class LockPatternUtils {
byte[] res = new byte[patternSize];
for (int i = 0; i < patternSize; i++) {
LockPatternView.Cell cell = pattern.get(i);
- res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
+ res[i] = (byte) (cell.getRow() * getLockPatternSize() + cell.getColumn());
}
return new String(res);
}
@@ -774,7 +791,7 @@ public class LockPatternUtils {
* @param pattern the gesture pattern.
* @return the hash of the pattern in a byte array.
*/
- private static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
+ private byte[] patternToHash(List<LockPatternView.Cell> pattern) {
if (pattern == null) {
return null;
}
@@ -783,7 +800,7 @@ public class LockPatternUtils {
byte[] res = new byte[patternSize];
for (int i = 0; i < patternSize; i++) {
LockPatternView.Cell cell = pattern.get(i);
- res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
+ res[i] = (byte) (cell.getRow() * getLockPatternSize() + cell.getColumn());
}
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
@@ -952,6 +969,24 @@ public class LockPatternUtils {
}
/**
+ * @return the pattern lockscreen size
+ */
+ public byte getLockPatternSize() {
+ try {
+ return getLockSettings().getLockPatternSize(getCurrentOrCallingUserId());
+ } catch (RemoteException re) {
+ return PATTERN_SIZE_DEFAULT;
+ }
+ }
+
+ /**
+ * Set the pattern lockscreen size
+ */
+ public void setLockPatternSize(long size) {
+ setLong(Settings.Secure.LOCK_PATTERN_SIZE, size);
+ }
+
+ /**
* Set and store the lockout deadline, meaning the user can't attempt his/her unlock
* pattern until the deadline has passed.
* @return the chosen deadline.
@@ -1333,4 +1368,13 @@ public class LockPatternUtils {
return false;
}
+ /**
+ * @hide
+ * Set the lock-before-unlock option (show widgets before the secure
+ * unlock screen). See config_enableLockBeforeUnlockScreen
+ */
+ public void setLockBeforeUnlock(boolean enabled) {
+ setBoolean(Settings.Secure.LOCK_BEFORE_UNLOCK, enabled);
+ }
+
}
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 7a76ab0..703f544 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -38,13 +38,14 @@ import android.view.View;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.R;
+import com.android.internal.widget.LockPatternUtils;
import java.util.ArrayList;
import java.util.List;
/**
* Displays and detects the user's unlock attempt, which is a drag of a finger
- * across 9 regions of the screen.
+ * across regions of the screen.
*
* Is also capable of displaying a static pattern in "in progress", "wrong" or
* "correct" states.
@@ -72,8 +73,10 @@ public class LockPatternView extends View {
*/
private static final int MILLIS_PER_CIRCLE_ANIMATING = 700;
+ private byte mPatternSize = LockPatternUtils.PATTERN_SIZE_DEFAULT;
+
private OnPatternListener mOnPatternListener;
- private ArrayList<Cell> mPattern = new ArrayList<Cell>(9);
+ private ArrayList<Cell> mPattern = new ArrayList<Cell>(mPatternSize * mPatternSize);
/**
* Lookup table for the circles of the pattern we are currently drawing.
@@ -81,7 +84,7 @@ public class LockPatternView extends View {
* in which case we use this to hold the cells we are drawing for the in
* progress animation.
*/
- private boolean[][] mPatternDrawLookup = new boolean[3][3];
+ private boolean[][] mPatternDrawLookup = new boolean[mPatternSize][mPatternSize];
/**
* the in progress point:
@@ -125,30 +128,27 @@ public class LockPatternView extends View {
private final Matrix mArrowMatrix = new Matrix();
private final Matrix mCircleMatrix = new Matrix();
+ private LockPatternUtils mLockPatternUtils;
/**
- * Represents a cell in the 3 X 3 matrix of the unlock pattern view.
+ * Represents a cell in the matrix of the unlock pattern view.
*/
public static class Cell {
int row;
int column;
- // keep # objects limited to 9
- static Cell[][] sCells = new Cell[3][3];
+ // keep # objects limited
+ static Cell[][] sCells;
static {
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- sCells[i][j] = new Cell(i, j);
- }
- }
+ updateSize(LockPatternUtils.PATTERN_SIZE_DEFAULT);
}
/**
* @param row The row of the cell.
* @param column The column of the cell.
*/
- private Cell(int row, int column) {
- checkRange(row, column);
+ private Cell(int row, int column, byte size) {
+ checkRange(row, column, size);
this.row = row;
this.column = column;
}
@@ -165,17 +165,26 @@ public class LockPatternView extends View {
* @param row The row of the cell.
* @param column The column of the cell.
*/
- public static synchronized Cell of(int row, int column) {
- checkRange(row, column);
+ public static synchronized Cell of(int row, int column, byte size) {
+ checkRange(row, column, size);
return sCells[row][column];
}
- private static void checkRange(int row, int column) {
- if (row < 0 || row > 2) {
- throw new IllegalArgumentException("row must be in range 0-2");
+ public static void updateSize(byte size) {
+ sCells = new Cell[size][size];
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size; j++) {
+ sCells[i][j] = new Cell(i, j, size);
+ }
+ }
+ }
+
+ private static void checkRange(int row, int column, byte size) {
+ if (row < 0 || row > size - 1) {
+ throw new IllegalArgumentException("row must be in range 0-" + (size - 1));
}
- if (column < 0 || column > 2) {
- throw new IllegalArgumentException("column must be in range 0-2");
+ if (column < 0 || column > size - 1) {
+ throw new IllegalArgumentException("column must be in range 0-" + (size - 1));
}
}
@@ -304,6 +313,13 @@ public class LockPatternView extends View {
}
/**
+ * @return the current pattern lockscreen size.
+ */
+ public int getLockPatternSize() {
+ return mPatternSize;
+ }
+
+ /**
* Set whether the view is in stealth mode. If true, there will be no
* visible feedback as the user enters the pattern.
*
@@ -324,6 +340,26 @@ public class LockPatternView extends View {
}
/**
+ * Set the pattern size of the lockscreen
+ *
+ * @param size The pattern size.
+ */
+ public void setLockPatternSize(byte size) {
+ mPatternSize = size;
+ Cell.updateSize(size);
+ mPattern = new ArrayList<Cell>(size * size);
+ mPatternDrawLookup = new boolean[size][size];
+ }
+
+ /**
+ * Set the LockPatternUtil instance used to encode a pattern to a string
+ * @param utils The instance.
+ */
+ public void setLockPatternUtils(LockPatternUtils utils) {
+ mLockPatternUtils = utils;
+ }
+
+ /**
* Set the call back for pattern detection.
* @param onPatternListener The call back.
*/
@@ -420,8 +456,8 @@ public class LockPatternView extends View {
* Clear the pattern lookup table.
*/
private void clearPatternDrawLookup() {
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < mPatternSize; i++) {
+ for (int j = 0; j < mPatternSize; j++) {
mPatternDrawLookup[i][j] = false;
}
}
@@ -445,10 +481,10 @@ public class LockPatternView extends View {
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
final int width = w - mPaddingLeft - mPaddingRight;
- mSquareWidth = width / 3.0f;
+ mSquareWidth = width / (float) mPatternSize;
final int height = h - mPaddingTop - mPaddingBottom;
- mSquareHeight = height / 3.0f;
+ mSquareHeight = height / (float) mPatternSize;
}
private int resolveMeasured(int measureSpec, int desired)
@@ -471,14 +507,14 @@ public class LockPatternView extends View {
@Override
protected int getSuggestedMinimumWidth() {
- // View should be large enough to contain 3 side-by-side target bitmaps
- return 3 * mBitmapWidth;
+ // View should be large enough to contain side-by-side target bitmaps
+ return mPatternSize * mBitmapWidth;
}
@Override
protected int getSuggestedMinimumHeight() {
- // View should be large enough to contain 3 side-by-side target bitmaps
- return 3 * mBitmapWidth;
+ // View should be large enough to contain side-by-side target bitmaps
+ return mPatternSize * mBitmapWidth;
}
@Override
@@ -515,7 +551,6 @@ public class LockPatternView extends View {
if (cell != null) {
// check for gaps in existing pattern
- Cell fillInGapCell = null;
final ArrayList<Cell> pattern = mPattern;
if (!pattern.isEmpty()) {
final Cell lastCell = pattern.get(pattern.size() - 1);
@@ -525,21 +560,19 @@ public class LockPatternView extends View {
int fillInRow = lastCell.row;
int fillInColumn = lastCell.column;
- if (Math.abs(dRow) == 2 && Math.abs(dColumn) != 1) {
- fillInRow = lastCell.row + ((dRow > 0) ? 1 : -1);
- }
-
- if (Math.abs(dColumn) == 2 && Math.abs(dRow) != 1) {
- fillInColumn = lastCell.column + ((dColumn > 0) ? 1 : -1);
+ if (dRow == 0 || dColumn == 0 || Math.abs(dRow) == Math.abs(dColumn)) {
+ while (true) {
+ fillInRow += Integer.signum(dRow);
+ fillInColumn += Integer.signum(dColumn);
+ if (fillInRow == cell.row && fillInColumn == cell.column) break;
+ Cell fillInGapCell = Cell.of(fillInRow, fillInColumn, mPatternSize);
+ if (!mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) {
+ addCellToPattern(fillInGapCell);
+ }
+ }
}
-
- fillInGapCell = Cell.of(fillInRow, fillInColumn);
}
- if (fillInGapCell != null &&
- !mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) {
- addCellToPattern(fillInGapCell);
- }
addCellToPattern(cell);
if (mEnableHapticFeedback) {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
@@ -572,7 +605,7 @@ public class LockPatternView extends View {
if (mPatternDrawLookup[rowHit][columnHit]) {
return null;
}
- return Cell.of(rowHit, columnHit);
+ return Cell.of(rowHit, columnHit, mPatternSize);
}
/**
@@ -586,7 +619,7 @@ public class LockPatternView extends View {
float hitSize = squareHeight * mHitFactor;
float offset = mPaddingTop + (squareHeight - hitSize) / 2f;
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < mPatternSize; i++) {
final float hitTop = offset + squareHeight * i;
if (y >= hitTop && y <= hitTop + hitSize) {
@@ -606,7 +639,7 @@ public class LockPatternView extends View {
float hitSize = squareWidth * mHitFactor;
float offset = mPaddingLeft + (squareWidth - hitSize) / 2f;
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < mPatternSize; i++) {
final float hitLeft = offset + squareWidth * i;
if (x >= hitLeft && x <= hitLeft + hitSize) {
@@ -918,10 +951,10 @@ public class LockPatternView extends View {
final int paddingTop = mPaddingTop;
final int paddingLeft = mPaddingLeft;
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < mPatternSize; i++) {
float topY = paddingTop + i * squareHeight;
//float centerY = mPaddingTop + i * mSquareHeight + (mSquareHeight / 2);
- for (int j = 0; j < 3; j++) {
+ for (int j = 0; j < mPatternSize; j++) {
float leftX = paddingLeft + j * squareWidth;
drawCircle(canvas, (int) leftX, (int) topY, drawLookup[i][j]);
}
@@ -1082,8 +1115,8 @@ public class LockPatternView extends View {
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
return new SavedState(superState,
- LockPatternUtils.patternToString(mPattern),
- mPatternDisplayMode.ordinal(),
+ mLockPatternUtils.patternToString(mPattern),
+ mPatternDisplayMode.ordinal(), mPatternSize,
mInputEnabled, mInStealthMode, mEnableHapticFeedback);
}
@@ -1093,8 +1126,9 @@ public class LockPatternView extends View {
super.onRestoreInstanceState(ss.getSuperState());
setPattern(
DisplayMode.Correct,
- LockPatternUtils.stringToPattern(ss.getSerializedPattern()));
+ mLockPatternUtils.stringToPattern(ss.getSerializedPattern()));
mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()];
+ mPatternSize = ss.getPatternSize();
mInputEnabled = ss.isInputEnabled();
mInStealthMode = ss.isInStealthMode();
mEnableHapticFeedback = ss.isTactileFeedbackEnabled();
@@ -1107,6 +1141,7 @@ public class LockPatternView extends View {
private final String mSerializedPattern;
private final int mDisplayMode;
+ private final byte mPatternSize;
private final boolean mInputEnabled;
private final boolean mInStealthMode;
private final boolean mTactileFeedbackEnabled;
@@ -1115,10 +1150,12 @@ public class LockPatternView extends View {
* Constructor called from {@link LockPatternView#onSaveInstanceState()}
*/
private SavedState(Parcelable superState, String serializedPattern, int displayMode,
- boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) {
+ byte patternSize, boolean inputEnabled, boolean inStealthMode,
+ boolean tactileFeedbackEnabled) {
super(superState);
mSerializedPattern = serializedPattern;
mDisplayMode = displayMode;
+ mPatternSize = patternSize;
mInputEnabled = inputEnabled;
mInStealthMode = inStealthMode;
mTactileFeedbackEnabled = tactileFeedbackEnabled;
@@ -1131,6 +1168,7 @@ public class LockPatternView extends View {
super(in);
mSerializedPattern = in.readString();
mDisplayMode = in.readInt();
+ mPatternSize = (byte) in.readByte();
mInputEnabled = (Boolean) in.readValue(null);
mInStealthMode = (Boolean) in.readValue(null);
mTactileFeedbackEnabled = (Boolean) in.readValue(null);
@@ -1144,6 +1182,10 @@ public class LockPatternView extends View {
return mDisplayMode;
}
+ public byte getPatternSize() {
+ return mPatternSize;
+ }
+
public boolean isInputEnabled() {
return mInputEnabled;
}
@@ -1161,6 +1203,7 @@ public class LockPatternView extends View {
super.writeToParcel(dest, flags);
dest.writeString(mSerializedPattern);
dest.writeInt(mDisplayMode);
+ dest.writeByte(mPatternSize);
dest.writeValue(mInputEnabled);
dest.writeValue(mInStealthMode);
dest.writeValue(mTactileFeedbackEnabled);
diff --git a/core/java/com/android/internal/widget/LockSettingsService.java b/core/java/com/android/internal/widget/LockSettingsService.java
index 4ecbd16..4973627 100644
--- a/core/java/com/android/internal/widget/LockSettingsService.java
+++ b/core/java/com/android/internal/widget/LockSettingsService.java
@@ -32,6 +32,8 @@ import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.Slog;
+import com.android.internal.widget.LockPatternUtils;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -166,15 +168,38 @@ public class LockSettingsService extends ILockSettings.Stub {
return readFromDb(key, defaultValue, userId);
}
+ @Override
+ public byte getLockPatternSize(int userId) {
+ try {
+ long size = getLong(Settings.Secure.LOCK_PATTERN_SIZE, -1, userId);
+ if (size > 0 && size < 128) {
+ return (byte) size;
+ }
+ } catch (RemoteException re) {
+ //Any invalid size handled below
+ }
+ return LockPatternUtils.PATTERN_SIZE_DEFAULT;
+ }
+
+ private boolean isDefaultSize(int userId) {
+ return getLockPatternSize(userId) == LockPatternUtils.PATTERN_SIZE_DEFAULT;
+ }
+
private String getLockPatternFilename(int userId) {
+ return getLockPatternFilename(userId, isDefaultSize(userId));
+ }
+
+ private String getLockPatternFilename(int userId, boolean defaultSize) {
String dataSystemDirectory =
android.os.Environment.getDataDirectory().getAbsolutePath() +
SYSTEM_DIRECTORY;
+ String patternFile = (defaultSize ? "" : "cm_") + LOCK_PATTERN_FILE;
+
if (userId == 0) {
// Leave it in the same place for user 0
- return dataSystemDirectory + LOCK_PATTERN_FILE;
+ return dataSystemDirectory + patternFile;
} else {
- return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
+ return new File(Environment.getUserSystemDirectory(userId), patternFile)
.getAbsolutePath();
}
}
@@ -210,7 +235,9 @@ public class LockSettingsService extends ILockSettings.Stub {
public void setLockPattern(byte[] hash, int userId) throws RemoteException {
checkWritePermission(userId);
- writeFile(getLockPatternFilename(userId), hash);
+ boolean defaultSize = isDefaultSize(userId);
+ writeFile(getLockPatternFilename(userId, defaultSize), hash);
+ writeFile(getLockPatternFilename(userId, !defaultSize), null);
}
@Override
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index aad285a..8763df7 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -23,6 +23,7 @@ import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -62,6 +63,40 @@ public class GlowPadView extends View {
private static final int STATE_SNAP = 4;
private static final int STATE_FINISH = 5;
+ //Lockscreen targets
+ /**
+ * @hide
+ */
+ public final static String ICON_RESOURCE = "icon_resource";
+
+ /**
+ * @hide
+ */
+ public final static String ICON_PACKAGE = "icon_package";
+
+ /**
+ * @hide
+ */
+ public final static String ICON_FILE = "icon_file";
+
+ /**
+ * Number of customizable lockscreen targets for tablets
+ * @hide
+ */
+ public final static int MAX_TABLET_TARGETS = 7;
+
+ /**
+ * Number of customizable lockscreen targets for phones
+ * @hide
+ */
+ public final static int MAX_PHONE_TARGETS = 4;
+
+ /**
+ * Empty target used to reference unused lockscreen targets
+ * @hide
+ */
+ public final static String EMPTY_TARGET = "empty";
+
// Animation properties.
private static final float SNAP_MARGIN_DEFAULT = 20.0f; // distance to ring before we snap to it
@@ -122,6 +157,7 @@ public class GlowPadView extends View {
private boolean mMagneticTargets = false;
private boolean mDragging;
private int mNewTargetResources;
+ private ArrayList<TargetDrawable> mNewTargetDrawables;
private class AnimationBundle extends ArrayList<Tweener> {
private static final long serialVersionUID = 0xA84D78726F127468L;
@@ -187,6 +223,10 @@ public class GlowPadView extends View {
internalSetTargetResources(mNewTargetResources);
mNewTargetResources = 0;
hideTargets(false, false);
+ } else if (mNewTargetDrawables != null) {
+ internalSetTargetResources(mNewTargetDrawables);
+ mNewTargetDrawables = null;
+ hideTargets(false, false);
}
mAnimatingTargets = false;
}
@@ -269,7 +309,9 @@ public class GlowPadView extends View {
a.recycle();
- setVibrateEnabled(mVibrationDuration > 0);
+ final ContentResolver resolver = context.getContentResolver();
+ boolean vibrateEnabled = Settings.System.getInt(resolver,Settings.System.LOCKSCREEN_VIBRATE_ENABLED, 1) == 1;
+ setVibrateEnabled(vibrateEnabled ? mVibrationDuration > 0 : false);
assignDefaultsIfNeeded();
@@ -466,6 +508,7 @@ public class GlowPadView extends View {
// Force ring and targets to finish animation to final expanded state
mTargetAnimations.stop();
}
+ hideTargets(false, false);
} else {
// Animate handle back to the center based on current state.
hideGlow(HIDE_ANIMATION_DURATION, 0, 0.0f, mResetListenerWithPing);
@@ -605,6 +648,14 @@ public class GlowPadView extends View {
}
}
+ private void internalSetTargetResources(ArrayList<TargetDrawable> drawList) {
+ mTargetResourceId = 0;
+ mTargetDrawables = drawList;
+ updateTargetPositions(mWaveCenterX, mWaveCenterY);
+ updatePointCloudPosition(mWaveCenterX, mWaveCenterY);
+ hideTargets(false, false);
+ }
+
/**
* Loads an array of drawables from the given resourceId.
*
@@ -619,10 +670,23 @@ public class GlowPadView extends View {
}
}
+ public void setTargetResources(ArrayList<TargetDrawable> drawList) {
+ if (mAnimatingTargets) {
+ // postpone this change until we return to the initial state
+ mNewTargetDrawables = drawList;
+ } else {
+ internalSetTargetResources(drawList);
+ }
+ }
+
public int getTargetResourceId() {
return mTargetResourceId;
}
+ public ArrayList<TargetDrawable> getTargetDrawables() {
+ return mTargetDrawables;
+ }
+
/**
* Sets the resource id specifying the target descriptions for accessibility.
*
@@ -1245,7 +1309,7 @@ public class GlowPadView extends View {
}
private String getTargetDescription(int index) {
- if (mTargetDescriptions == null || mTargetDescriptions.isEmpty()) {
+ if (mTargetDescriptions == null || mTargetDescriptions.isEmpty() || index >= mTargetDescriptions.size()) {
mTargetDescriptions = loadDescriptions(mTargetDescriptionsResourceId);
if (mTargetDrawables.size() != mTargetDescriptions.size()) {
Log.w(TAG, "The number of target drawables must be"
@@ -1257,7 +1321,7 @@ public class GlowPadView extends View {
}
private String getDirectionDescription(int index) {
- if (mDirectionDescriptions == null || mDirectionDescriptions.isEmpty()) {
+ if (mDirectionDescriptions == null || mDirectionDescriptions.isEmpty() || index >= mDirectionDescriptions.size()) {
mDirectionDescriptions = loadDescriptions(mDirectionDescriptionsResourceId);
if (mTargetDrawables.size() != mDirectionDescriptions.size()) {
Log.w(TAG, "The number of target drawables must be"
diff --git a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
index 30f5f2f..249c948 100644
--- a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
+++ b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
@@ -28,9 +28,9 @@ public class TargetDrawable {
private static final boolean DEBUG = false;
public static final int[] STATE_ACTIVE =
- { android.R.attr.state_enabled, android.R.attr.state_active };
+ { android.R.attr.state_enabled, android.R.attr.state_active, -android.R.attr.state_focused };
public static final int[] STATE_INACTIVE =
- { android.R.attr.state_enabled, -android.R.attr.state_active };
+ { android.R.attr.state_enabled, -android.R.attr.state_active , -android.R.attr.state_focused };
public static final int[] STATE_FOCUSED =
{ android.R.attr.state_enabled, -android.R.attr.state_active,
android.R.attr.state_focused };
@@ -91,6 +91,14 @@ public class TargetDrawable {
setState(STATE_INACTIVE);
}
+ public TargetDrawable(Resources res, Drawable drawable) {
+ mResourceId = 0;
+ // Mutate the drawable so we can animate shared drawable properties.
+ mDrawable = drawable != null ? drawable.mutate() : null;
+ resizeDrawables();
+ setState(STATE_INACTIVE);
+ }
+
public TargetDrawable(TargetDrawable other) {
mResourceId = other.mResourceId;
// Mutate the drawable so we can animate shared drawable properties.
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 3ca085b..de1fb4e 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -86,6 +86,7 @@ LOCAL_SRC_FILES:= \
android_util_Process.cpp \
android_util_StringBlock.cpp \
android_util_XmlBlock.cpp \
+ android_util_PackageRedirectionMap.cpp \
android/graphics/AutoDecodeCancel.cpp \
android/graphics/Bitmap.cpp \
android/graphics/BitmapFactory.cpp \
@@ -151,6 +152,12 @@ LOCAL_SRC_FILES:= \
android_content_res_Configuration.cpp \
android_animation_PropertyValuesHolder.cpp
+ifeq ($(BOARD_USES_QCOM_HARDWARE),true)
+ LOCAL_CFLAGS += -DQCOM_HARDWARE
+ LOCAL_SRC_FILES += \
+ com_android_internal_app_ActivityTrigger.cpp
+endif
+
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
$(LOCAL_PATH)/android/graphics \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 9820e60..01ad2f0 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -173,6 +173,10 @@ extern int register_android_content_res_ObbScanner(JNIEnv* env);
extern int register_android_content_res_Configuration(JNIEnv* env);
extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
+extern int register_android_content_res_PackageRedirectionMap(JNIEnv* env);
+#ifdef QCOM_HARDWARE
+extern int register_com_android_internal_app_ActivityTrigger(JNIEnv *env);
+#endif
static AndroidRuntime* gCurRuntime = NULL;
@@ -1212,6 +1216,12 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
+ REG_JNI(register_android_content_res_PackageRedirectionMap),
+
+#ifdef QCOM_HARDWARE
+ REG_JNI(register_com_android_internal_app_ActivityTrigger),
+#endif
+
};
/*
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 8823328..07603f4 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -15,6 +15,7 @@
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
+#include <cutils/properties.h>
#include <androidfw/Asset.h>
#include <androidfw/ResourceTypes.h>
#include <netinet/in.h>
@@ -45,6 +46,8 @@ jfieldID gBitmap_layoutBoundsFieldID;
using namespace android;
+bool mPurgeableAssets;
+
static inline int32_t validOrNeg1(bool isValid, int32_t value) {
// return isValid ? value : -1;
SkASSERT((int)isValid == 0 || (int)isValid == 1);
@@ -491,8 +494,8 @@ static jobject nativeDecodeAssetScaled(JNIEnv* env, jobject clazz, jint native_a
SkStream* stream;
Asset* asset = reinterpret_cast<Asset*>(native_asset);
- bool forcePurgeable = optionsPurgeable(env, options);
- if (forcePurgeable) {
+ bool forcePurgeable = mPurgeableAssets;
+ if (forcePurgeable || optionsPurgeable(env, options)) {
// if we could "ref/reopen" the asset, we may not need to copy it here
// and we could assume optionsShareable, since assets are always RO
stream = copyAssetToStream(asset);
@@ -616,6 +619,11 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) {
SkASSERT(bitmap_class);
gBitmap_nativeBitmapFieldID = getFieldIDCheck(env, bitmap_class, "mNativeBitmap", "I");
gBitmap_layoutBoundsFieldID = getFieldIDCheck(env, bitmap_class, "mLayoutBounds", "[I");
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("persist.sys.purgeable_assets", value, "0");
+ mPurgeableAssets = atoi(value) == 1;
+
int ret = AndroidRuntime::registerNativeMethods(env,
"android/graphics/BitmapFactory$Options",
gOptionsMethods,
diff --git a/core/jni/android_emoji_EmojiFactory.cpp b/core/jni/android_emoji_EmojiFactory.cpp
index a658561..4383997 100644
--- a/core/jni/android_emoji_EmojiFactory.cpp
+++ b/core/jni/android_emoji_EmojiFactory.cpp
@@ -3,8 +3,7 @@
#define LOG_TAG "EmojiFactory_jni"
#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
+#include <ScopedUtfChars.h>
#include "EmojiFactory.h"
#include <nativehelper/JNIHelp.h>
@@ -125,16 +124,13 @@ static jobject android_emoji_EmojiFactory_newInstance(
return NULL;
}
- const jchar* jchars = env->GetStringChars(name, NULL);
- jsize len = env->GetStringLength(name);
- String8 str(String16(jchars, len));
+ ScopedUtfChars nameUtf(env, name);
- EmojiFactory *factory = gCaller->TryCallGetImplementation(str.string());
+ EmojiFactory *factory = gCaller->TryCallGetImplementation(nameUtf.c_str());
// EmojiFactory *factory = EmojiFactory::GetImplementation(str.string());
if (NULL == factory) {
return NULL;
}
- env->ReleaseStringChars(name, jchars);
return create_java_EmojiFactory(env, factory, name);
}
@@ -151,8 +147,8 @@ static jobject android_emoji_EmojiFactory_newAvailableInstance(
if (NULL == factory) {
return NULL;
}
- String16 name_16(String8(factory->Name()));
- jstring jname = env->NewString(name_16.string(), name_16.size());
+
+ jstring jname = env->NewStringUTF(factory->Name());
if (NULL == jname) {
return NULL;
}
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 67d831c..d8fc55e 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -840,12 +840,16 @@ static void android_hardware_Camera_stopFaceDetection(JNIEnv *env, jobject thiz)
static void android_hardware_Camera_enableFocusMoveCallback(JNIEnv *env, jobject thiz, jint enable)
{
ALOGV("enableFocusMoveCallback");
+#ifdef ICS_CAMERA_BLOB
+ return;
+#else
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
if (camera->sendCommand(CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG, enable, 0) != NO_ERROR) {
jniThrowRuntimeException(env, "enable focus move callback failed");
}
+#endif
}
//-------------------------------------------------
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index c76cb64..b75cc55 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -49,6 +49,11 @@ struct fields_t {
jmethodID postNativeEventInJava; //... event post callback method
int PCM16; //... format constants
int PCM8; //... format constants
+ int AMRNB; //... format constants
+ int AMRWB; //... format constants
+ int EVRC; //... format constants
+ int EVRCB; //... format constants
+ int EVRCWB; //... format constants
jfieldID nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object
jfieldID nativeCallbackCookie; // provides access to the AudioRecord callback data
};
@@ -162,6 +167,24 @@ static sp<AudioRecord> setAudioRecord(JNIEnv* env, jobject thiz, const sp<AudioR
env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (int)ar.get());
return old;
}
+int getformatrec(int audioformat)
+{
+ if(audioformat==javaAudioRecordFields.PCM16)
+ return AUDIO_FORMAT_PCM_16_BIT;
+#ifdef QCOM_HARDWARE
+ else if(audioformat==javaAudioRecordFields.AMRNB)
+ return AUDIO_FORMAT_AMR_NB;
+ else if(audioformat==javaAudioRecordFields.AMRWB)
+ return AUDIO_FORMAT_AMR_WB;
+ else if(audioformat==javaAudioRecordFields.EVRC)
+ return AUDIO_FORMAT_EVRC;
+ else if(audioformat==javaAudioRecordFields.EVRCB)
+ return AUDIO_FORMAT_EVRCB;
+ else if(audioformat==javaAudioRecordFields.EVRCWB)
+ return AUDIO_FORMAT_EVRCWB;
+#endif
+ return AUDIO_FORMAT_PCM_8_BIT;
+}
// ----------------------------------------------------------------------------
static int
@@ -181,14 +204,27 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
// compare the format against the Java constants
if ((audioFormat != javaAudioRecordFields.PCM16)
+#ifdef QCOM_HARDWARE
+ && (audioFormat != javaAudioRecordFields.AMRNB)
+ && (audioFormat != javaAudioRecordFields.AMRWB)
+ && (audioFormat != javaAudioRecordFields.EVRC)
+ && (audioFormat != javaAudioRecordFields.EVRCB)
+#endif
&& (audioFormat != javaAudioRecordFields.PCM8)) {
ALOGE("Error creating AudioRecord: unsupported audio format.");
return AUDIORECORD_ERROR_SETUP_INVALIDFORMAT;
}
-
- int bytesPerSample = audioFormat==javaAudioRecordFields.PCM16 ? 2 : 1;
- audio_format_t format = audioFormat==javaAudioRecordFields.PCM16 ?
- AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
+ int bytesPerSample;
+ if(audioFormat == javaAudioRecordFields.PCM8)
+ bytesPerSample = 1;
+#ifdef QCOM_HARDWARE
+ else if((audioFormat == javaAudioRecordFields.AMRWB) &&
+ ((uint32_t)source != AUDIO_SOURCE_VOICE_COMMUNICATION))
+ bytesPerSample = 61;
+#endif
+ else
+ bytesPerSample = 2;
+ audio_format_t format = (audio_format_t)getformatrec(audioFormat);
if (buffSizeInBytes == 0) {
ALOGE("Error creating AudioRecord: frameCount is 0.");
@@ -514,9 +550,8 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
int frameCount = 0;
status_t result = AudioRecord::getMinFrameCount(&frameCount,
sampleRateInHertz,
- (audioFormat == javaAudioRecordFields.PCM16 ?
- AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT),
- audio_channel_in_mask_from_count(nbChannels));
+ (audio_format_t)getformatrec(audioFormat),
+ nbChannels);
if (result == BAD_VALUE) {
return 0;
@@ -524,7 +559,17 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
if (result != NO_ERROR) {
return -1;
}
- return frameCount * nbChannels * (audioFormat == javaAudioRecordFields.PCM16 ? 2 : 1);
+ int bytesPerSample;
+ if(audioFormat == javaAudioRecordFields.PCM8)
+ bytesPerSample = 1;
+#ifdef QCOM_HARDWARE
+ else if(audioFormat == javaAudioRecordFields.AMRWB)
+ bytesPerSample = 61;
+#endif
+ else
+ bytesPerSample = 2;
+
+ return frameCount * nbChannels * bytesPerSample;
}
@@ -558,6 +603,11 @@ static JNINativeMethod gMethods[] = {
#define JAVA_POSTEVENT_CALLBACK_NAME "postEventFromNative"
#define JAVA_CONST_PCM16_NAME "ENCODING_PCM_16BIT"
#define JAVA_CONST_PCM8_NAME "ENCODING_PCM_8BIT"
+#define JAVA_CONST_AMRNB_NAME "ENCODING_AMRNB"
+#define JAVA_CONST_AMRWB_NAME "ENCODING_AMRWB"
+#define JAVA_CONST_EVRC_NAME "ENCODING_EVRC"
+#define JAVA_CONST_EVRCB_NAME "ENCODING_EVRCB"
+#define JAVA_CONST_EVRCWB_NAME "ENCODING_EVRCWB"
#define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME "mNativeRecorderInJavaObj"
#define JAVA_NATIVECALLBACKINFO_FIELD_NAME "mNativeCallbackCookie"
@@ -621,7 +671,22 @@ int register_android_media_AudioRecord(JNIEnv *env)
JAVA_CONST_PCM16_NAME, &(javaAudioRecordFields.PCM16))
|| !android_media_getIntConstantFromClass(env, audioFormatClass,
JAVA_AUDIOFORMAT_CLASS_NAME,
- JAVA_CONST_PCM8_NAME, &(javaAudioRecordFields.PCM8)) ) {
+ JAVA_CONST_PCM8_NAME, &(javaAudioRecordFields.PCM8))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_AMRNB_NAME, &(javaAudioRecordFields.AMRNB))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_AMRWB_NAME, &(javaAudioRecordFields.AMRWB))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_EVRC_NAME, &(javaAudioRecordFields.EVRC))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_EVRCB_NAME, &(javaAudioRecordFields.EVRCB))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_EVRCWB_NAME, &(javaAudioRecordFields.EVRCWB))) {
// error log performed in getIntConstantFromClass()
return -1;
}
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 7e5263d..e462f58 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,6 +50,19 @@ struct fields_t {
jmethodID postNativeEventInJava; //... event post callback method
int PCM16; //... format constants
int PCM8; //... format constants
+ int AMRNB; //... format constants
+ int AMRWB; //... format constants
+ int EVRC; //... format constants
+ int EVRCB; //... format constants
+ int EVRCWB; //... format constants
+ int STREAM_VOICE_CALL; //... stream type constants
+ int STREAM_SYSTEM; //... stream type constants
+ int STREAM_RING; //... stream type constants
+ int STREAM_MUSIC; //... stream type constants
+ int STREAM_ALARM; //... stream type constants
+ int STREAM_NOTIFICATION; //... stream type constants
+ int STREAM_BLUETOOTH_SCO; //... stream type constants
+ int STREAM_DTMF; //... stream type constants
int MODE_STREAM; //... memory mode
int MODE_STATIC; //... memory mode
jfieldID nativeTrackInJavaObj; // stores in Java the native AudioTrack object
@@ -199,6 +213,25 @@ static sp<AudioTrack> setAudioTrack(JNIEnv* env, jobject thiz, const sp<AudioTra
}
// ----------------------------------------------------------------------------
+int getformat(int audioformat)
+{
+ if(audioformat==javaAudioTrackFields.PCM16)
+ return AUDIO_FORMAT_PCM_16_BIT;
+#ifdef QCOM_HARDWARE
+ else if(audioformat==javaAudioTrackFields.AMRNB)
+ return AUDIO_FORMAT_AMR_NB;
+ else if(audioformat==javaAudioTrackFields.AMRWB)
+ return AUDIO_FORMAT_AMR_WB;
+ else if(audioformat==javaAudioTrackFields.EVRC)
+ return AUDIO_FORMAT_EVRC;
+ else if(audioformat==javaAudioTrackFields.EVRCB)
+ return AUDIO_FORMAT_EVRCB;
+ else if(audioformat==javaAudioTrackFields.EVRCWB)
+ return AUDIO_FORMAT_EVRCWB;
+#endif
+ return AUDIO_FORMAT_PCM_8_BIT;
+}
+
static int
android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jint streamType, jint sampleRateInHertz, jint javaChannelMask,
@@ -249,7 +282,15 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
// check the format.
// This function was called from Java, so we compare the format against the Java constants
- if ((audioFormat != javaAudioTrackFields.PCM16) && (audioFormat != javaAudioTrackFields.PCM8)) {
+ if ((audioFormat != javaAudioTrackFields.PCM16)
+#ifdef QCOM_HARDWARE
+ && (audioFormat != javaAudioTrackFields.AMRNB)
+ && (audioFormat != javaAudioTrackFields.AMRWB)
+ && (audioFormat != javaAudioTrackFields.EVRC)
+ && (audioFormat != javaAudioTrackFields.EVRCB)
+ && (audioFormat != javaAudioTrackFields.EVRCWB)
+#endif
+ && (audioFormat != javaAudioTrackFields.PCM8)) {
ALOGE("Error creating AudioTrack: unsupported audio format.");
return AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT;
}
@@ -268,9 +309,12 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
}
// compute the frame count
- int bytesPerSample = audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1;
- audio_format_t format = audioFormat == javaAudioTrackFields.PCM16 ?
- AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
+ int bytesPerSample;
+ if(audioFormat == javaAudioTrackFields.PCM8)
+ bytesPerSample = 1;
+ else
+ bytesPerSample = 2;
+ audio_format_t format = (audio_format_t)getformat(audioFormat);
int frameCount = buffSizeInBytes / (nbChannels * bytesPerSample);
jclass clazz = env->GetObjectClass(thiz);
@@ -516,7 +560,16 @@ jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, jbyte* data,
if (track->sharedBuffer() == 0) {
written = track->write(data + offsetInBytes, sizeInBytes);
} else {
+#ifdef QCOM_HARDWARE
+ if ((audioFormat == javaAudioTrackFields.PCM16)
+ || (audioFormat == javaAudioTrackFields.AMRNB)
+ || (audioFormat == javaAudioTrackFields.AMRWB)
+ || (audioFormat == javaAudioTrackFields.EVRC)
+ || (audioFormat == javaAudioTrackFields.EVRCB)
+ || (audioFormat == javaAudioTrackFields.EVRCWB)) {
+#else
if (audioFormat == javaAudioTrackFields.PCM16) {
+#endif
// writing to shared memory, check for capacity
if ((size_t)sizeInBytes > track->sharedBuffer()->size()) {
sizeInBytes = track->sharedBuffer()->size();
@@ -791,7 +844,7 @@ static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thi
sampleRateInHertz) != NO_ERROR) {
return -1;
}
- return frameCount * nbChannels * (audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1);
+ return frameCount * nbChannels * (audioFormat == javaAudioTrackFields.PCM8 ? 1 : 2);
}
// ----------------------------------------------------------------------------
@@ -866,6 +919,11 @@ static JNINativeMethod gMethods[] = {
#define JAVA_POSTEVENT_CALLBACK_NAME "postEventFromNative"
#define JAVA_CONST_PCM16_NAME "ENCODING_PCM_16BIT"
#define JAVA_CONST_PCM8_NAME "ENCODING_PCM_8BIT"
+#define JAVA_CONST_AMRNB_NAME "ENCODING_AMRNB"
+#define JAVA_CONST_AMRWB_NAME "ENCODING_AMRWB"
+#define JAVA_CONST_EVRC_NAME "ENCODING_EVRC"
+#define JAVA_CONST_EVRCB_NAME "ENCODING_EVRCB"
+#define JAVA_CONST_EVRCWB_NAME "ENCODING_EVRCWB"
#define JAVA_CONST_BUFFER_COUNT_NAME "BUFFER_COUNT"
#define JAVA_CONST_STREAM_VOICE_CALL_NAME "STREAM_VOICE_CALL"
#define JAVA_CONST_STREAM_SYSTEM_NAME "STREAM_SYSTEM"
@@ -963,7 +1021,57 @@ int register_android_media_AudioTrack(JNIEnv *env)
JAVA_CONST_PCM16_NAME, &(javaAudioTrackFields.PCM16))
|| !android_media_getIntConstantFromClass(env, audioFormatClass,
JAVA_AUDIOFORMAT_CLASS_NAME,
- JAVA_CONST_PCM8_NAME, &(javaAudioTrackFields.PCM8)) ) {
+ JAVA_CONST_PCM8_NAME, &(javaAudioTrackFields.PCM8))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_AMRNB_NAME, &(javaAudioTrackFields.AMRNB))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_AMRWB_NAME, &(javaAudioTrackFields.AMRWB))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_EVRC_NAME, &(javaAudioTrackFields.EVRC))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_EVRCB_NAME, &(javaAudioTrackFields.EVRCB))
+ || !android_media_getIntConstantFromClass(env, audioFormatClass,
+ JAVA_AUDIOFORMAT_CLASS_NAME,
+ JAVA_CONST_EVRCWB_NAME, &(javaAudioTrackFields.EVRCWB))
+) {
+ // error log performed in android_media_getIntConstantFromClass()
+ return -1;
+ }
+ // Get the stream types from the AudioManager class
+ jclass audioManagerClass = NULL;
+ audioManagerClass = env->FindClass(JAVA_AUDIOMANAGER_CLASS_NAME);
+ if (audioManagerClass == NULL) {
+ ALOGE("Can't find %s", JAVA_AUDIOMANAGER_CLASS_NAME);
+ return -1;
+ }
+ if ( !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_VOICE_CALL_NAME, &(javaAudioTrackFields.STREAM_VOICE_CALL))
+ || !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_MUSIC_NAME, &(javaAudioTrackFields.STREAM_MUSIC))
+ || !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_SYSTEM_NAME, &(javaAudioTrackFields.STREAM_SYSTEM))
+ || !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_RING_NAME, &(javaAudioTrackFields.STREAM_RING))
+ || !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_ALARM_NAME, &(javaAudioTrackFields.STREAM_ALARM))
+ || !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_NOTIFICATION_NAME, &(javaAudioTrackFields.STREAM_NOTIFICATION))
+ || !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_BLUETOOTH_SCO_NAME, &(javaAudioTrackFields.STREAM_BLUETOOTH_SCO))
+ || !android_media_getIntConstantFromClass(env, audioManagerClass,
+ JAVA_AUDIOMANAGER_CLASS_NAME,
+ JAVA_CONST_STREAM_DTMF_NAME, &(javaAudioTrackFields.STREAM_DTMF))) {
// error log performed in android_media_getIntConstantFromClass()
return -1;
}
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 9537ac4..d36ac4e 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -190,7 +190,10 @@ static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jI
return doStringCommand(env, ifname.c_str(), "%s", command.c_str());
}
-
+static jboolean android_net_wifi_setMode(JNIEnv* env, jobject, jint type)
+{
+ return (jboolean)(::wifi_set_mode(type) == 0);
+}
// ----------------------------------------------------------------------------
@@ -217,6 +220,7 @@ static JNINativeMethod gWifiMethods[] = {
(void*) android_net_wifi_doIntCommand },
{ "doStringCommand", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_doStringCommand },
+ { "setMode", "(I)Z", (void*) android_net_wifi_setMode},
};
int register_android_net_wifi_WifiManager(JNIEnv* env)
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index d422951..e29ea70 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1,6 +1,7 @@
/* //device/libs/android_runtime/android_util_AssetManager.cpp
**
** Copyright 2006, The Android Open Source Project
+** This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -34,9 +35,13 @@
#include <androidfw/Asset.h>
#include <androidfw/AssetManager.h>
#include <androidfw/ResourceTypes.h>
+#include <androidfw/PackageRedirectionMap.h>
+#include <androidfw/ZipFile.h>
#include <stdio.h>
+#define REDIRECT_NOISY(x) //x
+
namespace android {
// ----------------------------------------------------------------------------
@@ -691,17 +696,23 @@ static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject
}
const ResTable& res(am->getResources());
+ uint32_t ref = res.lookupRedirectionMap(ident);
+ if (ref == 0) {
+ ref = ident;
+ } else {
+ REDIRECT_NOISY(ALOGW("PERFORMED REDIRECT OF ident=0x%08x FOR ref=0x%08x\n", ident, ref));
+ }
+
Res_value value;
ResTable_config config;
uint32_t typeSpecFlags;
- ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
+ ssize_t block = res.getResource(ref, &value, false, density, &typeSpecFlags, &config);
#if THROW_ON_BAD_ID
if (block == BAD_INDEX) {
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
return 0;
}
#endif
- uint32_t ref = ident;
if (resolve) {
block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);
#if THROW_ON_BAD_ID
@@ -885,7 +896,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
return JNI_FALSE;
}
- DEBUG_STYLES(LOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x xml=0x%x",
+ DEBUG_STYLES(ALOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x xml=0x%x",
themeToken, defStyleAttr, defStyleRes, xmlParserToken));
ResTable::Theme* theme = (ResTable::Theme*)themeToken;
@@ -952,6 +963,20 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
// Now lock down the resource object and start pulling stuff from it.
res.lock();
+ // Apply theme redirections to the referenced styles.
+ if (defStyleRes != 0) {
+ uint32_t ref = res.lookupRedirectionMap(defStyleRes);
+ if (ref != 0) {
+ defStyleRes = ref;
+ }
+ }
+ if (style != 0) {
+ uint32_t ref = res.lookupRedirectionMap(style);
+ if (ref != 0) {
+ style = ref;
+ }
+ }
+
// Retrieve the default style bag, if requested.
const ResTable::bag_entry* defStyleEnt = NULL;
uint32_t defStyleTypeSetFlags = 0;
@@ -983,7 +1008,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
for (jsize ii=0; ii<NI; ii++) {
const uint32_t curIdent = (uint32_t)src[ii];
- DEBUG_STYLES(LOGI("RETRIEVING ATTR 0x%08x...", curIdent));
+ DEBUG_STYLES(ALOGI("RETRIEVING ATTR 0x%08x...", curIdent));
// Try to find a value for this attribute... we prioritize values
// coming from, first XML attributes, then XML style, then default
@@ -1004,7 +1029,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
xmlParser->getAttributeValue(ix, &value);
ix++;
curXmlAttr = xmlParser->getAttributeNameResID(ix);
- DEBUG_STYLES(LOGI("-> From XML: type=0x%x, data=0x%08x",
+ DEBUG_STYLES(ALOGI("-> From XML: type=0x%x, data=0x%08x",
value.dataType, value.data));
}
@@ -1018,7 +1043,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
block = styleEnt->stringBlock;
typeSetFlags = styleTypeSetFlags;
value = styleEnt->map.value;
- DEBUG_STYLES(LOGI("-> From style: type=0x%x, data=0x%08x",
+ DEBUG_STYLES(ALOGI("-> From style: type=0x%x, data=0x%08x",
value.dataType, value.data));
}
styleEnt++;
@@ -1034,7 +1059,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
block = defStyleEnt->stringBlock;
typeSetFlags = defStyleTypeSetFlags;
value = defStyleEnt->map.value;
- DEBUG_STYLES(LOGI("-> From def style: type=0x%x, data=0x%08x",
+ DEBUG_STYLES(ALOGI("-> From def style: type=0x%x, data=0x%08x",
value.dataType, value.data));
}
defStyleEnt++;
@@ -1046,14 +1071,14 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
ssize_t newBlock = theme->resolveAttributeReference(&value, block,
&resid, &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
- DEBUG_STYLES(LOGI("-> Resolved attr: type=0x%x, data=0x%08x",
+ DEBUG_STYLES(ALOGI("-> Resolved attr: type=0x%x, data=0x%08x",
value.dataType, value.data));
} else {
// If we still don't have a value for this attribute, try to find
// it in the theme!
ssize_t newBlock = theme->getAttribute(curIdent, &value, &typeSetFlags);
if (newBlock >= 0) {
- DEBUG_STYLES(LOGI("-> From theme: type=0x%x, data=0x%08x",
+ DEBUG_STYLES(ALOGI("-> From theme: type=0x%x, data=0x%08x",
value.dataType, value.data));
newBlock = res.resolveReference(&value, block, &resid,
&typeSetFlags, &config);
@@ -1064,19 +1089,44 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
}
#endif
if (newBlock >= 0) block = newBlock;
- DEBUG_STYLES(LOGI("-> Resolved theme: type=0x%x, data=0x%08x",
+ DEBUG_STYLES(ALOGI("-> Resolved theme: type=0x%x, data=0x%08x",
value.dataType, value.data));
}
}
// Deal with the special @null value -- it turns back to TYPE_NULL.
if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
- DEBUG_STYLES(LOGI("-> Setting to @null!"));
+ DEBUG_STYLES(ALOGI("-> Setting to @null!"));
value.dataType = Res_value::TYPE_NULL;
block = kXmlBlock;
}
- DEBUG_STYLES(LOGI("Attribute 0x%08x: type=0x%x, data=0x%08x",
+ // One final test for a resource redirection from the applied theme.
+ if (resid != 0) {
+ uint32_t redirect = res.lookupRedirectionMap(resid);
+ if (redirect != 0) {
+ REDIRECT_NOISY(ALOGW("deep REDIRECT 0x%08x => 0x%08x\n", resid, redirect));
+ ssize_t newBlock = res.getResource(redirect, &value, true, config.density, &typeSetFlags, &config);
+ if (newBlock >= 0) {
+ newBlock = res.resolveReference(&value, newBlock, &redirect, &typeSetFlags, &config);
+#if THROW_ON_BAD_ID
+ if (newBlock == BAD_INDEX) {
+ jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
+ return JNI_FALSE;
+ }
+#endif
+ if (newBlock >= 0) {
+ block = newBlock;
+ resid = redirect;
+ }
+ }
+ if (resid != redirect) {
+ ALOGW("deep redirect failure from 0x%08x => 0x%08x, defStyleAttr=0x%08x, defStyleRes=0x%08x, style=0x%08x\n", resid, redirect, defStyleAttr, defStyleRes, style);
+ }
+ }
+ }
+
+ DEBUG_STYLES(ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x",
curIdent, value.dataType, value.data));
// Write the final value back to Java.
@@ -1333,6 +1383,31 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
value.dataType = Res_value::TYPE_NULL;
}
+ // One final test for a resource redirection from the applied theme.
+ if (resid != 0) {
+ uint32_t redirect = res.lookupRedirectionMap(resid);
+ if (redirect != 0) {
+ REDIRECT_NOISY(ALOGW("array REDIRECT 0x%08x => 0x%08x\n", resid, redirect));
+ ssize_t newBlock = res.getResource(redirect, &value, true, config.density, &typeSetFlags, &config);
+ if (newBlock >= 0) {
+ newBlock = res.resolveReference(&value, newBlock, &redirect, &typeSetFlags, &config);
+#if THROW_ON_BAD_ID
+ if (newBlock == BAD_INDEX) {
+ jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
+ return JNI_FALSE;
+ }
+#endif
+ if (newBlock >= 0) {
+ block = newBlock;
+ resid = redirect;
+ }
+ }
+ if (resid != redirect) {
+ ALOGW("array redirect failure from 0x%08x => 0x%08x, array id=0x%08x", resid, redirect, id);
+ }
+ }
+ }
+
//printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
// Write the final value back to Java.
@@ -1561,6 +1636,84 @@ static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, j
return array;
}
+static jint android_content_AssetManager_splitThemePackage(JNIEnv* env, jobject clazz,
+ jstring srcFileName, jstring dstFileName, jobjectArray drmProtectedAssetNames)
+{
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return -1;
+ }
+
+ ALOGV("splitThemePackage in %p (Java object %p)\n", am, clazz);
+
+ if (srcFileName == NULL || dstFileName == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", srcFileName == NULL ? "srcFileName" : "dstFileName");
+ return -2;
+ }
+
+ jsize size = env->GetArrayLength(drmProtectedAssetNames);
+ if (size == 0) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "drmProtectedAssetNames");
+ return -3;
+ }
+
+ const char* srcFileName8 = env->GetStringUTFChars(srcFileName, NULL);
+ ZipFile* srcZip = new ZipFile;
+ status_t err = srcZip->open(srcFileName8, ZipFile::kOpenReadWrite);
+ if (err != NO_ERROR) {
+ ALOGV("error opening zip file %s\n", srcFileName8);
+ delete srcZip;
+ env->ReleaseStringUTFChars(srcFileName, srcFileName8);
+ return -4;
+ }
+
+ const char* dstFileName8 = env->GetStringUTFChars(dstFileName, NULL);
+ ZipFile* dstZip = new ZipFile;
+ err = dstZip->open(dstFileName8, ZipFile::kOpenReadWrite | ZipFile::kOpenTruncate | ZipFile::kOpenCreate);
+
+ if (err != NO_ERROR) {
+ ALOGV("error opening zip file %s\n", dstFileName8);
+ delete srcZip;
+ delete dstZip;
+ env->ReleaseStringUTFChars(srcFileName, srcFileName8);
+ env->ReleaseStringUTFChars(dstFileName, dstFileName8);
+ return -5;
+ }
+
+ int result = 0;
+ for (int i = 0; i < size; i++) {
+ jstring javaString = (jstring)env->GetObjectArrayElement(drmProtectedAssetNames, i);
+ const char* drmProtectedAssetFileName8 = env->GetStringUTFChars(javaString, NULL);
+ ZipEntry *assetEntry = srcZip->getEntryByName(drmProtectedAssetFileName8);
+ if (assetEntry == NULL) {
+ result = 1;
+ ALOGV("Invalid asset entry %s\n", drmProtectedAssetFileName8);
+ } else {
+ status_t loc_result = dstZip->add(srcZip, assetEntry, 0, NULL);
+ if (loc_result != NO_ERROR) {
+ ALOGV("error copying zip entry %s\n", drmProtectedAssetFileName8);
+ result = result | 2;
+ } else {
+ loc_result = srcZip->remove(assetEntry);
+ if (loc_result != NO_ERROR) {
+ ALOGV("error removing zip entry %s\n", drmProtectedAssetFileName8);
+ result = result | 4;
+ }
+ }
+ }
+ env->ReleaseStringUTFChars(javaString, drmProtectedAssetFileName8);
+ }
+ srcZip->flush();
+ dstZip->flush();
+
+ delete srcZip;
+ delete dstZip;
+ env->ReleaseStringUTFChars(srcFileName, srcFileName8);
+ env->ReleaseStringUTFChars(dstFileName, dstFileName8);
+
+ return (jint)result;
+}
+
static void android_content_AssetManager_init(JNIEnv* env, jobject clazz)
{
AssetManager* am = new AssetManager();
@@ -1607,6 +1760,173 @@ static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env,
return AssetManager::getGlobalCount();
}
+static jint android_content_AssetManager_getBasePackageCount(JNIEnv* env, jobject clazz)
+{
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return JNI_FALSE;
+ }
+
+ return am->getResources().getBasePackageCount();
+}
+
+static jstring android_content_AssetManager_getBasePackageName(JNIEnv* env, jobject clazz, jint index)
+{
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return JNI_FALSE;
+ }
+
+ String16 packageName(am->getResources().getBasePackageName(index));
+ return env->NewString((const jchar*)packageName.string(), packageName.size());
+}
+
+static jint android_content_AssetManager_getBasePackageId(JNIEnv* env, jobject clazz, jint index)
+{
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return JNI_FALSE;
+ }
+
+ return am->getResources().getBasePackageId(index);
+}
+
+static void android_content_AssetManager_addRedirectionsNative(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap)
+{
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return;
+ }
+
+ am->addRedirections(resMap);
+}
+
+static void android_content_AssetManager_clearRedirectionsNative(JNIEnv* env, jobject clazz)
+{
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return;
+ }
+
+ am->clearRedirections();
+}
+
+static jboolean android_content_AssetManager_generateStyleRedirections(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap, jint sourceStyle, jint destStyle)
+{
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return JNI_FALSE;
+ }
+
+ const ResTable& res(am->getResources());
+
+ res.lock();
+
+ // Load up a bag for the user-supplied theme.
+ const ResTable::bag_entry* themeEnt = NULL;
+ ssize_t N = res.getBagLocked(destStyle, &themeEnt);
+ const ResTable::bag_entry* endThemeEnt = themeEnt + (N >= 0 ? N : 0);
+
+ // ...and a bag for the framework default.
+ const ResTable::bag_entry* frameworkEnt = NULL;
+ N = res.getBagLocked(sourceStyle, &frameworkEnt);
+ const ResTable::bag_entry* endFrameworkEnt = frameworkEnt + (N >= 0 ? N : 0);
+
+ // Add the source => dest style redirection first.
+ jboolean ret = JNI_FALSE;
+ if (themeEnt < endThemeEnt && frameworkEnt < endFrameworkEnt) {
+ resMap->addRedirection(sourceStyle, destStyle);
+ ret = JNI_TRUE;
+ }
+
+ // Now compare them and infer resource redirections for attributes that
+ // remap to different styles. This works by essentially lining up all the
+ // sorted attributes from each theme and detected TYPE_REFERENCE entries
+ // that point to different resources. When we find such a mismatch, we'll
+ // create a resource redirection from the original framework resource ID to
+ // the one in the theme. This lets us do things like automatically find
+ // redirections for @android:style/Widget.Button by looking at how the
+ // theme overrides the android:attr/buttonStyle attribute.
+ REDIRECT_NOISY(ALOGW("delta between 0x%08x and 0x%08x:\n", sourceStyle, destStyle));
+ for (; frameworkEnt < endFrameworkEnt; frameworkEnt++) {
+ if (frameworkEnt->map.value.dataType != Res_value::TYPE_REFERENCE) {
+ continue;
+ }
+
+ uint32_t curIdent = frameworkEnt->map.name.ident;
+
+ // Walk along the theme entry looking for a match.
+ while (themeEnt < endThemeEnt && curIdent > themeEnt->map.name.ident) {
+ themeEnt++;
+ }
+ // Match found, compare the references.
+ if (themeEnt < endThemeEnt && curIdent == themeEnt->map.name.ident) {
+ if (themeEnt->map.value.data != frameworkEnt->map.value.data) {
+ uint32_t fromIdent = frameworkEnt->map.value.data;
+ uint32_t toIdent = themeEnt->map.value.data;
+ REDIRECT_NOISY(ALOGW(" generated mapping from 0x%08x => 0x%08x (by attr 0x%08x)\n",
+ fromIdent, toIdent, curIdent));
+ resMap->addRedirection(fromIdent, toIdent);
+ }
+ themeEnt++;
+ }
+
+ // Exhausted the theme, bail early.
+ if (themeEnt >= endThemeEnt) {
+ break;
+ }
+ }
+
+ res.unlock();
+
+ return ret;
+}
+
+static jboolean android_content_AssetManager_detachThemePath(JNIEnv* env, jobject clazz,
+ jstring packageName, jint cookie)
+{
+ if (packageName == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", "packageName");
+ return JNI_FALSE;
+ }
+
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return JNI_FALSE;
+ }
+
+ const char* name8 = env->GetStringUTFChars(packageName, NULL);
+ bool res = am->detachThemePath(String8(name8), (void *)cookie);
+ env->ReleaseStringUTFChars(packageName, name8);
+
+ return res;
+}
+
+static jint android_content_AssetManager_attachThemePath(
+ JNIEnv* env, jobject clazz, jstring path)
+{
+ if (path == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", "path");
+ return JNI_FALSE;
+ }
+
+ AssetManager* am = assetManagerForJavaObject(env, clazz);
+ if (am == NULL) {
+ return JNI_FALSE;
+ }
+
+ const char* path8 = env->GetStringUTFChars(path, NULL);
+
+ void* cookie;
+ bool res = am->attachThemePath(String8(path8), &cookie);
+
+ env->ReleaseStringUTFChars(path, path8);
+
+ return (res) ? (jint)cookie : 0;
+}
+
// ----------------------------------------------------------------------------
/*
@@ -1716,6 +2036,28 @@ static JNINativeMethod gAssetManagerMethods[] = {
(void*) android_content_AssetManager_getAssetAllocations },
{ "getGlobalAssetManagerCount", "()I",
(void*) android_content_AssetManager_getGlobalAssetCount },
+
+ // Split theme package apk into two.
+ { "splitThemePackage","(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)I",
+ (void*) android_content_AssetManager_splitThemePackage },
+
+ // Dynamic theme package support.
+ { "detachThemePath", "(Ljava/lang/String;I)Z",
+ (void*) android_content_AssetManager_detachThemePath },
+ { "attachThemePath", "(Ljava/lang/String;)I",
+ (void*) android_content_AssetManager_attachThemePath },
+ { "getBasePackageCount", "()I",
+ (void*) android_content_AssetManager_getBasePackageCount },
+ { "getBasePackageName", "(I)Ljava/lang/String;",
+ (void*) android_content_AssetManager_getBasePackageName },
+ { "getBasePackageId", "(I)I",
+ (void*) android_content_AssetManager_getBasePackageId },
+ { "addRedirectionsNative", "(I)V",
+ (void*) android_content_AssetManager_addRedirectionsNative },
+ { "clearRedirectionsNative", "()V",
+ (void*) android_content_AssetManager_clearRedirectionsNative },
+ { "generateStyleRedirections", "(III)Z",
+ (void*) android_content_AssetManager_generateStyleRedirections },
};
int register_android_content_AssetManager(JNIEnv* env)
diff --git a/core/jni/android_util_PackageRedirectionMap.cpp b/core/jni/android_util_PackageRedirectionMap.cpp
new file mode 100644
index 0000000..97380f3
--- /dev/null
+++ b/core/jni/android_util_PackageRedirectionMap.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011, T-Mobile USA, Inc.
+ *
+ * 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.
+ */
+
+#include <androidfw/PackageRedirectionMap.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include <utils/misc.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include "android_os_Parcel.h"
+#include <binder/Parcel.h>
+
+#include <androidfw/ResourceTypes.h>
+
+#include <stdio.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static PackageRedirectionMap* PackageRedirectionMap_constructor(JNIEnv* env, jobject clazz)
+{
+ return new PackageRedirectionMap;
+}
+
+static void PackageRedirectionMap_destructor(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap)
+{
+ delete resMap;
+}
+
+static PackageRedirectionMap* PackageRedirectionMap_createFromParcel(JNIEnv* env, jobject clazz,
+ jobject parcel)
+{
+ if (parcel == NULL) {
+ return NULL;
+ }
+
+ Parcel* p = parcelForJavaObject(env, parcel);
+ PackageRedirectionMap* resMap = new PackageRedirectionMap;
+
+ int32_t entryCount = p->readInt32();
+ while (entryCount-- > 0) {
+ uint32_t fromIdent = (uint32_t)p->readInt32();
+ uint32_t toIdent = (uint32_t)p->readInt32();
+ resMap->addRedirection(fromIdent, toIdent);
+ }
+
+ return resMap;
+}
+
+static jboolean PackageRedirectionMap_writeToParcel(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap, jobject parcel)
+{
+ if (parcel == NULL) {
+ return JNI_FALSE;
+ }
+
+ Parcel* p = parcelForJavaObject(env, parcel);
+
+ int package = resMap->getPackage();
+ size_t nTypes = resMap->getNumberOfTypes();
+ size_t entryCount = 0;
+ for (size_t type=0; type<nTypes; type++) {
+ entryCount += resMap->getNumberOfUsedEntries(type);
+ }
+ p->writeInt32(entryCount);
+ for (size_t type=0; type<nTypes; type++) {
+ size_t nEntries = resMap->getNumberOfEntries(type);
+ for (size_t entry=0; entry<nEntries; entry++) {
+ uint32_t toIdent = resMap->getEntry(type, entry);
+ if (toIdent != 0) {
+ uint32_t fromIdent = Res_MAKEID(package-1, type, entry);
+ p->writeInt32(fromIdent);
+ p->writeInt32(toIdent);
+ }
+ }
+ }
+
+ return JNI_TRUE;
+}
+
+static void PackageRedirectionMap_addRedirection(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap, jint fromIdent, jint toIdent)
+{
+ resMap->addRedirection(fromIdent, toIdent);
+}
+
+static jint PackageRedirectionMap_getPackageId(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap)
+{
+ return resMap->getPackage();
+}
+
+static jint PackageRedirectionMap_lookupRedirection(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap, jint fromIdent)
+{
+ return resMap->lookupRedirection(fromIdent);
+}
+
+static jintArray PackageRedirectionMap_getRedirectionKeys(JNIEnv* env, jobject clazz,
+ PackageRedirectionMap* resMap)
+{
+ int package = resMap->getPackage();
+ size_t nTypes = resMap->getNumberOfTypes();
+ size_t entryCount = 0;
+ for (size_t type=0; type<nTypes; type++) {
+ size_t usedEntries = resMap->getNumberOfUsedEntries(type);
+ entryCount += usedEntries;
+ }
+ jintArray array = env->NewIntArray(entryCount);
+ if (array == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", "");
+ return NULL;
+ }
+ jsize index = 0;
+ for (size_t type=0; type<nTypes; type++) {
+ size_t nEntries = resMap->getNumberOfEntries(type);
+ for (size_t entry=0; entry<nEntries; entry++) {
+ uint32_t toIdent = resMap->getEntry(type, entry);
+ if (toIdent != 0) {
+ jint fromIdent = (jint)Res_MAKEID(package-1, type, entry);
+ env->SetIntArrayRegion(array, index++, 1, &fromIdent);
+ }
+ }
+ }
+ return array;
+}
+
+// ----------------------------------------------------------------------------
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gPackageRedirectionMapMethods[] = {
+ { "nativeConstructor", "()I",
+ (void*) PackageRedirectionMap_constructor },
+ { "nativeDestructor", "(I)V",
+ (void*) PackageRedirectionMap_destructor },
+ { "nativeCreateFromParcel", "(Landroid/os/Parcel;)I",
+ (void*) PackageRedirectionMap_createFromParcel },
+ { "nativeWriteToParcel", "(ILandroid/os/Parcel;)Z",
+ (void*) PackageRedirectionMap_writeToParcel },
+ { "nativeAddRedirection", "(III)V",
+ (void*) PackageRedirectionMap_addRedirection },
+ { "nativeGetPackageId", "(I)I",
+ (void*) PackageRedirectionMap_getPackageId },
+ { "nativeLookupRedirection", "(II)I",
+ (void*) PackageRedirectionMap_lookupRedirection },
+ { "nativeGetRedirectionKeys", "(I)[I",
+ (void*) PackageRedirectionMap_getRedirectionKeys },
+};
+
+int register_android_content_res_PackageRedirectionMap(JNIEnv* env)
+{
+ return AndroidRuntime::registerNativeMethods(env,
+ "android/content/res/PackageRedirectionMap",
+ gPackageRedirectionMapMethods,
+ NELEM(gPackageRedirectionMapMethods));
+}
+
+}; // namespace android
diff --git a/core/jni/com_android_internal_app_ActivityTrigger.cpp b/core/jni/com_android_internal_app_ActivityTrigger.cpp
new file mode 100644
index 0000000..93b19fa
--- /dev/null
+++ b/core/jni/com_android_internal_app_ActivityTrigger.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Code Aurora nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "ActTriggerJNI"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include <android_runtime/AndroidRuntime.h>
+
+#include <dlfcn.h>
+#include <limits.h>
+#include <string.h>
+
+#include <cutils/properties.h>
+#include <utils/Log.h>
+
+#define LIBRARY_PATH_PREFIX "/system/lib/"
+
+namespace android
+{
+
+// ----------------------------------------------------------------------------
+
+static void (*startActivity)(const char *) = NULL;
+static void (*resumeActivity)(const char *) = NULL;
+static void *dlhandle = NULL;
+
+// ----------------------------------------------------------------------------
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_init()
+{
+ const char *rc;
+ void (*init)(void);
+ char buf[PROPERTY_VALUE_MAX];
+ int len;
+
+ /* Retrieve name of vendor extension library */
+ if (property_get("ro.vendor.extension_library", buf, NULL) <= 0) {
+ return;
+ }
+
+ /* Sanity check - ensure */
+ buf[PROPERTY_VALUE_MAX-1] = '\0';
+ if ((strncmp(buf, LIBRARY_PATH_PREFIX, sizeof(LIBRARY_PATH_PREFIX) - 1) != 0)
+ ||
+ (strstr(buf, "..") != NULL)) {
+ return;
+ }
+
+ dlhandle = dlopen(buf, RTLD_NOW | RTLD_LOCAL);
+ if (dlhandle == NULL) {
+ return;
+ }
+
+ dlerror();
+
+ *(void **) (&startActivity) = dlsym(dlhandle, "activity_trigger_start");
+ if ((rc = dlerror()) != NULL) {
+ goto cleanup;
+ }
+ *(void **) (&resumeActivity) = dlsym(dlhandle, "activity_trigger_resume");
+ if ((rc = dlerror()) != NULL) {
+ goto cleanup;
+ }
+ *(void **) (&init) = dlsym(dlhandle, "activity_trigger_init");
+ if ((rc = dlerror()) != NULL) {
+ goto cleanup;
+ }
+ (*init)();
+ return;
+
+cleanup:
+ startActivity = NULL;
+ resumeActivity = NULL;
+ if (dlhandle) {
+ dlclose(dlhandle);
+ dlhandle = NULL;
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_deinit(JNIEnv *env, jobject clazz)
+{
+ void (*deinit)(void);
+
+ if (dlhandle) {
+ startActivity = NULL;
+ resumeActivity = NULL;
+
+ *(void **) (&deinit) = dlsym(dlhandle, "activity_trigger_deinit");
+ if (deinit) {
+ (*deinit)();
+ }
+
+ dlclose(dlhandle);
+ dlhandle = NULL;
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_startActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if (startActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*startActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+static void
+com_android_internal_app_ActivityTrigger_native_at_resumeActivity(JNIEnv *env, jobject clazz, jstring activity)
+{
+ if (resumeActivity && activity) {
+ const char *actStr = env->GetStringUTFChars(activity, NULL);
+ if (actStr) {
+ (*resumeActivity)(actStr);
+ env->ReleaseStringUTFChars(activity, actStr);
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+ {"native_at_startActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_startActivity},
+ {"native_at_resumeActivity", "(Ljava/lang/String;)V", (void *)com_android_internal_app_ActivityTrigger_native_at_resumeActivity},
+ {"native_at_deinit", "()V", (void *)com_android_internal_app_ActivityTrigger_native_at_deinit},
+};
+
+
+int register_com_android_internal_app_ActivityTrigger(JNIEnv *env)
+{
+ com_android_internal_app_ActivityTrigger_native_at_init();
+
+ return AndroidRuntime::registerNativeMethods(env,
+ "com/android/internal/app/ActivityTrigger", gMethods, NELEM(gMethods));
+}
+
+} // namespace android
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2a357af..373d018 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -18,6 +18,7 @@
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:pluto="http://www.w3.org/2001/pluto.html"
package="android" coreApp="true" android:sharedUserId="android.uid.system"
android:sharedUserLabel="@string/android_system_label">
@@ -140,6 +141,7 @@
<protected-broadcast android:name="android.intent.action.PROXY_CHANGE" />
<protected-broadcast android:name="android.os.UpdateLock.UPDATE_LOCK_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.NAVBAR_EDIT" />
<protected-broadcast android:name="android.intent.action.DREAMING_STARTED" />
<protected-broadcast android:name="android.intent.action.DREAMING_STOPPED" />
@@ -787,13 +789,37 @@
android:description="@string/permdesc_changeWifiMulticastState"
android:label="@string/permlab_changeWifiMulticastState" />
- <!-- Allows access to the vibrator -->
+ <!-- Allows an application to override the power key action
+ @hide -->
+ <permission android:name="android.permission.PREVENT_POWER_KEY"
+ android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
+ android:protectionLevel="signatureOrSystem"
+ android:label="@string/permlab_preventpower"
+ android:description="@string/permdesc_preventpower" />
+
+<!-- Allows access to the vibrator -->
<permission android:name="android.permission.VIBRATE"
android:permissionGroup="android.permission-group.AFFECTS_BATTERY"
android:protectionLevel="normal"
android:label="@string/permlab_vibrate"
android:description="@string/permdesc_vibrate" />
+ <!-- Allows access to the FM Radio receiver
+ @hide Pending API council approval -->
+ <permission android:name="com.stericsson.permission.FM_RADIO_RECEIVER"
+ android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
+ android:protectionLevel="normal"
+ android:label="@string/permlab_fm_radio_receiver"
+ android:description="@string/permdesc_fm_radio_receiver" />
+
+ <!-- Allows access to the FM Radio transmitter
+ @hide Pending API council approval -->
+ <permission android:name="com.stericsson.permission.FM_RADIO_TRANSMITTER"
+ android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
+ android:protectionLevel="dangerous"
+ android:label="@string/permlab_fm_radio_transmitter"
+ android:description="@string/permdesc_fm_radio_transmitter" />
+
<!-- Allows access to the flashlight -->
<permission android:name="android.permission.FLASHLIGHT"
android:permissionGroup="android.permission-group.AFFECTS_BATTERY"
@@ -2290,6 +2316,18 @@
</intent-filter>
</receiver>
+ <receiver android:name="com.android.server.AppsLaunchFailureReceiver" >
+ <intent-filter>
+ <action android:name="com.tmobile.intent.action.APP_LAUNCH_FAILURE" />
+ <action android:name="com.tmobile.intent.action.APP_LAUNCH_FAILURE_RESET" />
+ <action android:name="android.intent.action.PACKAGE_ADDED" />
+ <action android:name="android.intent.action.PACKAGE_REMOVED" />
+ <action android:name="com.tmobile.intent.action.THEME_PACKAGE_UPDATED" />
+ <category android:name="com.tmobile.intent.category.THEME_PACKAGE_INSTALL_STATE_CHANGE" />
+ <data android:scheme="package" />
+ </intent-filter>
+ </receiver>
+
<service android:name="com.android.internal.os.storage.ExternalStorageFormatter"
android:permission="android.permission.MASTER_CLEAR"
android:exported="true" />
diff --git a/core/res/res/drawable-hdpi/ic_lock_expanded_desktop.png b/core/res/res/drawable-hdpi/ic_lock_expanded_desktop.png
new file mode 100644
index 0000000..01f5b89
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_expanded_desktop.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_idle_calendar.png b/core/res/res/drawable-hdpi/ic_lock_idle_calendar.png
new file mode 100644
index 0000000..05b68b1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_idle_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_profile.png b/core/res/res/drawable-hdpi/ic_lock_profile.png
new file mode 100644
index 0000000..7fc4cec
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_profile.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_reboot.png b/core/res/res/drawable-hdpi/ic_lock_reboot.png
new file mode 100644
index 0000000..ca00936
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_reboot.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_screenshot.png b/core/res/res/drawable-hdpi/ic_lock_screenshot.png
new file mode 100644
index 0000000..5ef76f7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_screenshot.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_alarm_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_alarm_activated.png
new file mode 100644
index 0000000..7fc4e3f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_alarm_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_alarm_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_alarm_normal.png
new file mode 100644
index 0000000..af87580
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_alarm_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_answer_active.png b/core/res/res/drawable-hdpi/ic_lockscreen_answer_active.png
new file mode 100644
index 0000000..d201bfb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_answer_active.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.png
new file mode 100644
index 0000000..efb29f1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.png
new file mode 100644
index 0000000..176d448
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_browser_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_browser_activated.png
new file mode 100644
index 0000000..559af17
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_browser_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_browser_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_browser_normal.png
new file mode 100644
index 0000000..24d3398
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_browser_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_calendar_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_calendar_activated.png
new file mode 100644
index 0000000..f4972e7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_calendar_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_calendar_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_calendar_normal.png
new file mode 100644
index 0000000..9a5c37e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_calendar_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
index 19c8eb2..1e77930 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
index c79a245..c1a6047 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_chrome_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_chrome_activated.png
new file mode 100644
index 0000000..75357a0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_chrome_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_chrome_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_chrome_normal.png
new file mode 100644
index 0000000..f6f29d1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_chrome_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_decline_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_decline_activated.png
new file mode 100644
index 0000000..9866769
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_decline_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.png
new file mode 100644
index 0000000..f37b16a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.png
new file mode 100644
index 0000000..d88087b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_email2_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_email2_activated.png
new file mode 100644
index 0000000..018a7cb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_email2_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_email2_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_email2_normal.png
new file mode 100644
index 0000000..324efd4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_email2_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_email_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_email_activated.png
new file mode 100644
index 0000000..17aeaa7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_email_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_email_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_email_normal.png
new file mode 100644
index 0000000..1aaf27a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_email_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_facebook_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_facebook_activated.png
new file mode 100644
index 0000000..37b4c12
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_facebook_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_facebook_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_facebook_normal.png
new file mode 100644
index 0000000..6f967d0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_facebook_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_gallery_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_gallery_activated.png
new file mode 100644
index 0000000..013c908
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_gallery_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_gallery_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_gallery_normal.png
new file mode 100644
index 0000000..9fd4315
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_gallery_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
index 2c4847c..7c105e6 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
index 656f3ba..5daf9ed 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_small_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_small_activated.png
new file mode 100644
index 0000000..4449857
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_small_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_small_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_small_normal.png
new file mode 100644
index 0000000..44460e8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_small_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_gplus_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_gplus_activated.png
new file mode 100644
index 0000000..a526ab7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_gplus_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_gplus_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_gplus_normal.png
new file mode 100644
index 0000000..8187db4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_gplus_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_gtalk_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_gtalk_activated.png
new file mode 100644
index 0000000..eb4aa82
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_gtalk_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_gtalk_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_gtalk_normal.png
new file mode 100644
index 0000000..d86b90e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_gtalk_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
index 0bbf62f..1e2d3ca 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_maps_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_maps_activated.png
new file mode 100644
index 0000000..6e070e4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_maps_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_maps_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_maps_normal.png
new file mode 100644
index 0000000..15ea525
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_maps_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_movie_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_movie_activated.png
new file mode 100644
index 0000000..1fecc76
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_movie_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_movie_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_movie_normal.png
new file mode 100644
index 0000000..e020698
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_movie_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_music_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_music_activated.png
new file mode 100644
index 0000000..9b1f39c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_music_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_music_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_music_normal.png
new file mode 100644
index 0000000..1af9ba6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_music_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_nav_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_nav_activated.png
new file mode 100644
index 0000000..0dead7c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_nav_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_nav_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_nav_normal.png
new file mode 100644
index 0000000..8284c01
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_nav_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_phone_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_phone_activated.png
new file mode 100644
index 0000000..1a2f90c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_phone_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_phone_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_phone_normal.png
new file mode 100644
index 0000000..eade8f5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_phone_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_podcast_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_podcast_activated.png
new file mode 100644
index 0000000..c7d587c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_podcast_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_podcast_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_podcast_normal.png
new file mode 100644
index 0000000..0c0608d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_podcast_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_rss_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_rss_activated.png
new file mode 100644
index 0000000..1cf791e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_rss_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_rss_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_rss_normal.png
new file mode 100644
index 0000000..b7478dd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_rss_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_sms_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_sms_activated.png
new file mode 100644
index 0000000..2497315
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_sms_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_sms_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_sms_normal.png
new file mode 100644
index 0000000..e2c126c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_sms_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
index 0dd81c0..74c9257 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_target_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_target_activated.png
new file mode 100644
index 0000000..c5810bf
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_target_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_twitter_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_twitter_activated.png
new file mode 100644
index 0000000..42a4b27
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_twitter_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_twitter_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_twitter_normal.png
new file mode 100644
index 0000000..b716c38
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_twitter_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb.png b/core/res/res/drawable-hdpi/stat_sys_adb.png
index cfbbd8d..6c1bd0e 100644
--- a/core/res/res/drawable-hdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-hdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tether_bluetooth.png b/core/res/res/drawable-hdpi/stat_sys_tether_bluetooth.png
index 9451174..ab5208e 100644
--- a/core/res/res/drawable-hdpi/stat_sys_tether_bluetooth.png
+++ b/core/res/res/drawable-hdpi/stat_sys_tether_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tether_usb.png b/core/res/res/drawable-hdpi/stat_sys_tether_usb.png
index cae1bd1..b40f8d9 100644
--- a/core/res/res/drawable-hdpi/stat_sys_tether_usb.png
+++ b/core/res/res/drawable-hdpi/stat_sys_tether_usb.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
index 7d4df50..86c3df3 100644
--- a/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
+++ b/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_expanded_desktop.png b/core/res/res/drawable-mdpi/ic_lock_expanded_desktop.png
new file mode 100644
index 0000000..bffad73
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_expanded_desktop.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_idle_calendar.png b/core/res/res/drawable-mdpi/ic_lock_idle_calendar.png
new file mode 100644
index 0000000..2834c8f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_idle_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_profile.png b/core/res/res/drawable-mdpi/ic_lock_profile.png
new file mode 100644
index 0000000..d47ba16
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_profile.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_reboot.png b/core/res/res/drawable-mdpi/ic_lock_reboot.png
new file mode 100644
index 0000000..2b125b9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_reboot.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_screenshot.png b/core/res/res/drawable-mdpi/ic_lock_screenshot.png
new file mode 100644
index 0000000..9996e72
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_screenshot.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_alarm_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_alarm_activated.png
new file mode 100644
index 0000000..3e6bf27
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_alarm_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_alarm_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_alarm_normal.png
new file mode 100644
index 0000000..e7cd0fe
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_alarm_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_answer_active.png b/core/res/res/drawable-mdpi/ic_lockscreen_answer_active.png
new file mode 100644
index 0000000..0ad03c0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_answer_active.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_answer_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_answer_focused.png
new file mode 100644
index 0000000..f46e8bd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_answer_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_answer_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_answer_normal.png
new file mode 100644
index 0000000..ddeeb18
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_browser_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_browser_activated.png
new file mode 100644
index 0000000..53a97b9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_browser_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_browser_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_browser_normal.png
new file mode 100644
index 0000000..c9e4e2c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_browser_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_calendar_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_calendar_activated.png
new file mode 100644
index 0000000..19ec569
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_calendar_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_calendar_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_calendar_normal.png
new file mode 100644
index 0000000..d1f274c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_calendar_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
index 862f33b..69f254e 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
index 30df0a3..bc179d1 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_chrome_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_chrome_activated.png
new file mode 100644
index 0000000..52a4221e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_chrome_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_chrome_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_chrome_normal.png
new file mode 100644
index 0000000..1abda2f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_chrome_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_decline_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_decline_activated.png
new file mode 100644
index 0000000..d1aae18
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_decline_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_decline_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_decline_focused.png
new file mode 100644
index 0000000..b52c844
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_decline_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_decline_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_decline_normal.png
new file mode 100644
index 0000000..722027e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_email2_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_email2_activated.png
new file mode 100644
index 0000000..8b5c9b8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_email2_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_email2_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_email2_normal.png
new file mode 100644
index 0000000..601a6ee
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_email2_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_email_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_email_activated.png
new file mode 100644
index 0000000..e411398
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_email_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_email_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_email_normal.png
new file mode 100644
index 0000000..b44ac5f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_email_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_facebook_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_facebook_activated.png
new file mode 100644
index 0000000..db3ba33
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_facebook_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_facebook_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_facebook_normal.png
new file mode 100644
index 0000000..2753b44
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_facebook_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_gallery_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_gallery_activated.png
new file mode 100644
index 0000000..2fe369d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_gallery_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_gallery_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_gallery_normal.png
new file mode 100644
index 0000000..8342819
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_gallery_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
index 32a68e0..35a3ad5 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
index 2f7efcf..292b0ce 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_small_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_small_activated.png
new file mode 100644
index 0000000..2b903ba
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_small_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_small_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_small_normal.png
new file mode 100644
index 0000000..103d40e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_small_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_gplus_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_gplus_activated.png
new file mode 100644
index 0000000..9b0c0cc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_gplus_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_gplus_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_gplus_normal.png
new file mode 100644
index 0000000..acc280e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_gplus_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_gtalk_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_gtalk_activated.png
new file mode 100644
index 0000000..2668775
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_gtalk_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_gtalk_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_gtalk_normal.png
new file mode 100644
index 0000000..7521ee9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_gtalk_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
index aab2f6b..d9f5e04 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_maps_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_maps_activated.png
new file mode 100644
index 0000000..3368e95
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_maps_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_maps_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_maps_normal.png
new file mode 100644
index 0000000..67bc22f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_maps_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_movie_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_movie_activated.png
new file mode 100644
index 0000000..ff07877
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_movie_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_movie_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_movie_normal.png
new file mode 100644
index 0000000..2ad3588
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_movie_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_music_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_music_activated.png
new file mode 100644
index 0000000..15037f7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_music_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_music_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_music_normal.png
new file mode 100644
index 0000000..4f25712
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_music_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_nav_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_nav_activated.png
new file mode 100644
index 0000000..300e885
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_nav_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_nav_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_nav_normal.png
new file mode 100644
index 0000000..04e5bab
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_nav_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_phone_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_phone_activated.png
new file mode 100644
index 0000000..5c75455
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_phone_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_phone_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_phone_normal.png
new file mode 100644
index 0000000..04fcb46
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_phone_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_podcast_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_podcast_activated.png
new file mode 100644
index 0000000..f2a3109
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_podcast_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_podcast_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_podcast_normal.png
new file mode 100644
index 0000000..c6abe65
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_podcast_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_rss_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_rss_activated.png
new file mode 100644
index 0000000..30e69c8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_rss_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_rss_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_rss_normal.png
new file mode 100644
index 0000000..1a02883
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_rss_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_sms_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_sms_activated.png
new file mode 100644
index 0000000..b34b71e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_sms_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_sms_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_sms_normal.png
new file mode 100644
index 0000000..47d2056
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_sms_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
index eb6ceed..c82e126 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_target_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_target_activated.png
new file mode 100644
index 0000000..f2a3109
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_target_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_twitter_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_twitter_activated.png
new file mode 100644
index 0000000..b33b078
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_twitter_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_twitter_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_twitter_normal.png
new file mode 100644
index 0000000..10817f0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_twitter_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb.png b/core/res/res/drawable-mdpi/stat_sys_adb.png
index 4862919..529298b 100644
--- a/core/res/res/drawable-mdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-mdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_tether_bluetooth.png b/core/res/res/drawable-mdpi/stat_sys_tether_bluetooth.png
index f42dae0..fc620b8 100644
--- a/core/res/res/drawable-mdpi/stat_sys_tether_bluetooth.png
+++ b/core/res/res/drawable-mdpi/stat_sys_tether_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_tether_usb.png b/core/res/res/drawable-mdpi/stat_sys_tether_usb.png
index 2e2b8ca..0915809 100644
--- a/core/res/res/drawable-mdpi/stat_sys_tether_usb.png
+++ b/core/res/res/drawable-mdpi/stat_sys_tether_usb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-mdpi/stat_sys_tether_wifi.png
index 869ad35..584dc1f 100644
--- a/core/res/res/drawable-mdpi/stat_sys_tether_wifi.png
+++ b/core/res/res/drawable-mdpi/stat_sys_tether_wifi.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/cidlogo.png b/core/res/res/drawable-nodpi/cidlogo.png
new file mode 100644
index 0000000..ceb2246
--- /dev/null
+++ b/core/res/res/drawable-nodpi/cidlogo.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/cidlogo_alt.png b/core/res/res/drawable-nodpi/cidlogo_alt.png
new file mode 100644
index 0000000..e5c03ed
--- /dev/null
+++ b/core/res/res/drawable-nodpi/cidlogo_alt.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/ic_lock_expanded_desktop.png b/core/res/res/drawable-sw600dp-xhdpi/ic_lock_expanded_desktop.png
new file mode 100644
index 0000000..e0c99e5
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xhdpi/ic_lock_expanded_desktop.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lock_expanded_desktop.png b/core/res/res/drawable-xhdpi/ic_lock_expanded_desktop.png
new file mode 100644
index 0000000..e0c99e5
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lock_expanded_desktop.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lock_idle_calendar.png b/core/res/res/drawable-xhdpi/ic_lock_idle_calendar.png
new file mode 100644
index 0000000..5ae7782
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lock_idle_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lock_profile.png b/core/res/res/drawable-xhdpi/ic_lock_profile.png
new file mode 100644
index 0000000..4c9472c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lock_profile.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lock_reboot.png b/core/res/res/drawable-xhdpi/ic_lock_reboot.png
new file mode 100644
index 0000000..653970f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lock_reboot.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lock_screenshot.png b/core/res/res/drawable-xhdpi/ic_lock_screenshot.png
new file mode 100644
index 0000000..7e4c0ee
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lock_screenshot.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_alarm_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_alarm_activated.png
new file mode 100644
index 0000000..9ce624e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_alarm_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_alarm_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_alarm_normal.png
new file mode 100644
index 0000000..0744227
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_alarm_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_answer_active.png b/core/res/res/drawable-xhdpi/ic_lockscreen_answer_active.png
new file mode 100644
index 0000000..8edf62d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_answer_active.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_answer_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_answer_focused.png
new file mode 100644
index 0000000..2a47e9b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_answer_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_answer_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_answer_normal.png
new file mode 100644
index 0000000..f049dc9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_browser_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_browser_activated.png
new file mode 100644
index 0000000..a548cd5
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_browser_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_browser_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_browser_normal.png
new file mode 100644
index 0000000..cd5d76c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_browser_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_calendar_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_calendar_activated.png
new file mode 100644
index 0000000..31cc06f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_calendar_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_calendar_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_calendar_normal.png
new file mode 100644
index 0000000..d536058
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_calendar_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
index 760ef2d..1cb37f9 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
index 093bc05..b468d5a 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_chrome_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_chrome_activated.png
new file mode 100644
index 0000000..ea90ef5
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_chrome_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_chrome_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_chrome_normal.png
new file mode 100644
index 0000000..e49b962
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_chrome_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_decline_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_decline_activated.png
new file mode 100644
index 0000000..4244ca0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_decline_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_decline_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_decline_focused.png
new file mode 100644
index 0000000..a98a379
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_decline_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_decline_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_decline_normal.png
new file mode 100644
index 0000000..fa2a0f4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_email2_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_email2_activated.png
new file mode 100644
index 0000000..13d79a1
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_email2_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_email2_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_email2_normal.png
new file mode 100644
index 0000000..3f1d2ba4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_email2_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_email_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_email_activated.png
new file mode 100644
index 0000000..da7a20f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_email_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_email_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_email_normal.png
new file mode 100644
index 0000000..f27b0ef
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_email_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_facebook_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_facebook_activated.png
new file mode 100644
index 0000000..583bb51
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_facebook_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_facebook_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_facebook_normal.png
new file mode 100644
index 0000000..1cca26c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_facebook_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_gallery_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_gallery_activated.png
new file mode 100644
index 0000000..91acdd6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_gallery_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_gallery_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_gallery_normal.png
new file mode 100644
index 0000000..cdb947b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_gallery_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
index d643f83..de9eec8 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
index 9a9bf68..f45db74 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_small_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_small_activated.png
new file mode 100644
index 0000000..08ca942
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_small_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_small_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_small_normal.png
new file mode 100644
index 0000000..75deb64
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_small_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_gplus_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_gplus_activated.png
new file mode 100644
index 0000000..3c04e0d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_gplus_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_gplus_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_gplus_normal.png
new file mode 100644
index 0000000..9ec36bf
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_gplus_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_activated.png
new file mode 100644
index 0000000..63ed20b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_normal.png
new file mode 100644
index 0000000..a1f0c81
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_gtalk_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
index 2264dc3..fb1af78 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_maps_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_maps_activated.png
new file mode 100644
index 0000000..bed705f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_maps_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_maps_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_maps_normal.png
new file mode 100644
index 0000000..65f0a1f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_maps_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_movie_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_movie_activated.png
new file mode 100644
index 0000000..ea8dc6a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_movie_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_movie_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_movie_normal.png
new file mode 100644
index 0000000..3493895
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_movie_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_music_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_music_activated.png
new file mode 100644
index 0000000..dd3634b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_music_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_music_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_music_normal.png
new file mode 100644
index 0000000..781f8c7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_music_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_nav_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_nav_activated.png
new file mode 100644
index 0000000..aa2ff3d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_nav_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_nav_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_nav_normal.png
new file mode 100644
index 0000000..f0802c8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_nav_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_phone_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_phone_activated.png
new file mode 100644
index 0000000..8365b44
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_phone_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_phone_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_phone_normal.png
new file mode 100644
index 0000000..8eac860
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_phone_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_podcast_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_podcast_activated.png
new file mode 100644
index 0000000..fa0ae47
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_podcast_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_podcast_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_podcast_normal.png
new file mode 100644
index 0000000..dd7f470
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_podcast_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_rss_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_rss_activated.png
new file mode 100644
index 0000000..4d0a020
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_rss_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_rss_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_rss_normal.png
new file mode 100644
index 0000000..7d32abf
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_rss_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_sms_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_sms_activated.png
new file mode 100644
index 0000000..efec4bc
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_sms_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_sms_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_sms_normal.png
new file mode 100644
index 0000000..302344d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_sms_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
index 6af5375..01ad781 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_target_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_target_activated.png
new file mode 100644
index 0000000..6f84ff2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_target_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_twitter_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_twitter_activated.png
new file mode 100644
index 0000000..b8da994
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_twitter_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_twitter_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_twitter_normal.png
new file mode 100644
index 0000000..b084153
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_twitter_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_adb.png b/core/res/res/drawable-xhdpi/stat_sys_adb.png
index 576ae24..2f4d755 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_tether_bluetooth.png b/core/res/res/drawable-xhdpi/stat_sys_tether_bluetooth.png
index 3f57d1c..16c0d2d 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_tether_bluetooth.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_tether_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_tether_usb.png b/core/res/res/drawable-xhdpi/stat_sys_tether_usb.png
index 36afe48..633b181 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_tether_usb.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_tether_usb.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-xhdpi/stat_sys_tether_wifi.png
index dc48646..d381c20 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_tether_wifi.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_tether_wifi.png
Binary files differ
diff --git a/core/res/res/drawable/progress_large.xml b/core/res/res/drawable/progress_large.xml
index 4f016bc..44b4103 100644
--- a/core/res/res/drawable/progress_large.xml
+++ b/core/res/res/drawable/progress_large.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_76"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_large_white.xml b/core/res/res/drawable/progress_large_white.xml
index c690ed4..6c2388c 100644
--- a/core/res/res/drawable/progress_large_white.xml
+++ b/core/res/res/drawable/progress_large_white.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_76"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_medium.xml b/core/res/res/drawable/progress_medium.xml
index eb1bd50..82ad686 100644
--- a/core/res/res/drawable/progress_medium.xml
+++ b/core/res/res/drawable/progress_medium.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_48"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_medium_white.xml b/core/res/res/drawable/progress_medium_white.xml
index b4f9b31..886ee05 100644
--- a/core/res/res/drawable/progress_medium_white.xml
+++ b/core/res/res/drawable/progress_medium_white.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_48"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_small.xml b/core/res/res/drawable/progress_small.xml
index e0ee5e4..1881da3 100644
--- a/core/res/res/drawable/progress_small.xml
+++ b/core/res/res/drawable/progress_small.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_16"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_small_titlebar.xml b/core/res/res/drawable/progress_small_titlebar.xml
index 8cfba86..5bb5cf8 100644
--- a/core/res/res/drawable/progress_small_titlebar.xml
+++ b/core/res/res/drawable/progress_small_titlebar.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_16"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_small_white.xml b/core/res/res/drawable/progress_small_white.xml
index 8cfba86..5bb5cf8 100644
--- a/core/res/res/drawable/progress_small_white.xml
+++ b/core/res/res/drawable/progress_small_white.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_16"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/search_spinner.xml b/core/res/res/drawable/search_spinner.xml
index 31a77c3..b8c8b09 100644
--- a/core/res/res/drawable/search_spinner.xml
+++ b/core/res/res/drawable/search_spinner.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_20"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index fb25f9c..6dedc1f 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -64,7 +64,7 @@
android:id="@+id/keyguard_security_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_maxHeight="@dimen/keyguard_security_height"
+ android:layout_maxHeight="@dimen/keyguard_security_no_widget_height"
androidprv:layout_childType="challenge"
android:padding="0dp"
android:gravity="bottom|center_horizontal">
@@ -80,6 +80,7 @@
</com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
<ImageButton
+ android:id="@+id/expand_challenge_handle"
android:layout_width="match_parent"
android:layout_height="@dimen/kg_widget_pager_bottom_padding"
androidprv:layout_childType="expandChallengeHandle"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_status_land.xml b/core/res/res/layout-sw600dp/keyguard_screen_status_land.xml
index c6ddd1b..e6c3f96 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_status_land.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_status_land.xml
@@ -2,6 +2,7 @@
<!--
**
** Copyright 2010, The Android Open Source Project
+** Copyright 2012, The CyanogenMod Project (Weather, Calendar)
**
** Licensed under the Apache License, Version 2.0 (the "License")
** you may not use this file except in compliance with the License.
@@ -41,9 +42,7 @@
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dip"
- android:layout_marginBottom="8dip"
- >
+ android:layout_marginBottom="8dip" >
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
@@ -120,4 +119,5 @@
android:textColor="@color/lockscreen_owner_info"
android:visibility="invisible"
/>
+
</LinearLayout>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_status_port.xml b/core/res/res/layout-sw600dp/keyguard_screen_status_port.xml
index 765dc95..e022a9e 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_status_port.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_status_port.xml
@@ -2,6 +2,7 @@
<!--
**
** Copyright 2010, The Android Open Source Project
+** Copyright 2012, The CyanogenMod Project (Weather, Calendar)
**
** Licensed under the Apache License, Version 2.0 (the "License")
** you may not use this file except in compliance with the License.
@@ -43,8 +44,7 @@
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dip"
- android:layout_marginBottom="8dip">
+ android:layout_marginBottom="8dip" >
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
@@ -120,4 +120,5 @@
android:visibility="invisible"
android:textColor="@color/lockscreen_owner_info"
/>
+
</LinearLayout>
diff --git a/core/res/res/layout/keyguard_glow_pad_view.xml b/core/res/res/layout/keyguard_glow_pad_view.xml
index cfd8160..8ca97ff 100644
--- a/core/res/res/layout/keyguard_glow_pad_view.xml
+++ b/core/res/res/layout/keyguard_glow_pad_view.xml
@@ -38,7 +38,7 @@
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset"
- prvandroid:magneticTargets="true"
+ prvandroid:magneticTargets="false"
prvandroid:feedbackCount="1"
prvandroid:vibrationDuration="20"
prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index 54381ee..b897c3f 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -2,6 +2,7 @@
<!--
**
** Copyright 2009, The Android Open Source Project
+** Copyright 2012, The CyanogenMod Project (Weather, Calendar)
**
** Licensed under the Apache License, Version 2.0 (the "License")
** you may not use this file except in compliance with the License.
@@ -26,6 +27,7 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:id="@+id/root"
android:gravity="center_horizontal">
<com.android.internal.widget.DigitalClock android:id="@+id/time"
@@ -189,7 +191,7 @@
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
- android:layout_rowSpan="4"
+ android:layout_rowSpan="5"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 7ef9d8b..e6a55b5 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -30,8 +30,9 @@
<!-- Column 0 -->
<com.android.internal.widget.DigitalClock android:id="@+id/time"
- android:layout_marginTop="80dip"
+ android:layout_marginTop="40dip"
android:layout_marginBottom="8dip"
+ android:layout_columnSpan="3"
android:layout_gravity="end">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
@@ -64,7 +65,7 @@
<TextView
android:id="@+id/date"
- android:layout_width="0dip"
+ android:layout_columnSpan="3"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:layout_marginTop="6dip"
@@ -76,6 +77,7 @@
<TextView
android:id="@+id/alarm_status"
+ android:layout_columnSpan="3"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
@@ -87,7 +89,7 @@
<TextView
android:id="@+id/status1"
- android:layout_width="0dip"
+ android:layout_columnSpan="3"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:layout_marginTop="4dip"
@@ -102,7 +104,7 @@
<TextView
android:id="@+id/carrier"
- android:layout_width="0dip"
+ android:layout_columnSpan="3"
android:layout_gravity="fill_horizontal"
android:layout_marginBottom="12dip"
android:gravity="end"
@@ -131,7 +133,7 @@
<!-- Column 2 -->
<com.android.internal.widget.multiwaveview.GlowPadView
android:id="@+id/unlock_widget"
- android:layout_width="302dip"
+ android:layout_width="200dip"
android:layout_height="match_parent"
android:layout_rowSpan="7"
android:gravity="start|center_vertical"
@@ -157,7 +159,7 @@
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="5"
- android:layout_columnSpan="1"
+ android:layout_columnSpan="3"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml
index 6e6fe08..a780206 100644
--- a/core/res/res/layout/keyguard_sim_pin_view.xml
+++ b/core/res/res/layout/keyguard_sim_pin_view.xml
@@ -25,7 +25,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_maxWidth="@dimen/keyguard_security_width"
- android:layout_maxHeight="@dimen/keyguard_security_height"
+ android:layout_maxHeight="@dimen/keyguard_security_no_widget_height"
android:gravity="center_horizontal">
<ImageView
diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml
index 0412fdc..75fc89e 100644
--- a/core/res/res/layout/keyguard_sim_puk_view.xml
+++ b/core/res/res/layout/keyguard_sim_puk_view.xml
@@ -26,7 +26,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_maxWidth="@dimen/keyguard_security_width"
- android:layout_maxHeight="@dimen/keyguard_security_height"
+ android:layout_maxHeight="@dimen/keyguard_security_no_widget_height"
android:gravity="center_horizontal">
<ImageView
diff --git a/core/res/res/values-ar-rEG/donottranslate-cldr.xml b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
index 155480d..c95e71f 100644
--- a/core/res/res/values-ar-rEG/donottranslate-cldr.xml
+++ b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE، d MMMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-ar/donottranslate-cldr.xml b/core/res/res/values-ar/donottranslate-cldr.xml
index 135963b..96e13c4 100644
--- a/core/res/res/values-ar/donottranslate-cldr.xml
+++ b/core/res/res/values-ar/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E d MMMM</string>
<string name="abbrev_wday_month_day_no_year">E d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE، d MMMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-bg/donottranslate-cldr.xml b/core/res/res/values-bg/donottranslate-cldr.xml
index 9c1ae2c..6b8275c 100644
--- a/core/res/res/values-bg/donottranslate-cldr.xml
+++ b/core/res/res/values-bg/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">d MMMM, EEEE</string>
<string name="abbrev_wday_month_day_no_year">d MMMM, EEE</string>
<string name="abbrev_wday_month_day_year">d MMM yyyy, E</string>
+ <string name="full_wday_month_day_no_year_split">d MMMM\nEEEE</string>
</resources>
diff --git a/core/res/res/values-ca/donottranslate-cldr.xml b/core/res/res/values-ca/donottranslate-cldr.xml
index 84e7e79..258f06b 100644
--- a/core/res/res/values-ca/donottranslate-cldr.xml
+++ b/core/res/res/values-ca/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-cs/donottranslate-cldr.xml b/core/res/res/values-cs/donottranslate-cldr.xml
index ff7902d..ce5691a 100644
--- a/core/res/res/values-cs/donottranslate-cldr.xml
+++ b/core/res/res/values-cs/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string>
<string name="abbrev_wday_month_day_year">E d. MMMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f361a42..a8c35a7 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/* //device/apps/common/assets/res/any/strings.xml
**
@@ -27,22 +27,39 @@
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+
<string name="untitled" msgid="4638956954852782576">"&lt;Bez názvu&gt;"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
+ <string name="ellipsis" msgid="7899829516048813237">"\u2026"</string>
+ <string name="ellipsis_two_dots" msgid="1228078994866030736">"\u2025"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(žádné telefonní číslo)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Neznámé)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Hlasová schránka"</string>
<string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+
<string name="mmiError" msgid="5154499457739052907">"Problém s připojením nebo neplatný kód MMI."</string>
<string name="mmiFdnError" msgid="5224398216385316471">"Operace je omezena pouze na povolená telefonní čísla."</string>
+
+ <string name="profileNameDefault">Výchozí</string>
+ <string name="profileNameWork">Práce</string>
+ <string name="profileNameHome">Doma</string>
+ <string name="profileNameSilent">Tichý</string>
+ <string name="profileNameNight">Noc</string>
+
+ <string name="profileGroupPhone">Telefon</string>
+ <string name="profileGroupCalendar">Kalendář</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">E-mail</string>
+ <string name="profileGroupSMS">SMS</string>
+
+ <string name="wildcardProfile">Ostatní</string>
+
<string name="serviceEnabled" msgid="8147278346414714315">"Služba byla zapnuta."</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"Služba byla zapnuta pro:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"Služba byla vypnuta."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"Registrace byla úspěšná."</string>
<string name="serviceErased" msgid="1288584695297200972">"Smazaní proběhlo úspěšně."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Nesprávné heslo."</string>
- <string name="mmiComplete" msgid="8232527495411698359">"Funkce MMI byla dokončena."</string>
+ <string name="mmiComplete" msgid="8232527495411698359">"Požadavek MMI dokončen."</string>
<string name="badPin" msgid="9015277645546710014">"Původní kód PIN byl zadán nesprávně."</string>
<string name="badPuk" msgid="5487257647081132201">"Kód PUK byl zadán nesprávně."</string>
<string name="mismatchPin" msgid="609379054496863419">"Zadané kódy PIN se neshodují."</string>
@@ -50,8 +67,10 @@
<string name="invalidPuk" msgid="8761456210898036513">"Zadejte osmimístný nebo delší kód PUK."</string>
<string name="needPuk" msgid="919668385956251611">"SIM karta je blokována pomocí kódu PUK. Odblokujete ji zadáním kódu PUK."</string>
<string name="needPuk2" msgid="4526033371987193070">"Chcete-li odblokovat SIM kartu, zadejte kód PUK2."</string>
+
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
+
<string name="ClipMmi" msgid="6952821216480289285">"Příchozí identifikace volajícího"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Odchozí identifikace volajícího"</string>
<string name="CfMmi" msgid="5123218989141573515">"Přesměrování hovorů"</string>
@@ -65,12 +84,14 @@
<string name="RuacMmi" msgid="7827887459138308886">"Odmítnutí nevyžádaných obtěžujících hovorů"</string>
<string name="CndMmi" msgid="3116446237081575808">"Doručení volaného čísla"</string>
<string name="DndMmi" msgid="1265478932418334331">"Nerušit"</string>
+
<string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Ve výchozím nastavení je identifikace volajícího omezena. Příští hovor: Omezeno"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Ve výchozím nastavení je identifikace volajícího omezena. Příští hovor: Neomezeno"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Ve výchozím nastavení není identifikace volajícího omezena. Příští hovor: Omezeno"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Ve výchozím nastavení není identifikace volajícího omezena. Příští hovor: Neomezeno"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Služba není zřízena."</string>
- <string name="CLIRPermanent" msgid="3377371145926835671">"Nastavení identifikace volajícího nesmíte měnit."</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"Nelze změnit nastavení identifikace volajícího."</string>
+
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"Omezený přístup byl změněn."</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"Datová služba je zablokována."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Tísňová linka je zablokována."</string>
@@ -79,7 +100,8 @@
<string name="RestrictedOnSms" msgid="8314352327461638897">"Služby SMS jsou zablokovány."</string>
<string name="RestrictedOnVoiceData" msgid="996636487106171320">"Hlasové a datové služby jsou zablokovány."</string>
<string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Hlasové služby a služby SMS jsou zablokovány."</string>
- <string name="RestrictedOnAll" msgid="5643028264466092821">"Veškeré hlasové a datové služby a služby SMS jsou zablokovány."</string>
+ <string name="RestrictedOnAll" msgid="5643028264466092821">"Veškeré hlasové, datové a SMS služby jsou zablokovány."</string>
+
<string name="serviceClassVoice" msgid="1258393812335258019">"Hlas"</string>
<string name="serviceClassData" msgid="872456782077937893">"Data"</string>
<string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string>
@@ -88,6 +110,7 @@
<string name="serviceClassDataSync" msgid="7530000519646054776">"Synchronizace"</string>
<string name="serviceClassPacket" msgid="6991006557993423453">"Pakety"</string>
<string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+
<string name="roamingText0" msgid="7170335472198694945">"Indikátor roamingu svítí"</string>
<string name="roamingText1" msgid="5314861519752538922">"Indikátor roamingu nesvítí"</string>
<string name="roamingText2" msgid="8969929049081268115">"Indikátor roamingu bliká"</string>
@@ -102,13 +125,16 @@
<string name="roamingText11" msgid="4154476854426920970">"Banner roamingu je zapnutý"</string>
<string name="roamingText12" msgid="1189071119992726320">"Banner roamingu je vypnutý"</string>
<string name="roamingTextSearching" msgid="8360141885972279963">"Vyhledávání služby"</string>
+
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nepřesměrováno"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> po <xliff:g id="TIME_DELAY">{2}</xliff:g> sek."</string>
<string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nepřesměrováno"</string>
<string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nepřesměrováno"</string>
+
<string name="fcComplete" msgid="3118848230966886575">"Požadavek zadaný pomocí kódu funkce byl úspěšně dokončen."</string>
<string name="fcError" msgid="3327560126588500777">"Problém s připojením nebo neplatný kód funkce."</string>
+
<string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
<string name="httpError" msgid="7956392511146698522">"Došlo k chybě sítě."</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"Adresu URL nelze najít."</string>
@@ -122,16 +148,20 @@
<string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokol není podporován."</string>
<string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Nelze navázat bezpečné připojení."</string>
<string name="httpErrorBadUrl" msgid="3636929722728881972">"Stránku nelze otevřít. Adresa URL je neplatná."</string>
- <string name="httpErrorFile" msgid="2170788515052558676">"Do souboru nelze získat přístup."</string>
+ <string name="httpErrorFile" msgid="2170788515052558676">"K souboru nelze získat přístup."</string>
<string name="httpErrorFileNotFound" msgid="6203856612042655084">"Požadovaný soubor nelze najít."</string>
- <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Je zpracováváno příliš mnoho požadavků. Opakujte akci později."</string>
+ <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Je požadováno zpracovat příliš mnoho požadavků. Opakujte akci později."</string>
+
<string name="notification_title" msgid="8967710025036163822">"Chyba přihlášení k účtu <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="8353523060269335667">"Synchronizace"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronizace"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Příliš mnoho smazaných položek služby <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+
<string name="low_memory" product="tablet" msgid="6494019234102154896">"Úložiště tabletu je plné. Uvolněte místo smazáním některých souborů."</string>
- <string name="low_memory" product="default" msgid="3475999286680000541">"Paměť telefonu je plná. Uvolněte místo smazáním některých souborů."</string>
+ <string name="low_memory" product="default" msgid="3475999286680000541">"Úložiště telefonu je plné. Uvolněte místo smazáním některých souborů."</string>
+
<string name="me" msgid="6545696007631404292">"Já"</string>
+
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Možnosti tabletu"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Možnosti telefonu"</string>
<string name="silent_mode" msgid="7167703389802618663">"Tichý režim"</string>
@@ -139,15 +169,34 @@
<string name="turn_off_radio" msgid="8198784949987062346">"Vypnout bezdrátové připojení"</string>
<string name="screen_lock" msgid="799094655496098153">"Zámek obrazovky"</string>
<string name="power_off" msgid="4266614107412865048">"Vypnout"</string>
+
+ <string name="reboot_system" product="tablet">Restartovat tablet</string>
+ <string name="reboot_system" product="default">Restartovat telefon</string>
+
+ <string name="global_action_screenshot">Snímek obrazovky</string>
+
+ <string name="global_actions_toggle_expanded_desktop_mode">Rozšířená plocha</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Zapnuto</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Vypnuto</string>
+
+ <!-- Reboot option dialog is intentionally untranslated -->
+
+ <string name="reboot_progress">Restart\u2026</string>
+ <string name="reboot_confirm" product="tablet">Tablet bude restartován.</string>
+ <string name="reboot_confirm" product="default">Telefon bude restartován.</string>
+
<string name="silent_mode_silent" msgid="319298163018473078">"Vyzvánění vypnuto"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Vibrační vyzvánění"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Vyzvánění zapnuto"</string>
- <string name="shutdown_progress" msgid="2281079257329981203">"Vypínání..."</string>
- <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet se vypne."</string>
- <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Váš telefon bude vypnut."</string>
+
+ <string name="shutdown_progress" msgid="2281079257329981203">"Vypínání\u2026"</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet bude vypnut."</string>
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon bude vypnut."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Chcete zařízení vypnout?"</string>
- <string name="reboot_safemode_title" msgid="7054509914500140361">"Restart v nouzovém režimu"</string>
- <string name="reboot_safemode_confirm" msgid="55293944502784668">"Chcete zařízení restartovat v nouzovém režimu? Deaktivujete tak veškeré nainstalované aplikace třetích stran. Po dalším restartu budou obnoveny."</string>
+
+ <string name="reboot_safemode_title" msgid="7054509914500140361">"Restart do nouzového režimu"</string>
+ <string name="reboot_safemode_confirm" msgid="55293944502784668">"Chcete zařízení restartovat do nouzovém režimu? Deaktivujete tak veškeré nainstalované aplikace třetích stran. Po dalším restartu budou obnoveny."</string>
+
<string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Žádné nové aplikace"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Možnosti tabletu"</string>
@@ -155,456 +204,464 @@
<string name="global_action_lock" msgid="2844945191792119712">"Zámek obrazovky"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Vypnout"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Hlášení chyb"</string>
+
<string name="bugreport_title" msgid="2667494803742548533">"Zaznamenat zprávu o chybě"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Shromažďuje informace o aktuálním stavu zařízení. Tyto informace je následně možné poslat v e-mailové zprávě, chvíli však potrvá, než bude hlášení o chybě připraveno k odeslání. Buďte prosím trpěliví."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Shromažďují se informace o aktuálním stavu zařízení. Tyto informace je následně možné poslat v e-mailové zprávě, chvíli však potrvá, než bude hlášení o chybě připraveno k odeslání. Buďte prosím trpěliví."</string>
+
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tichý režim"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je VYPNUTÝ."</string>
- <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je zapnutý"</string>
+ <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je ZAPNUTÝ"</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Režim V letadle"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim V letadle je ZAPNUTÝ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim V letadle je VYPNUTÝ"</string>
+
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
+
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Zpoplatněné služby"</string>
- <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Provádět činnosti, které vás mohou stát peníze."</string>
+ <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Umožňí provádět činnosti, které mohou být zpoplatněny."</string>
<string name="permgrouplab_messages" msgid="7521249148445456662">"Vaše zprávy"</string>
- <string name="permgroupdesc_messages" msgid="7821999071003699236">"Čtení a zápis zpráv SMS, e-mailů a dalších zpráv."</string>
+ <string name="permgroupdesc_messages" msgid="7821999071003699236">"Umožňí číst a psát zprávy SMS, e-maily a další."</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Vaše osobní informace"</string>
- <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Přímý přístup k informacím o vás uložených na vaší vizitce"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informace o vašich kontaktech a sociálních sítích"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Přímý přístup k informacím o vašich kontaktech a sociálních propojeních"</string>
- <string name="permgrouplab_location" msgid="635149742436692049">"Vaše poloha"</string>
- <string name="permgroupdesc_location" msgid="5704679763124170100">"Sledovat vaši fyzickou polohu."</string>
+ <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Umožní přímý přístup k informacím o vás uložených v kontaktech"</string>
+ <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informace o kontaktech a sociálních sítích"</string>
+ <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Umožní přímý přístup k informacím o kontaktech a sociálních propojeních"</string>
+ <string name="permgrouplab_location" msgid="635149742436692049">"Poloha"</string>
+ <string name="permgroupdesc_location" msgid="5704679763124170100">"Umožní sledovat fyzickou polohu."</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"Síťová komunikace"</string>
- <string name="permgroupdesc_network" msgid="4478299413241861987">"Přístup k různým funkcím sítě."</string>
+ <string name="permgroupdesc_network" msgid="4478299413241861987">"Umožní přístup k různým funkcím sítě."</string>
<string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
- <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Přístup do zařízení a k sítím prostřednictvím rozhraní Bluetooth."</string>
+ <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Umožní přístup využívat rozhraní Bluetooth."</string>
<string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Nastavení zvuku"</string>
- <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Změna nastavení zvuku"</string>
+ <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Umožní změnit nastavení zvuku"</string>
<string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Vliv na baterii"</string>
- <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Používání funkcí, které mohou rychle vyčerpat baterii"</string>
+ <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Umožní používání funkcí, které mohou rychle vyčerpat baterii"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendář"</string>
- <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Přímý přístup ke kalendáři a událostem"</string>
+ <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Umožní přímý přístup ke kalendáři a událostem"</string>
<string name="permgrouplab_dictionary" msgid="4148597128843641379">"Čtení uživatelského slovníku"</string>
- <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Čtení slov v uživatelském slovníku."</string>
+ <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Umožní čtení slov v uživatelském slovníku."</string>
<string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Zápis do uživatelského slovníku"</string>
- <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Přidávání slov do uživatelského slovníku."</string>
+ <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Umožní přidávání slov do uživatelského slovníku."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Záložky a historie"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Přímý přístup k záložkám a historii prohlížení"</string>
+ <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Umožní přímý přístup k záložkám a historii prohlížení"</string>
<string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Budík"</string>
- <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Nastavení budíku"</string>
+ <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Umožní změnit nastavení budíku"</string>
<string name="permgrouplab_voicemail" msgid="4162237145027592133">"Hlasová schránka"</string>
- <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Přímý přístup do hlasové schránky"</string>
+ <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Umožní přímý přístup do hlasové schránky"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Přímý přístup k mikrofonu a možnost nahrávání zvuku"</string>
+ <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Umožní přímý přístup k mikrofonu a možnost nahrávání zvuku"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
- <string name="permgroupdesc_camera" msgid="2933667372289567714">"Přímý přístup k fotoaparátu a možnost pořizování fotografií a videí"</string>
+ <string name="permgroupdesc_camera" msgid="2933667372289567714">"Umožní přístup k fotoaparátu a možnost pořizování fotografií a videa"</string>
<string name="permgrouplab_appInfo" msgid="8028789762634147725">"Informace o vašich aplikacích"</string>
- <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Možnost ovlivnit chování dalších aplikací v zařízení"</string>
+ <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Umožní ovlivnit chování dalších aplikací v zařízení"</string>
<string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Tapeta"</string>
- <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Změna nastavení tapety zařízení"</string>
+ <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Umožnéí změnit nastavení tapety zařízení"</string>
<string name="permgrouplab_systemClock" msgid="406535759236612992">"Hodiny"</string>
- <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Změna času nebo časového pásma zařízení"</string>
+ <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Umožní změnit čas nebo časové pásmo zařízení"</string>
<string name="permgrouplab_statusBar" msgid="2095862568113945398">"Stavový řádek"</string>
- <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Změna nastavení stavového řádku zařízení"</string>
+ <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Umožní změnit nastavení stavového řádku zařízení"</string>
<string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Synchronizace"</string>
- <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Přístup k nastavení synchronizace"</string>
+ <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Umožní měnit nastavení synchronizace"</string>
<string name="permgrouplab_accounts" msgid="3359646291125325519">"Vaše účty"</string>
- <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Přístup k dostupným účtům."</string>
+ <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Umožní přístup k dostupným účtům."</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Řízení hardwaru"</string>
- <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Přímý přístup k hardwaru telefonu."</string>
+ <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Umožní přímý přístup k hardwaru telefonu."</string>
<string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonní hovory"</string>
- <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Sledování, záznam a zpracování telefonních hovorů."</string>
+ <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Umožní sledování, záznamenávat a zpracovávat telefonní hovory."</string>
<string name="permgrouplab_systemTools" msgid="4652191644082714048">"Systémové nástroje"</string>
- <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Nízkoúrovňový přístup a kontrola nad systémem."</string>
+ <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Umožní nízkoúrovňový přístup a kontrolu nad systémem."</string>
<string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Nástroje pro vývojáře"</string>
<string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Funkce pouze pro vývojáře aplikací."</string>
<string name="permgrouplab_display" msgid="4279909676036402636">"Uživatelské rozhraní dalších aplikací"</string>
- <string name="permgroupdesc_display" msgid="6051002031933013714">"Vliv na uživatelské rozhraní dalších aplikací"</string>
+ <string name="permgroupdesc_display" msgid="6051002031933013714">"Umožní ovlivňovat uživatelské rozhraní dalších aplikací"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Úložiště"</string>
- <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Přístup do úložiště USB."</string>
- <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Přístup ke kartě SD."</string>
+ <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Umožní přístup do úložiště USB."</string>
+ <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Umožní přístup ke kartě SD."</string>
+
<string name="permlab_statusBar" msgid="7417192629601890791">"zakázání či změny stavového řádku"</string>
- <string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje aplikaci zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string>
+ <string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string>
<string name="permlab_statusBarService" msgid="7247281911387931485">"stavový řádek"</string>
- <string name="permdesc_statusBarService" msgid="716113660795976060">"Umožňuje aplikaci být stavovým řádkem."</string>
+ <string name="permdesc_statusBarService" msgid="716113660795976060">"Umožňuje být stavovým řádkem."</string>
<string name="permlab_expandStatusBar" msgid="1148198785937489264">"rozbalení a sbalení stavového řádku"</string>
- <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Umožňuje aplikaci rozbalit či sbalit stavový řádek."</string>
+ <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Umožňuje rozbalit či sbalit stavový řádek."</string>
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"přesměrování odchozích hovorů"</string>
- <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Umožňuje aplikaci zpracovávat odchozí hovory a měnit vytáčené číslo. Toto oprávnění umožňuje sledovat či přesměrovat odchozí hovory nebo jim zabránit."</string>
+ <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Umožňuje zpracovávat odchozí hovory a měnit vytáčené číslo. Toto oprávnění umožňuje sledovat či přesměrovat odchozí hovory nebo jim zabránit."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"příjem textových zpráv (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"Umožňuje aplikaci přijmout a zpracovat zprávy SMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Umožňuje přijmout a zpracovat zprávy SMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"příjem textových zpráv (MMS)"</string>
- <string name="permdesc_receiveMms" msgid="533019437263212260">"Umožňuje aplikaci přijmout a zpracovat zprávy MMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Umožňuje přijmout a zpracovat zprávy MMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"příjem nouzového vysílání"</string>
- <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Umožňuje aplikaci přijmout a zpracovat zprávy tísňového vysílání. Toto oprávnění je dostupné pouze pro systémové aplikace."</string>
+ <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Umožňuje přijmout a zpracovat zprávy tísňového vysílání. Toto oprávnění je dostupné pouze pro systémové aplikace."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čtení zpráv informační služby"</string>
- <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje aplikaci číst zprávy informační služby přijaté ve vašem zařízení. Upozornění informační služby jsou v některých oblastech odesílána za účelem varování před mimořádnými událostmi. Škodlivé aplikace mohou narušit výkon či provoz vašeho zařízení během přijímání zpráv informační služby."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje číst zprávy informační služby přijaté ve vašem zařízení. Upozornění informační služby jsou v některých oblastech odesílána za účelem varování před mimořádnými událostmi. Škodlivé aplikace mohou narušit výkon či provoz vašeho zařízení během přijímání zpráv informační služby."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"odesílaní zpráv SMS"</string>
- <string name="permdesc_sendSms" msgid="7094729298204937667">"Umožňuje aplikaci odesílat zprávy SMS. Může to mít za následek účtování neočekávaných poplatků. Škodlivé aplikace vás mohou připravit o peníze odesíláním zpráv bez vašeho svolení."</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"Umožňuje odesílat zprávy SMS. Může to mít za následek účtování neočekávaných poplatků. Škodlivé aplikace vás mohou připravit o peníze odesíláním zpráv bez vašeho svolení."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"posílat zprávy SMS bez potvrzení"</string>
- <string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Umožňuje aplikaci odesílat zprávy SMS. Může to mít za následek účtování neočekávaných poplatků. Škodlivé aplikace vás mohou připravit o peníze odesíláním zpráv bez vašeho svolení."</string>
+ <string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Umožňuje odesílat zprávy SMS. Může to mít za následek účtování neočekávaných poplatků. Škodlivé aplikace vás mohou připravit o peníze odesíláním zpráv bez vašeho svolení."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"čtení textových zpráv (SMS nebo MMS)"</string>
- <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Umožňuje aplikaci číst zprávy SMS uložené v tabletu nebo na SIM kartě.Toto oprávnění umožňuje aplikaci číst zprávy SMS bez ohledu na jejich obsah nebo důvěrnost."</string>
- <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Umožňuje aplikaci číst zprávy SMS uložené v telefonu nebo na SIM kartě. Toto oprávnění umožňuje aplikaci číst zprávy SMS bez ohledu na jejich obsah nebo důvěrnost."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Umožňuje číst zprávy SMS uložené v tabletu nebo na SIM kartě.Toto oprávnění umožňuje aplikaci číst zprávy SMS bez ohledu na jejich obsah nebo důvěrnost."</string>
+ <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Umožňuje číst zprávy SMS uložené v telefonu nebo na SIM kartě. Toto oprávnění umožňuje aplikaci číst zprávy SMS bez ohledu na jejich obsah nebo důvěrnost."</string>
<string name="permlab_writeSms" msgid="3216950472636214774">"úprava textových zpráv (SMS nebo MMS)"</string>
- <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Umožňuje aplikaci zapisování do zpráv SMS uložených v tabletu nebo na SIM kartě. Škodlivé aplikace mohou vaše zprávy smazat."</string>
- <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Umožňuje aplikaci zapisování do zpráv SMS uložených v telefonu nebo na SIM kartě. Škodlivé aplikace mohou vaše zprávy smazat."</string>
+ <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Umožňuje zapisování do zpráv SMS uložených v tabletu nebo na SIM kartě. Škodlivé aplikace mohou vaše zprávy smazat."</string>
+ <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Umožňuje zapisování do zpráv SMS uložených v telefonu nebo na SIM kartě. Škodlivé aplikace mohou vaše zprávy smazat."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"příjem textových zpráv (WAP)"</string>
- <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Umožňuje aplikaci přijmout a zpracovat zprávy WAP. Toto oprávnění umožňuje sledovat přijaté zprávy nebo je smazat, aniž by se vám zobrazily."</string>
+ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Umožňuje přijmout a zpracovat zprávy WAP. Toto oprávnění umožňuje sledovat přijaté zprávy nebo je smazat, aniž by se vám zobrazily."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"načtení spuštěných aplikací"</string>
- <string name="permdesc_getTasks" msgid="7454215995847658102">"Umožňuje aplikaci získat informace o aktuálně a naposledy spuštěných úlohách. Aplikace s tímto oprávněním může odhalit informace o aplikacích, které se v zařízení používají."</string>
+ <string name="permdesc_getTasks" msgid="7454215995847658102">"Umožňuje získat informace o aktuálně a naposledy spuštěných úlohách. Aplikace s tímto oprávněním může odhalit informace o aplikacích, které se v zařízení používají."</string>
<string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"interakce napříč uživateli"</string>
- <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umožňuje aplikaci provádět akce napříč různými uživateli zařízení. Škodlivé aplikace toto oprávnění mohou zneužít k obejití ochrany mezi uživateli."</string>
+ <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umožňuje provádět akce napříč různými uživateli zařízení. Škodlivé aplikace toto oprávnění mohou zneužít k obejití ochrany mezi uživateli."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"úplné oprávnění k interakcím napříč uživateli"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Povoluje všechny možné interakce napříč uživateli."</string>
<string name="permlab_manageUsers" msgid="1676150911672282428">"správa uživatelů"</string>
- <string name="permdesc_manageUsers" msgid="8409306667645355638">"Umožňuje aplikacím spravovat uživatele v zařízení, včetně vytváření a mazání dotazů."</string>
+ <string name="permdesc_manageUsers" msgid="8409306667645355638">"Umožňuje spravovat uživatele v zařízení, včetně vytváření a mazání dotazů."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"získání podrobností o spuštěných aplikacích"</string>
- <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Umožňuje aplikaci získat podrobné informace o aktuálně a naposledy spuštěných úlohách. Škodlivé aplikace mohou odhalit soukromé informace o ostatních aplikacích."</string>
+ <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Umožňuje získat podrobné informace o aktuálně a naposledy spuštěných úlohách. Škodlivé aplikace mohou odhalit soukromé informace o ostatních aplikacích."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"změna uspořádání spuštěných aplikací"</string>
- <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Umožňuje aplikaci přesunout úlohy na popředí nebo pozadí. Aplikace tak může činit bez vašeho zásahu."</string>
+ <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Umožňuje přesunout úlohy na popředí nebo pozadí. Aplikace tak může činit bez vašeho zásahu."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"zastavení činnosti aplikací"</string>
- <string name="permdesc_removeTasks" msgid="1394714352062635493">"Umožňuje aplikaci odstranit úlohy a ukončit jejich aplikace. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
+ <string name="permdesc_removeTasks" msgid="1394714352062635493">"Umožňuje odstranit úlohy a ukončit jejich aplikace. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
<string name="permlab_startAnyActivity" msgid="2918768238045206456">"zahájení libovolné činnosti"</string>
- <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Umožňuje aplikaci zahájit libovolnou aktivitu bez ohledu na ochranu pomocí oprávnění či exportovaný stav."</string>
+ <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Umožňuje zahájit libovolnou aktivitu bez ohledu na ochranu pomocí oprávnění či exportovaný stav."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nastavit kompatibilitu obrazovky"</string>
- <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Umožňuje aplikaci ovládat režim kompatibility obrazovky v ostatních aplikacích. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
+ <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Umožňuje ovládat režim kompatibility obrazovky v ostatních aplikacích. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"povolení ladění aplikací"</string>
- <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Umožňuje aplikaci zapnout ladění jiné aplikace. Škodlivé aplikace mohou toto oprávnění použít k ukončení ostatních aplikací."</string>
+ <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Umožňuje zapnout ladění jiné aplikace. Škodlivé aplikace mohou toto oprávnění použít k ukončení ostatních aplikací."</string>
<string name="permlab_changeConfiguration" msgid="4162092185124234480">"změna systémových nastavení obrazovky"</string>
- <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Umožňuje aplikaci změnit aktuální konfiguraci, např. národní prostředí či obecnou velikost písma."</string>
+ <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Umožňuje změnit aktuální nastavení, např. národní prostředí či velikost písma."</string>
<string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivovat režim V autě"</string>
- <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Umožňuje aplikaci aktivovat režim V autě."</string>
+ <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Umožňuje aktivovat režim V autě."</string>
<string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"zavření ostatních aplikací"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Umožňuje aplikaci ukončit procesy na pozadí ostatních aplikací. Mohlo by dojít k zastavení ostatních aplikací."</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Umožňuje ukončit procesy na pozadí ostatních aplikací. Mohlo by dojít k zastavení ostatních aplikací."</string>
<string name="permlab_forceStopPackages" msgid="2329627428832067700">"vynucení zastavení jiných aplikací"</string>
- <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Umožňuje aplikaci vynutit zastavení jiných aplikací."</string>
+ <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Umožňuje vynutit zastavení jiných aplikací."</string>
<string name="permlab_forceBack" msgid="652935204072584616">"vynucení zavření aplikace"</string>
- <string name="permdesc_forceBack" msgid="3892295830419513623">"Umožňuje aplikaci vynutit ukončení jakékoli činnosti běžící na popředí a její vrácení zpět. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_forceBack" msgid="3892295830419513623">"Umožňuje vynutit ukončení jakékoli činnosti běžící na popředí. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_dump" msgid="1681799862438954752">"načtení interního stavu systému"</string>
- <string name="permdesc_dump" msgid="1778299088692290329">"Umožňuje aplikaci získat informace o vnitřním stavu systému. Škodlivé aplikace mohou získat různé soukromé informace nebo informace o zabezpečení, které by běžně vůbec neměly potřebovat."</string>
+ <string name="permdesc_dump" msgid="1778299088692290329">"Umožňuje získat informace o vnitřním stavu systému. Škodlivé aplikace mohou získat různé soukromé informace nebo informace o zabezpečení, které by běžně vůbec neměly potřebovat."</string>
<string name="permlab_retrieve_window_content" msgid="8022588608994589938">"načtení obsahu obrazovky"</string>
- <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Umožňuje aplikaci načíst obsah aktivního okna. Škodlivé aplikace mohou načíst obsah celého okna a prozkoumat všechen text kromě hesel."</string>
+ <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Umožňuje načíst obsah aktivního okna. Škodlivé aplikace mohou načíst obsah celého okna a prozkoumat všechen text kromě hesel."</string>
<string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"dočasná aktivace usnadnění přístupu"</string>
- <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Umožňuje aplikaci dočasně aktivovat usnadnění přístupu v zařízení. Škodlivé aplikace mohou usnadnění přístupu aktivovat bez souhlasu uživatele."</string>
+ <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Umožňuje dočasně aktivovat usnadnění přístupu v zařízení. Škodlivé aplikace mohou usnadnění přístupu aktivovat bez souhlasu uživatele."</string>
<string name="permlab_retrieve_window_info" msgid="8532295199112519378">"načítání informací o oknech"</string>
- <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Umožňuje aplikaci načíst informace o oknech ze správce oken. Škodlivé aplikace mnohou načíst informace, které slouží k internímu systémovému využití."</string>
+ <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Umožňuje načíst informace o oknech ze správce oken. Škodlivé aplikace mnohou načíst informace, které slouží k internímu systémovému využití."</string>
<string name="permlab_filter_events" msgid="8675535648807427389">"filtrování událostí"</string>
- <string name="permdesc_filter_events" msgid="8006236315888347680">"Umožní aplikaci registrovat vstupní filtr, který filtruje stream všech uživatelských přenosů před jejich odvysíláním. Škodlivé aplikace mohou používat uživatelské rozhraní systému bez zásahu uživatele."</string>
+ <string name="permdesc_filter_events" msgid="8006236315888347680">"Umožní registrovat vstupní filtr, který zpracovává všchny uživatelské události. Škodlivé aplikace mohou používat uživatelské rozhraní systému bez zásahu uživatele."</string>
<string name="permlab_magnify_display" msgid="5973626738170618775">"zvětšit zobrazení"</string>
- <string name="permdesc_magnify_display" msgid="7121235684515003792">"Povoluje aplikaci zvětšit obsah displeje. Škodlivé aplikace mohou změnit zobrazení obsahu způsobem, který učiní zařízení nepoužitelným."</string>
+ <string name="permdesc_magnify_display" msgid="7121235684515003792">"Povoluje zvětšit obsah displeje. Škodlivé aplikace mohou změnit zobrazení obsahu způsobem, který učiní zařízení nepoužitelným."</string>
<string name="permlab_shutdown" msgid="7185747824038909016">"částečné vypnutí"</string>
<string name="permdesc_shutdown" msgid="7046500838746291775">"Uvede správce činností do vypnutého stavu. Nedojde však k úplnému vypnutí."</string>
<string name="permlab_stopAppSwitches" msgid="4138608610717425573">"zabránění přepínání aplikací"</string>
<string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Zabrání uživateli přepnout na jinou aplikaci."</string>
<string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"sledování a řízení spouštění všech aplikací"</string>
- <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Umožňuje aplikaci sledovat a řídit spouštění činností systémem. Škodlivé aplikace mohou systém zcela ovládnout. Toto oprávnění je požadováno pouze pro účely vývoje, nikdy pro běžné použití."</string>
- <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"odeslání vysílání o odstranění balíčku"</string>
- <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Umožňuje aplikaci vysílat oznámení o odstranění balíčku aplikace. Škodlivé aplikace mohou toto oprávnění použít k ukončení jakékoli jiné spuštěné aplikace."</string>
- <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"odeslání vysílání o přijaté zprávě SMS"</string>
- <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Umožňuje aplikaci vysílat oznámení o přijetí zprávy SMS. Škodlivé aplikace mohou toto oprávnění použít k vytváření falešných příchozích zpráv SMS."</string>
- <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"odeslání vysílání typu WAP-PUSH-received"</string>
- <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Umožňuje aplikaci vysílat oznámení o přijetí zprávy WAP PUSH. Škodlivé aplikace mohou toto oprávnění použít k vytváření falešných přijatých zpráv MMS nebo utajenému nahrazení obsahu libovolné webové stránky jejich škodlivými variantami."</string>
+ <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Umožňuje sledovat a řídit spouštění činností systémem. Škodlivé aplikace mohou systém zcela ovládnout. Toto oprávnění je požadováno pouze pro účely vývoje, nikdy pro běžné použití."</string>
+ <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"odeslání události o odstranění balíčku"</string>
+ <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Umožňuje odeslat oznámení o odstranění balíčku aplikace. Škodlivé aplikace mohou toto oprávnění použít k ukončení jakékoli jiné spuštěné aplikace."</string>
+ <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"odeslání události o přijaté zprávě SMS"</string>
+ <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Umožňuje odeslat oznámení o přijetí zprávy SMS. Škodlivé aplikace mohou toto oprávnění použít k vytváření falešných příchozích zpráv SMS."</string>
+ <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"odeslání události typu přijmutí WAP-PUSH zprávy"</string>
+ <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Umožňuje odeslat oznámení o přijetí zprávy WAP PUSH. Škodlivé aplikace mohou toto oprávnění použít k vytváření falešných přijatých zpráv MMS nebo nahrazení obsahu libovolné webové stránky jejich škodlivými variantami."</string>
<string name="permlab_setProcessLimit" msgid="2451873664363662666">"omezení počtu spuštěných procesů"</string>
- <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Umožňuje aplikaci řídit maximální počet spuštěných procesů. Běžné aplikace toto oprávnění nikdy nepotřebují."</string>
- <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"vynucení zavření aplikací na pozadí"</string>
- <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Umožňuje aplikaci ovládat, zda budou činnosti po přechodu na pozadí vždy ukončeny. Běžné aplikace toto oprávnění nikdy nepožadují."</string>
+ <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Umožňuje řídit maximální počet spuštěných procesů. Běžné aplikace toto oprávnění nikdy nepotřebují."</string>
+ <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"vynucené zavření aplikace na pozadí"</string>
+ <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Umožňuje ovlivnit, zda budou činnosti po přechodu na pozadí vždy ukončeny. Běžné aplikace toto oprávnění nikdy nepožadují."</string>
<string name="permlab_batteryStats" msgid="2789610673514103364">"čtení statistických údajů o baterii"</string>
- <string name="permdesc_batteryStats" msgid="5897346582882915114">"Umožňuje aplikaci číst aktuální podrobné údaje o využití baterie. Aplikace to může využít k získání podrobných informací o tom, které aplikace používáte."</string>
+ <string name="permdesc_batteryStats" msgid="5897346582882915114">"Umožňuje číst aktuální podrobné údaje o využití baterie. Aplikace to může využít k získání podrobných informací o tom, které aplikace používáte."</string>
<string name="permlab_updateBatteryStats" msgid="3719689764536379557">"změna statistických údajů o baterii"</string>
- <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Umožňuje aplikaci upravit shromážděné statistiky o baterii. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Umožňuje upravit shromážděné statistiky o baterii. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_backup" msgid="470013022865453920">"ovládání zálohování a obnovy systému"</string>
- <string name="permdesc_backup" msgid="6912230525140589891">"Umožňuje aplikaci řídit mechanismy zálohování a obnovení systému. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_backup" msgid="6912230525140589891">"Umožňuje řídit mechanismy zálohování a obnovení systému. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_confirm_full_backup" msgid="5557071325804469102">"potvrzení operace úplné zálohy nebo úplného obnovení"</string>
- <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Umožňuje aplikaci spustit uživatelské rozhraní potvrzení úplné zálohy. Toto oprávnění nesmí používat žádná aplikace."</string>
+ <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Umožňuje spustit požadavek potvrzení úplné zálohy. Toto oprávnění nesmí používat žádná aplikace."</string>
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"zobrazení nepovolených oken"</string>
- <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Umožňuje aplikaci vytvářet okna, která se budou používat v interním uživatelském rozhraní systému. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Umožňuje vytvářet okna, která se budou používat v interním uživatelském rozhraní systému. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_systemAlertWindow" msgid="3543347980839518613">"kreslení přes další aplikace"</string>
- <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Umožňuje aplikaci využívat jiné aplikace nebo části uživatelského rozhraní. Aplikace tak může zasahovat do používání rozhraní jakékoli aplikace a měnit rozhraní zobrazené v jiných aplikacích."</string>
+ <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Umožňuje využívat jiné aplikace nebo části uživatelského rozhraní. Aplikace tak může zasahovat do používání rozhraní jakékoli aplikace a měnit rozhraní zobrazené v jiných aplikacích."</string>
<string name="permlab_setAnimationScale" msgid="2805103241153907174">"změna globální rychlosti animace"</string>
- <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Umožňuje aplikaci kdykoliv globálně změnit rychlost animací (rychlejší či pomalejší animace)."</string>
+ <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Umožňuje kdykoliv globálně změnit rychlost animací (rychlejší či pomalejší animace)."</string>
<string name="permlab_manageAppTokens" msgid="1286505717050121370">"správa klíčů aplikací"</string>
- <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Umožňuje aplikaci vytvořit a spravovat vlastní klíče a současně obejít pořadí vykreslování. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Umožňuje vytvořit a spravovat vlastní klíče a současně obejít jejich přirozené pořadí. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_freezeScreen" msgid="4708181184441880175">"zmrazit obrazovku"</string>
<string name="permdesc_freezeScreen" msgid="8558923789222670064">"Povoluje aplikaci dočasně zmrazit obrazovku pro přechod do režimu celé obrazovky."</string>
<string name="permlab_injectEvents" msgid="1378746584023586600">"používání kláves a tlačítek"</string>
- <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Umožňuje aplikaci doručit vlastní vstupní události (stisknutí tlačítek atd.) dalším aplikacím. Škodlivé aplikace mohou pomocí tohoto oprávnění převzít kontrolu nad tabletem."</string>
- <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Umožňuje aplikaci doručit vlastní vstupní události (stisknutí tlačítek atd.) dalším aplikacím. Škodlivé aplikace mohou pomocí tohoto oprávnění převzít kontrolu nad telefonem."</string>
+ <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Umožňuje vytvořit vlastní vstupní události (stisknutí tlačítek atd.) dalším aplikacím. Škodlivé aplikace mohou pomocí tohoto oprávnění převzít kontrolu nad tabletem."</string>
+ <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Umožňujevytvořit vlastní vstupní události (stisknutí tlačítek atd.) dalším aplikacím. Škodlivé aplikace mohou pomocí tohoto oprávnění převzít kontrolu nad telefonem."</string>
<string name="permlab_readInputState" msgid="469428900041249234">"zaznamenání psaného textu a prováděných činností"</string>
- <string name="permdesc_readInputState" msgid="8387754901688728043">"Umožňuje aplikaci sledovat, které klávesy stisknete, a to i při interakci s jinou aplikací (např. zadávání hesla). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_readInputState" msgid="8387754901688728043">"Umožňuje sledovat, které klávesy stisknete, a to i při interakci s jinou aplikací (např. zadávání hesla). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vazba k metodě zadávání dat"</string>
- <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje držiteli vázat se na nejvyšší úroveň rozhraní pro zadávání dat. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje vázat se na nejvyšší úroveň rozhraní pro zadávání dat. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"navázat se na službu usnadnění přístupu"</string>
- <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby usnadnění přístupu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje navázat se na nejvyšší úroveň rozhraní služby usnadnění přístupu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"navázat se na textovou službu"</string>
- <string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje držiteli připojit se k nejvyšší úrovni rozhraní textové služby (např. SpellCheckerService). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje připojit se k nejvyšší úrovni rozhraní textové služby (např. SpellCheckerService). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"navázat se na službu VPN"</string>
- <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Umožňuje držiteli navázat se na nejvyšší úroveň služby VPN. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Umožňuje navázat se na nejvyšší úroveň služby VPN. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"vazba na tapetu"</string>
- <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní tapety. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Umožňuje navázat se na nejvyšší úroveň rozhraní tapety. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"navázat se na službu widgetu"</string>
- <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Umožňuje držiteli navázat se na nejvyšší úroveň služby widgetu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Umožňuje navázat se na nejvyšší úroveň služby widgetu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"komunikovat se správcem zařízení"</string>
- <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Umožňuje držiteli oprávnění odesílat informace správci zařízení. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Umožňuje odesílat informace správci zařízení. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"změna orientace obrazovky"</string>
- <string name="permdesc_setOrientation" msgid="3046126619316671476">"Umožňuje aplikaci kdykoli změnit otočení obrazovky. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
- <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"změna rychlosti kurzoru"</string>
- <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Umožňuje aplikaci kdykoli změnit rychlost ukazatele myši nebo touchpadu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Umožňuje kdykoli změnit orientaci obrazovky. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"změna rychlosti ukazatele"</string>
+ <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Umožňuje kdykoli změnit rychlost ukazatele myši nebo touchpadu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"změnit rozložení klávesnice"</string>
- <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Umožňuje aplikaci změnit rozložení klávesnice. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Umožňuje změnit rozložení klávesnice. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"odeslání signálů systému Linux aplikacím"</string>
- <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Umožňuje aplikaci vyžádat zaslání poskytnutého signálu všem trvalým procesům."</string>
+ <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Umožňuje vyžádat zaslání poskytnutého signálu všem trvalým procesům."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"trvalé spuštění aplikace"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Umožňuje aplikaci uložit některé své části trvale do paměti. Může to omezit paměť dostupnou pro ostatní aplikace a zpomalit tak tablet."</string>
- <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Umožňuje aplikaci uložit některé své části trvale do paměti. Může to omezit paměť dostupnou pro ostatní aplikace a zpomalit tak telefon."</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Umožňuje uložit některé své části trvale do paměti. Může to omezit paměť dostupnou pro ostatní aplikace a zpomalit tak tablet."</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Umožňuje uložit některé své části trvale do paměti. Může to omezit paměť dostupnou pro ostatní aplikace a zpomalit tak telefon."</string>
<string name="permlab_deletePackages" msgid="184385129537705938">"smazání aplikací"</string>
- <string name="permdesc_deletePackages" msgid="7411480275167205081">"Umožňuje aplikaci smazat balíčky Android. Škodlivé aplikace mohou toto oprávnění použít ke smazání důležitých aplikací."</string>
+ <string name="permdesc_deletePackages" msgid="7411480275167205081">"Umožňuje smazat balíčky aplikací. Škodlivé aplikace mohou toto oprávnění použít ke smazání důležitých aplikací."</string>
<string name="permlab_clearAppUserData" msgid="274109191845842756">"smazání dat ostatních aplikací"</string>
<string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Umožňuje aplikaci vymazat data uživatele."</string>
<string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"smazání mezipaměti ostatních aplikací"</string>
- <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Umožňuje aplikaci smazat soubory v mezipaměti."</string>
+ <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Umožňuje smazat soubory v mezipaměti."</string>
<string name="permlab_getPackageSize" msgid="7472921768357981986">"výpočet místa pro ukládání aplikací"</string>
- <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Umožňuje aplikaci načtení svého kódu, dat a velikostí mezipaměti."</string>
+ <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Umožňuje načtení svého kódu, dat a velikostí mezipaměti."</string>
<string name="permlab_installPackages" msgid="2199128482820306924">"přímá instalace aplikací"</string>
- <string name="permdesc_installPackages" msgid="5628530972548071284">"Umožňuje aplikaci instalovat nové nebo aktualizované balíčky Android. Škodlivé aplikace mohou toto oprávnění použít k přidání nových aplikací s libovolně silnými oprávněními."</string>
+ <string name="permdesc_installPackages" msgid="5628530972548071284">"Umožňuje instalovat nové nebo aktualizované balíčky aplikací. Škodlivé aplikace mohou toto oprávnění použít k přidání nových aplikací s libovolně silnými oprávněními."</string>
<string name="permlab_clearAppCache" msgid="7487279391723526815">"smazání všech dat v mezipaměti aplikace"</string>
- <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Umožňuje aplikaci uvolnit úložiště v tabletu tím, že smaže soubory ve složkách mezipaměti jiných aplikací. To může způsobit, že se jiné aplikace budou spouštět pomaleji, protože budou potřebovat znovu načíst data."</string>
- <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Umožňuje aplikaci uvolnit úložiště v telefonu tím, že smaže soubory ve složkách mezipaměti jiných aplikací. To může způsobit, že se jiné aplikace budou spouštět pomaleji, protože budou potřebovat znovu načíst data."</string>
+ <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Umožňuje uvolnit úložiště v tabletu tím, že smaže soubory ve složkách mezipaměti jiných aplikací. To může způsobit, že se jiné aplikace budou spouštět pomaleji, protože budou potřebovat znovu načíst data."</string>
+ <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Umožňuje uvolnit úložiště v telefonu tím, že smaže soubory ve složkách mezipaměti jiných aplikací. To může způsobit, že se jiné aplikace budou spouštět pomaleji, protože budou potřebovat znovu načíst data."</string>
<string name="permlab_movePackage" msgid="3289890271645921411">"přesun zdrojů aplikace"</string>
- <string name="permdesc_movePackage" msgid="319562217778244524">"Umožňuje aplikaci přesunout zdroje aplikace z interního média do externího a naopak."</string>
+ <string name="permdesc_movePackage" msgid="319562217778244524">"Umožňuje přesunout zdroje aplikace z interního úložiště do externího a naopak."</string>
+ <string name="permlab_preventpower">zachovat tlačítko vypínání</string>
+ <string name="permdesc_preventpower">Umožní změnit chování tlačítka pro zapínání a vypínání</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"čtení citlivých dat v protokolech"</string>
- <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Umožňuje aplikaci číst různé systémové soubory protokolů. Toto oprávnění aplikaci umožní získat obecné informace o činnostech s tabletem, které by mohly obsahovat osobní či soukromé informace."</string>
- <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Umožňuje aplikaci číst různé systémové soubory protokolů. Toto oprávnění aplikaci umožní získat obecné informace o činnostech s telefonem, které by mohly obsahovat osobní či soukromé informace."</string>
+ <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Umožňuje číst různé systémové soubory protokolů. Toto oprávnění umožní získat obecné informace o činnostech s tabletem, které by mohly obsahovat osobní či soukromé informace."</string>
+ <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Umožňuje číst různé systémové soubory protokolů. Toto oprávnění umožní získat obecné informace o činnostech s telefonem, které by mohly obsahovat osobní či soukromé informace."</string>
<string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"použít jakýkoliv dekodér pro přehrávání médií"</string>
- <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje aplikaci používat libovolný nainstalovaný dekodér médií k dekódování při přehrávání."</string>
+ <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje používat libovolný nainstalovaný dekodér médií k dekódování při přehrávání."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"čtení nebo zápis do prostředků funkce diag"</string>
- <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikaci číst libovolné prostředky ve skupině diag, např. soubory ve složce /dev, a zapisovat do nich. Může dojít k ovlivnění stability a bezpečnosti systému. Toto nastavení by měl používat POUZE výrobce či operátor pro diagnostiku hardwaru."</string>
+ <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje číst libovolné prostředky ve skupině diag, např. soubory ve složce /dev, a zapisovat do nich. Může dojít k ovlivnění stability a bezpečnosti systému. Toto nastavení by měl používat POUZE výrobce či operátor pro diagnostiku hardwaru."</string>
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
- <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí tabletu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
- <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí telefonu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
+ <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí tabletu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí telefonu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
<string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"udělení nebo odebrání oprávnění"</string>
- <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Umožňuje aplikaci udělit nebo odebrat sobě samotné nebo jiným aplikacím určitá oprávnění. Škodlivé aplikace pomocí tohoto oprávnění mohou získat přístup k funkcím, které jste jim nepovolili."</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Umožňuje udělit nebo odebrat sobě samotné nebo jiným aplikacím určitá oprávnění. Škodlivé aplikace pomocí tohoto oprávnění mohou získat přístup k funkcím, které jste jim nepovolili."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastavení upřednostňovaných aplikací"</string>
- <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje aplikaci upravit preferované aplikace. Škodlivé aplikace mohou tajně měnit běžící aplikace a přinutit stávající aplikace, aby shromažďovaly vaše soukromé údaje."</string>
+ <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje upravit preferované aplikace. Škodlivé aplikace mohou tajně měnit běžící aplikace a přinutit stávající aplikace, aby shromažďovaly vaše soukromé údaje."</string>
<string name="permlab_writeSettings" msgid="2226195290955224730">"změna nastavení systému"</string>
- <string name="permdesc_writeSettings" msgid="7775723441558907181">"Umožňuje aplikaci upravit data nastavení systému. Škodlivé aplikace mohou poškodit konfiguraci systému."</string>
+ <string name="permdesc_writeSettings" msgid="7775723441558907181">"Umožňuje upravit data nastavení systému. Škodlivé aplikace mohou poškodit nastavení systému."</string>
<string name="permlab_writeSecureSettings" msgid="204676251876718288">"změny zabezpečených nastavení systému"</string>
- <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Umožňuje aplikaci upravit data nastavení zabezpečení systému. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Umožňuje upravit data nastavení zabezpečení systému. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_writeGservices" msgid="2149426664226152185">"změna mapy služeb Google"</string>
- <string name="permdesc_writeGservices" msgid="1287309437638380229">"Umožňuje aplikaci změnit mapu služeb Google. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_writeGservices" msgid="1287309437638380229">"Umožňuje změnit mapu služeb Google. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"spuštění při startu"</string>
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Umožňuje aplikaci spuštění ihned po spuštění systému. Toto oprávnění může zpomalit spuštění tabletu a umožnit aplikaci celkově zpomalit tablet, protože bude neustále spuštěna."</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Umožňuje aplikaci spuštění ihned po spuštění systému. Toto oprávnění může zpomalit spuštění telefonu a umožnit aplikaci celkově zpomalit telefon, protože bude neustále spuštěna."</string>
- <string name="permlab_broadcastSticky" msgid="7919126372606881614">"odeslání trvalého vysílání"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Umožňuje aplikaci odesílat trvalá vysílání, která přetrvávají i po skončení vysílání. Nadměrné používání může tablet zpomalit či způsobit jeho nestabilitu, protože bude používat příliš mnoho paměti."</string>
- <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Umožňuje aplikaci odesílat trvalá vysílání, která přetrvávají i po skončení vysílání. Nadměrné používání může telefon zpomalit či způsobit jeho nestabilitu, protože bude používat příliš mnoho paměti."</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Umožňuje start aplikace ihned po spuštění systému. Toto oprávnění může zpomalit spuštění tabletu a umožnit aplikaci celkově zpomalit tablet, protože bude neustále spuštěna."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Umožňuje start aplikace ihned po spuštění systému. Toto oprávnění může zpomalit spuštění telefonu a umožnit aplikaci celkově zpomalit telefon, protože bude neustále spuštěna."</string>
+ <string name="permlab_broadcastSticky" msgid="7919126372606881614">"odeslání trvalých událostí"</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Umožňuje odesílat trvalé události, které přetrvávají i po skončení odesílání. Nadměrné používání může tablet zpomalit či způsobit jeho nestabilitu z důvodu vyššího využití paměti."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Umožňuje odesílat trvalá vysílání, která přetrvávají i po skončení odesílání. Nadměrné používání může telefon zpomalit či způsobit jeho nestabilitu z důvodu vyššího využití paměti."</string>
<string name="permlab_readContacts" msgid="8348481131899886131">"čtení kontaktů"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Umožňuje aplikaci číst údaje o kontaktech uložených v tabletu, včetně toho, jak často voláte, posíláte e-maily nebo jinak komunikujete s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
- <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Umožňuje aplikaci číst údaje o kontaktech uložených v telefonu, včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Umožňuje číst údaje o kontaktech uložených v tabletu, včetně toho, jak často voláte, posíláte e-maily nebo jinak komunikujete s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+ <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Umožňuje číst údaje o kontaktech uložených v telefonu, včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"úprava kontaktů"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Umožňuje aplikaci upravit údaje o kontaktech uložených v tabletu včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
- <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Umožňuje aplikaci upravit údaje o kontaktech uložených v telefonu včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Umožňuje upravit údaje o kontaktech uložených v tabletu včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Umožňuje upravit údaje o kontaktech uložených v telefonu včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"číst seznam hovorů"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Umožňuje aplikaci číst seznam hovorů v tabletu, včetně dat o příchozích a odchozích hovorech. Toto oprávnění umožňuje aplikaci ukládat údaje ze seznamu hovorů. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
- <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Umožňuje aplikaci číst seznam hovorů v telefonu, včetně dat o příchozích a odchozích hovorech. Toto oprávnění umožňuje aplikaci ukládat údaje ze seznamu hovorů. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Umožňuje číst seznam hovorů v tabletu, včetně dat o příchozích a odchozích hovorech. Toto oprávnění umožňuje aplikaci ukládat údaje ze seznamu hovorů. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Umožňuje číst seznam hovorů v telefonu, včetně dat o příchozích a odchozích hovorech. Toto oprávnění umožňuje aplikaci ukládat údaje ze seznamu hovorů. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"zapisovat seznam hovorů"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Umožňuje aplikaci upravovat seznam hovorů vašeho tabletu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Umožňuje aplikaci upravovat seznam hovorů vašeho telefonu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"čtení vaší vlastní vizitky"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Umožňuje aplikaci číst údaje v osobním profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás aplikace může identifikovat a odeslat údaje z profilu dalším aplikacím."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"úprava vaší vlastní vizitky"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Umožňuje aplikaci změnit nebo přidat údaje osobního profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás aplikace může identifikovat a odeslat údaje z profilu dalším aplikacím."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"číst váš sociální stream"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Umožňuje aplikaci získat přístup k sociálním aktualizacím od vašich přátel a synchronizaci těchto aktualizací. Při sdílení informací buďte opatrní – toto oprávnění umožňuje aplikaci číst komunikaci mezi vámi a vašimi přáteli v sociálních sítích bez ohledu na její důvěrnost. Poznámka: Toto oprávnění nemusí platit pro všechny sociální sítě."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zapisovat do vašeho sociálního streamu"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Umožňuje aplikaci zobrazit sociální aktualizace od vašich přátel. Při sdílení informací buďte opatrní – aplikace s tímto oprávněním může vytvářet zprávy, které zdánlivě pochází od vašich přátel. Poznámka: Toto oprávnění nemusí platit pro všechny sociální sítě."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Umožňuje upravovat seznam hovorů vašeho tabletu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Umožňuje upravovat seznam hovorů vašeho telefonu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
+ <string name="permlab_readProfile" msgid="4701889852612716678">"čtení vlastní vizitky"</string>
+ <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Umožňuje číst údaje v osobním profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás aplikace může identifikovat a odeslat údaje z profilu dalším aplikacím."</string>
+ <string name="permlab_writeProfile" msgid="907793628777397643">"úprava vlastní vizitky"</string>
+ <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Umožňuje změnit nebo přidat údaje osobního profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás aplikace může identifikovat a odeslat údaje z profilu dalším aplikacím."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"číst sociální stream"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Umožňuje získat přístup k sociálním aktualizacím od vašich přátel a synchronizaci těchto aktualizací. Při sdílení informací buďte opatrní – toto oprávnění umožňuje aplikaci číst komunikaci mezi vámi a vašimi přáteli v sociálních sítích bez ohledu na její důvěrnost. Poznámka: Toto oprávnění nemusí platit pro všechny sociální sítě."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zapisovat do sociálního streamu"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Umožňuje měnit sociální aktualizace od vašich přátel. Při sdílení informací buďte opatrní – aplikace s tímto oprávněním může vytvářet zprávy, které zdánlivě pochází od vašich přátel. Poznámka: Toto oprávnění nemusí platit pro všechny sociální sítě."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"čtení událostí kalendáře a důvěrné informace"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Umožňuje aplikaci číst všechny události kalendáře uložené v tabletu, včetně událostí přátel nebo spolupracovníků. Aplikace s tímto oprávněním může sdílet nebo ukládat údaje v kalendáři bez ohledu na důvěrnost nebo citlivost těchto údajů."</string>
- <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Umožňuje aplikaci číst všechny události kalendáře uložené v telefonu, včetně událostí přátel nebo spolupracovníků. Aplikace s tímto oprávněním může sdílet nebo ukládat údaje v kalendáři bez ohledu na důvěrnost nebo citlivost těchto údajů."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Umožňuje číst všechny události kalendáře uložené v tabletu, včetně událostí přátel nebo spolupracovníků. Aplikace s tímto oprávněním může sdílet nebo ukládat údaje v kalendáři bez ohledu na důvěrnost nebo citlivost těchto údajů."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Umožňuje číst všechny události kalendáře uložené v telefonu, včetně událostí přátel nebo spolupracovníků. Aplikace s tímto oprávněním může sdílet nebo ukládat údaje v kalendáři bez ohledu na důvěrnost nebo citlivost těchto údajů."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"přidávání a upravování událostí kalendářů a odesílání e-mailů bez vědomí vlastníka"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Umožňuje aplikaci přidat, odebrat nebo změnit události, které můžete v tabletu upravovat, a to včetně událostí přátel a spolupracovníků. Toto oprávnění umožňuje aplikaci odesílat zprávy, které budou zdánlivě přicházet od vlastníka kalendáře, nebo upravovat události bez vědomí vlastníka."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Umožňuje aplikaci přidat, odebrat nebo změnit události, které můžete v telefonu upravovat, a to včetně událostí přátel a spolupracovníků. Toto oprávnění umožňuje aplikaci odesílat zprávy, které budou zdánlivě přicházet od vlastníků kalendářů, nebo upravovat události bez vědomí vlastníků."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Umožňuje přidat, odebrat nebo změnit události, které můžete v tabletu upravovat, a to včetně událostí přátel a spolupracovníků. Toto oprávnění umožňuje aplikaci odesílat zprávy, které budou zdánlivě přicházet od vlastníka kalendáře, nebo upravovat události bez vědomí vlastníka."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Umožňuje přidat, odebrat nebo změnit události, které můžete v telefonu upravovat, a to včetně událostí přátel a spolupracovníků. Toto oprávnění umožňuje aplikaci odesílat zprávy, které budou zdánlivě přicházet od vlastníků kalendářů, nebo upravovat události bez vědomí vlastníků."</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"simulace zdrojů polohy pro účely testování"</string>
<string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Vytváření simulace zdrojů polohy pro účely testování nebo instalace nového poskytovatele polohy. Toto oprávnění umožňuje aplikaci přepsat polohu nebo stav, který vracejí jiné zdroje polohy, například systém GPS nebo poskytovatelé polohy."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"přístup k dalším příkazům poskytovatele polohy"</string>
- <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Umožňuje aplikaci získat přístup k dalším příkazům poskytovatele polohy. Aplikace s tímto oprávněním může narušit funkci GPS či jiných zdrojů polohy."</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Umožňuje získat přístup k dalším příkazům poskytovatele polohy. Aplikace s tímto oprávněním může narušit funkci GPS či jiných zdrojů polohy."</string>
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"oprávnění k instalaci poskytovatele polohy"</string>
<string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Vytváření simulace zdrojů polohy pro účely testování nebo instalace nového poskytovatele polohy. Toto oprávnění umožňuje aplikaci přepsat polohu nebo stav, který vracejí jiné zdroje polohy, například systém GPS nebo poskytovatelé polohy."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"přesná poloha (pomocí GPS a sítě)"</string>
- <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Umožňuje aplikaci zjistit vaši přesnou polohu pomocí systému GPS nebo síťových lokalizačních zdrojů, jako jsou vysílače mobilní sítě a sítě Wi-Fi. Aby aplikace mohla služby určování polohy použít, musejí být zapnuté a musejí být v zařízení k dispozici. Aplikace pomocí těchto informací mohou určit vaši přesnou polohu a mohou spotřebovávat více energie z baterie."</string>
+ <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Umožňuje zjistit vaši přesnou polohu pomocí systému GPS nebo síťových lokalizačních zdrojů, jako jsou vysílače mobilní sítě a sítě WiFi. Aby aplikace mohla služby určování polohy použít, musejí být zapnuté a musejí být v zařízení k dispozici. Aplikace pomocí těchto informací mohou určit vaši přesnou polohu a mohou spotřebovávat více energie z baterie."</string>
<string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"přibližná poloha (pomocí sítě)"</string>
- <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Umožňuje aplikaci získat vaši přibližnou polohu. Polohu stanovují služby určování polohy pomocí síťových zdrojů, jako jsou vysílače mobilních sítí a sítě Wi-Fi. Aby aplikace mohla služby určování polohy použít, musejí být zapnuté a musejí být ve vašem zařízení k dispozici. Aplikace na základě těchto informací mohou zjistit vaši přibližnou polohu."</string>
+ <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Umožňuje získat vaši přibližnou polohu. Polohu stanovují služby určování polohy pomocí síťových zdrojů, jako jsou vysílače mobilních sítí a sítě WiFi. Aby aplikace mohla služby určování polohy použít, musejí být zapnuté a musejí být ve vašem zařízení k dispozici. Aplikace na základě těchto informací mohou zjistit vaši přibližnou polohu."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"přístup ke službě SurfaceFlinger"</string>
- <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Umožňuje aplikaci používat nízkoúrovňové funkce SurfaceFlinger."</string>
+ <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Umožňuje používat nízkoúrovňové funkce SurfaceFlinger."</string>
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"čtení vyrovnávací paměti snímků"</string>
- <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Umožňuje aplikaci číst obsah vyrovnávací paměti snímků."</string>
- <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurovat displeje přes Wi-Fi"</string>
- <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Povoluje aplikaci připojit a konfigurovat displeje přes Wi-Fi."</string>
- <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládat displeje přes Wi-Fi"</string>
- <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Povoluje aplikaci ovládat základní funkce displejů přes Wi-Fi."</string>
- <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"změna vašeho nastavení zvuku"</string>
- <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Umožňuje aplikaci změnit globální nastavení zvuku, například hlasitost či reproduktor pro výstup zvuku."</string>
+ <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Umožňuje číst obsah vyrovnávací paměti snímků."</string>
+ <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"nastavení displeje přes WiFi"</string>
+ <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Povoluje připojit a nastavit displeje přes WiFi."</string>
+ <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládat displeje přes WiFi"</string>
+ <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Povoluje ovládat základní funkce displejů přes WiFi."</string>
+ <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"změna nastavení zvuku"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Umožňuje změnit globální nastavení zvuku, například hlasitost či reproduktor pro výstup zvuku."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"nahrávání zvuku"</string>
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Umožňuje aplikaci zaznamenat zvuk pomocí mikrofonu. Toto oprávnění umožňuje aplikaci kdykoliv zaznamenat zvuk bez vašeho svolení."</string>
<string name="permlab_camera" msgid="3616391919559751192">"pořizování fotografií a videí"</string>
- <string name="permdesc_camera" msgid="8497216524735535009">"Umožňuje aplikaci pořizovat fotografie a videa pomocí fotoaparátu. Toto oprávnění umožňuje aplikaci používat fotoaparát kdykoliv i bez vašeho svolení."</string>
+ <string name="permdesc_camera" msgid="8497216524735535009">"Umožňuje pořizovat fotografie a videa pomocí fotoaparátu. Toto oprávnění umožňuje aplikaci používat fotoaparát kdykoliv i bez vašeho svolení."</string>
<string name="permlab_brick" product="tablet" msgid="2961292205764488304">"trvalé vypnutí tabletu"</string>
<string name="permlab_brick" product="default" msgid="8337817093326370537">"trvalé vypnutí telefonu"</string>
- <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Umožňuje aplikaci trvale vypnout celý tablet. To je velmi nebezpečné oprávnění."</string>
- <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Umožňuje aplikaci trvale vypnout celý telefon. To je velmi nebezpečné oprávnění."</string>
- <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"vynucení restartování tabletu"</string>
- <string name="permlab_reboot" product="default" msgid="2898560872462638242">"vynucení restartování telefonu"</string>
- <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Umožňuje aplikaci vynutit restartování tabletu."</string>
- <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Umožňuje aplikaci vynutit restartování telefonu."</string>
+ <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Umožňuje trvale vypnout celý tablet. To je velmi nebezpečné oprávnění."</string>
+ <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Umožňuje trvale vypnout celý telefon. To je velmi nebezpečné oprávnění."</string>
+ <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"vynucené restartování tabletu"</string>
+ <string name="permlab_reboot" product="default" msgid="2898560872462638242">"vynucené restartování telefonu"</string>
+ <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Umožňuje vynutit restartování tabletu."</string>
+ <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Umožňuje vynutit restartování telefonu."</string>
<string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"přístup k systému souborů v úložišti USB"</string>
<string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"přístup k systému souborů na kartě SD"</string>
- <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Umožňuje aplikaci připojit či odpojit souborové systémy ve vyměnitelných úložištích."</string>
+ <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Umožňuje připojit či odpojit souborové systémy ve vyměnitelných úložištích."</string>
<string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"smazání úložiště USB"</string>
<string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"smazání karty SD"</string>
- <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Umožňuje aplikaci formátovat vyměnitelná úložiště."</string>
+ <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Umožňuje formátovat vyměnitelná úložiště."</string>
<string name="permlab_asec_access" msgid="3411338632002193846">"získat informace o interním úložišti"</string>
- <string name="permdesc_asec_access" msgid="3094563844593878548">"Umožňuje aplikaci získat informace o interním úložišti."</string>
+ <string name="permdesc_asec_access" msgid="3094563844593878548">"Umožňuje získat informace o interním úložišti."</string>
<string name="permlab_asec_create" msgid="6414757234789336327">"vytvořit interní úložiště"</string>
- <string name="permdesc_asec_create" msgid="4558869273585856876">"Umožňuje aplikaci vytvořit interní úložiště."</string>
+ <string name="permdesc_asec_create" msgid="4558869273585856876">"Umožňuje vytvořit interní úložiště."</string>
<string name="permlab_asec_destroy" msgid="526928328301618022">"trvale smazat interní úložiště"</string>
- <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Umožňuje aplikaci trvale smazat interní úložiště."</string>
+ <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Umožňuje trvale smazat interní úložiště."</string>
<string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"připojení nebo odpojení interního úložiště"</string>
- <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Umožňuje aplikaci připojit nebo odpojit interní úložiště."</string>
+ <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Umožňuje připojit nebo odpojit interní úložiště."</string>
<string name="permlab_asec_rename" msgid="7496633954080472417">"přejmenovat interní úložiště"</string>
- <string name="permdesc_asec_rename" msgid="1794757588472127675">"Umožňuje aplikaci přejmenovat interní úložiště."</string>
+ <string name="permdesc_asec_rename" msgid="1794757588472127675">"Umožňuje přejmenovat interní úložiště."</string>
<string name="permlab_vibrate" msgid="7696427026057705834">"ovládání vibrací"</string>
- <string name="permdesc_vibrate" msgid="6284989245902300945">"Umožňuje aplikaci ovládat vibrace."</string>
- <string name="permlab_flashlight" msgid="2155920810121984215">"ovládání kontrolky"</string>
- <string name="permdesc_flashlight" msgid="6522284794568368310">"Umožňuje aplikaci ovládat baterku."</string>
+ <string name="permdesc_vibrate" msgid="6284989245902300945">"Umožňuje ovládat vibrace."</string>
+ <string name="permlab_flashlight" msgid="2155920810121984215">"ovládání blesku fotoaparátu"</string>
+ <string name="permdesc_flashlight" msgid="6522284794568368310">"Umožňuje ovládat LED osvětlení - blesk fotoaparátu."</string>
<string name="permlab_manageUsb" msgid="1113453430645402723">"spravovat nastavení a oprávnění pro zařízení USB"</string>
- <string name="permdesc_manageUsb" msgid="7776155430218239833">"Umožňuje aplikaci spravovat nastavení a oprávnění pro zařízení USB."</string>
+ <string name="permdesc_manageUsb" msgid="7776155430218239833">"Umožňuje spravovat nastavení a oprávnění pro zařízení USB."</string>
<string name="permlab_accessMtp" msgid="4953468676795917042">"implementace protokolu MTP"</string>
<string name="permdesc_accessMtp" msgid="6532961200486791570">"Povoluje přístup k ovladači protokolu MTP jádra za účelem implementace protokolu MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testování hardwaru"</string>
- <string name="permdesc_hardware_test" msgid="6597964191208016605">"Umožňuje aplikaci ovládat různé periferie pro účely testování hardwaru."</string>
+ <string name="permdesc_hardware_test" msgid="6597964191208016605">"Umožňuje ovládat různé periferie pro účely testování hardwaru."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"přímé volání na telefonní čísla"</string>
- <string name="permdesc_callPhone" msgid="3740797576113760827">"Umožňuje aplikaci volat na telefonní čísla bez vašeho přičinění. Může mít za následek neočekávané poplatky nebo hovory. Toto oprávnění neumožňuje aplikaci volat na tísňová čísla. Škodlivé aplikace vás mohou připravit o peníze uskutečňováním hovorů bez vašeho svolení."</string>
+ <string name="permdesc_callPhone" msgid="3740797576113760827">"Umožňuje volat na telefonní čísla bez vašeho přičinění. Může mít za následek neočekávané poplatky nebo hovory. Toto oprávnění neumožňuje aplikaci volat na tísňová čísla. Škodlivé aplikace vás mohou připravit o peníze uskutečňováním hovorů bez vašeho svolení."</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"přímé volání na libovolná telefonní čísla"</string>
- <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Umožňuje aplikaci zavolat na libovolné telefonní číslo, včetně tísňových čísel, bez vašeho přičinění. Škodlivé aplikace mohou uskutečňovat nepotřebné či nelegální hovory na pohotovostní služby."</string>
- <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"přímo spustit nastavení tabletu CDMA"</string>
- <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"přímo spustit nastavení telefonu CDMA"</string>
- <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Umožňuje aplikaci zahájit poskytování CDMA. Škodlivé aplikace mohou poskytování CDMA zahájit samovolně."</string>
+ <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Umožňuje zavolat na libovolné telefonní číslo, včetně tísňových čísel, bez vašeho přičinění. Škodlivé aplikace mohou uskutečňovat nepotřebné či nelegální hovory na pohotovostní služby."</string>
+ <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"přímé spuštění využití služby CDMA na tabletu"</string>
+ <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"přímé spuštění využití služby CDMA na telefonu"</string>
+ <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Umožňuje zahájit využití služby CDMA. Škodlivé aplikace mohou spuštění využití CDMA zahájit samovolně."</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"ovládání oznámení o aktualizaci polohy"</string>
- <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Umožňuje aplikaci zapnout nebo vypnout oznámení o aktualizaci polohy pomocí bezdrátového modulu. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Umožňuje zapnout nebo vypnout oznámení o aktualizaci polohy pomocí bezdrátového modulu. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_checkinProperties" msgid="7855259461268734914">"přístup k vlastnostem Checkin"</string>
- <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Umožňuje aplikaci číst nebo zapisovat přístup k vlastnostem nahraným službou ohlášení. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Umožňuje číst nebo zapisovat přístup k vlastnostem nahraným službou ohlášení. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_bindGadget" msgid="776905339015863471">"zvolit widgety"</string>
- <string name="permdesc_bindGadget" msgid="8261326938599049290">"Umožňuje aplikaci přikázat systému, které widgety mohou konkrétní aplikace používat. Aplikace s tímto oprávněním může ostatním aplikacím udělit přístup k osobním datům. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_bindGadget" msgid="8261326938599049290">"Umožňuje přikázat systému, které widgety mohou konkrétní aplikace používat. Aplikace s tímto oprávněním může ostatním aplikacím udělit přístup k osobním datům. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"změna stavu telefonu"</string>
- <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje aplikaci ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním smí bez upozornění přepínat sítě, zapínat a vypínat bezdrátový modul telefonu a podobně."</string>
+ <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním smí bez upozornění přepínat sítě, zapínat a vypínat bezdrátový modul telefonu a podobně."</string>
<string name="permlab_readPhoneState" msgid="9178228524507610486">"čtení stavu a identity telefonu"</string>
- <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikaci získat přístup k telefonním funkcím zařízení. Toto oprávnění umožňuje aplikaci zjistit telefonní číslo telefonu, identifikační čísla zařízení, zda zrovna probíhá hovor, a vzdálené číslo, ke kterému je hovor připojen."</string>
+ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje získat přístup k telefonním funkcím zařízení. Toto oprávnění umožňuje aplikaci zjistit telefonní číslo telefonu, identifikační čísla zařízení, zda zrovna probíhá hovor a vzdálené číslo, ke kterému je hovor připojen."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zabránění přechodu tabletu do režimu spánku"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zabránění přechodu telefonu do režimu spánku"</string>
- <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikaci zabránit přechodu tabletu do režimu spánku."</string>
- <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Umožňuje aplikaci zabránit přechodu telefonu do režimu spánku."</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje zabránit přechodu tabletu do režimu spánku."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Umožňuje zabránit přechodu telefonu do režimu spánku."</string>
<string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"zapnutí či vypnutí tabletu"</string>
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"zapnutí či vypnutí telefonu"</string>
- <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Umožňuje aplikaci zapnout či vypnout tablet."</string>
- <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Umožňuje aplikaci zapnout či vypnout telefon."</string>
+ <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Umožňuje zapnout či vypnout tablet."</string>
+ <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Umožňuje zapnout či vypnout telefon."</string>
<string name="permlab_factoryTest" msgid="3715225492696416187">"spuštění v režimu továrního testu"</string>
- <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Umožňuje aplikaci spuštění v režimu nízkoúrovňového testu výrobce a povolí přístup k hardwaru tabletu. K dispozici, pouze je-li tablet spuštěn v režimu testování výrobce."</string>
- <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Umožňuje aplikaci spuštění v režimu nízkoúrovňového testu výrobce a povolí přístup k hardwaru telefonu. K dispozici pouze, je-li telefon spuštěn v režimu testování výrobce."</string>
+ <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Umožňuje spuštění v režimu nízkoúrovňového testu výrobce a povolí přístup k hardwaru tabletu. K dispozici, pouze je-li tablet spuštěn v režimu testování výrobce."</string>
+ <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Umožňuje spuštění v režimu nízkoúrovňového testu výrobce a povolí přístup k hardwaru telefonu. K dispozici pouze, je-li telefon spuštěn v režimu testování výrobce."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"nastavení tapety"</string>
- <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Umožňuje aplikaci nastavit tapetu systému."</string>
+ <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Umožňuje nastavit tapetu systému."</string>
<string name="permlab_setWallpaperHints" msgid="3278608165977736538">"úprava velikosti tapety"</string>
- <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Umožňuje aplikaci nastavit nápovědu pro velikost tapety systému."</string>
+ <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Umožňuje nastavit velikost tapety systému."</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"obnovení továrního nastavení systému"</string>
- <string name="permdesc_masterClear" msgid="3665380492633910226">"Umožňuje aplikaci zcela resetovat systém na tovární nastavení, vymazat všechna data, nastavení a nainstalované aplikace."</string>
+ <string name="permdesc_masterClear" msgid="3665380492633910226">"Umožňuje zcela resetovat systém na tovární nastavení, vymazat všechna data, nastavení a nainstalované aplikace."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"nastavit čas"</string>
- <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Umožňuje aplikaci změnit čas hodin v tabletu."</string>
- <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Umožňuje aplikaci změnit čas hodin v telefonu."</string>
+ <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Umožňuje změnit čas v tabletu."</string>
+ <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Umožňuje změnit čas v telefonu."</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"nastavení časového pásma"</string>
- <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Umožňuje aplikaci změnit časové pásmo tabletu."</string>
- <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Umožňuje aplikaci změnit časové pásmo telefonu."</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Umožňuje změnit časové pásmo tabletu."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Umožňuje změnit časové pásmo telefonu."</string>
<string name="permlab_accountManagerService" msgid="4829262349691386986">"role služby AccountManagerService"</string>
<string name="permdesc_accountManagerService" msgid="1948455552333615954">"Umožňuje aplikaci volat funkce AccountAuthenticator."</string>
<string name="permlab_getAccounts" msgid="1086795467760122114">"vyhledání účtů v zařízení"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Umožňuje aplikaci získat seznam účtů v tabletu. Mohou sem patřit i účty vytvořené aplikacemi, které jste nainstalovali."</string>
- <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Umožňuje aplikaci získat seznam účtů v telefonu. Mohou sem patřit i účty vytvořené aplikacemi, které jste nainstalovali."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Umožňuje získat seznam účtů v tabletu. Mohou sem patřit i účty vytvořené aplikacemi, které jste nainstalovali."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Umožňuje získat seznam účtů v telefonu. Mohou sem patřit i účty vytvořené aplikacemi, které jste nainstalovali."</string>
<string name="permlab_authenticateAccounts" msgid="5265908481172736933">"vytváření účtů a nastavení hesel"</string>
- <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Umožňuje aplikaci používat funkce aplikace AccountManager související s ověřováním účtů – včetně vytváření účtů a získávání a nastavování hesel."</string>
+ <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Umožňuje používat funkce aplikace AccountManager související s ověřováním účtů – včetně vytváření účtů a získávání a nastavování hesel."</string>
<string name="permlab_manageAccounts" msgid="4983126304757177305">"přidání nebo odebrání účtů"</string>
- <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Umožňuje aplikaci provádět operace, jako je přidávání nebo odebírání účtů nebo mazání jejich hesel."</string>
+ <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Umožňuje provádět operace, jako je přidávání nebo odebírání účtů nebo mazání jejich hesel."</string>
<string name="permlab_useCredentials" msgid="235481396163877642">"používání účtů v zařízení"</string>
- <string name="permdesc_useCredentials" msgid="7984227147403346422">"Umožňuje aplikaci požadovat ověřovací klíče."</string>
+ <string name="permdesc_useCredentials" msgid="7984227147403346422">"Umožňuje požadovat ověřovací identity."</string>
<string name="permlab_accessNetworkState" msgid="4951027964348974773">"zobrazení síťových připojení"</string>
- <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Umožňuje aplikaci zobrazit informace o síťových připojeních, například o tom, které sítě jsou k dispozici a které jsou připojené."</string>
+ <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Umožňuje zobrazit informace o síťových připojeních, například o tom, které sítě jsou k dispozici a které jsou připojené."</string>
<string name="permlab_createNetworkSockets" msgid="8018758136404323658">"úplný přístup k síti"</string>
- <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Umožňuje aplikaci vytvářet síťové sokety a používat vlastní síťové protokoly. K odesílání údajů na internet toto oprávnění není nutné, protože údaje lze na internet odesílat prostřednictvím prohlížečů a dalších aplikací."</string>
+ <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Umožňuje vytvářet síťové sokety a používat vlastní síťové protokoly. K odesílání údajů na internet toto oprávnění není nutné, protože údaje lze na internet odesílat prostřednictvím prohlížečů a dalších aplikací."</string>
<string name="permlab_writeApnSettings" msgid="505660159675751896">"měnit/zachytávat nastavení sítě a síťové přenosy"</string>
- <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Umožňuje aplikaci změnit nastavení sítě a zachytit a prozkoumat síťové přenosy, například za účelem změny serveru proxy a portu jakéhokoli názvu přístupového bodu. Škodlivé aplikace mohou bez vašeho vědomí sledovat, přesměrovat nebo upravit síťové pakety."</string>
+ <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Umožňuje změnit nastavení sítě a zachytit a prozkoumat síťové přenosy, například za účelem změny serveru proxy a portu jakéhokoli názvu přístupového bodu. Škodlivé aplikace mohou bez vašeho vědomí sledovat, přesměrovat nebo upravit síťové pakety."</string>
<string name="permlab_changeNetworkState" msgid="958884291454327309">"změna připojení k síti"</string>
- <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Umožňuje aplikaci změnit stav připojení k síti."</string>
+ <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Umožňuje změnit stav připojení k síti."</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"změnit sdílené datové připojení"</string>
- <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Umožňuje aplikaci změnit stav sdíleného datového připojení k síti."</string>
+ <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Umožňuje změnit stav sdíleného datového připojení k síti."</string>
<string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"změnit nastavení použití dat na pozadí"</string>
- <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Umožňuje aplikaci změnit nastavení použití dat na pozadí."</string>
- <string name="permlab_accessWifiState" msgid="5202012949247040011">"zobrazení připojení Wi-Fi"</string>
- <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Umožňuje aplikaci zobrazit informace o sítích Wi-fi, například o tom, zda je povoleno připojení Wi-Fi, nebo název připojených zařízení Wi-Fi."</string>
- <string name="permlab_changeWifiState" msgid="6550641188749128035">"připojení k síti Wi-Fi a odpojení od sítě Wi-Fi"</string>
- <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Umožňuje aplikaci připojit se k přístupovým bodům Wi-Fi či se od nich odpojit a provádět změny konfigurace zařízení pro sítě Wi-Fi."</string>
- <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"povolení příjmu Wi-Fi Multicast"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Umožňuje aplikaci přijímat pakety odeslané do všech zařízení v síti Wi-Fi nejen pomocí tabletu, ale i prostřednictvím adres vícesměrového vysílání. Spotřeba energie je vyšší než u režimu bez vícesměrového vysílání (multicast)."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Umožňuje aplikaci přijímat pakety odeslané do všech zařízení v síti Wi-Fi nejen pomocí telefonu, ale i prostřednictvím adres vícesměrového vysílání. Spotřeba energie je vyšší než u režimu bez vícesměrového vysílání (multicast)."</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Umožňuje změnit nastavení použití dat na pozadí."</string>
+ <string name="permlab_accessWifiState" msgid="5202012949247040011">"zobrazení připojení WiFi"</string>
+ <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Umožňuje zobrazit informace o sítích WiFi, například o tom, zda je povoleno připojení WiFi, nebo název připojených zařízení WiFi."</string>
+ <string name="permlab_changeWifiState" msgid="6550641188749128035">"připojení k síti WiFi a odpojení od sítě WiFi"</string>
+ <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Umožňuje připojit se k přístupovým bodům WiFi či se od nich odpojit a provádět změny nastavení zařízení pro sítě WiFi."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"povolení příjmu WiFi Multicast"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Umožňuje přijímat pakety odeslané do všech zařízení v síti WiFi nejen pomocí tabletu, ale i prostřednictvím adres vícesměrového vysílání. Spotřeba energie je vyšší než u režimu bez vícesměrového vysílání (multicast)."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Umožňuje přijímat pakety odeslané do všech zařízení v síti WiFi nejen pomocí telefonu, ale i prostřednictvím adres vícesměrového vysílání. Spotřeba energie je vyšší než u režimu bez vícesměrového vysílání (multicast)."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"přístup do nastavení Bluetooth"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Umožňuje aplikaci konfigurovat místní tablet s rozhraním Bluetooth a vyhledávat a párovat vzdálená zařízení."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Umožňuje aplikaci konfigurovat místní telefon s rozhraním Bluetooth a vyhledávat a párovat vzdálená zařízení."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Umožňuje měnit nastavení Bluetooth tabletu, vyhledávat a párovat vzdálená zařízení."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Umožňuje měnit nastavení Bluetooth telefonu, vyhledávat a párovat vzdálená zařízení."</string>
<string name="permlab_accessWimaxState" msgid="4195907010610205703">"připojení a odpojení od sítě WiMAX"</string>
- <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Umožňuje aplikaci zjistit, zda je povoleno připojení WiMAX, a také získat informace o všech připojených sítích WiMAX."</string>
+ <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Umožňuje zjistit, zda je povoleno připojení WiMAX, a také získat informace o všech připojených sítích WiMAX."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"Změnit stav připojení WiMAX"</string>
- <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Umožňuje aplikaci připojovat tablet k sítím WiMAX a odpojovat jej od nich."</string>
- <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Umožňuje aplikaci připojovat telefon k sítím WiMAX a odpojovat jej od nich."</string>
+ <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Umožňuje připojovat a odpojovat tablet k sítím WiMAX."</string>
+ <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Umožňuje připojovat a odpojovat telefon k sítím WiMAX."</string>
<string name="permlab_bluetooth" msgid="6127769336339276828">"párování se zařízeními Bluetooth"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Umožňuje aplikaci zobrazit konfiguraci tabletu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
- <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Umožňuje aplikaci zobrazit konfiguraci telefonu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Umožňuje zobrazit nastavení tabletu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Umožňuje zobrazit nastavení telefonu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"ovládání technologie NFC"</string>
- <string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje aplikaci komunikovat se štítky, kartami a čtečkami s podporou technologie NFC."</string>
+ <string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje komunikovat se štítky, kartami a čtečkami s podporou technologie NFC."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"vypnutí zámku obrazovky"</string>
- <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje aplikaci vypnout zámek kláves a související zabezpečení heslem. Telefon například vypne zámek klávesnice při příchozím hovoru a po skončení hovoru jej zase zapne."</string>
+ <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje vypnout zamčení a související zabezpečení heslem. Na příklad při příchozím hovoru telefon vypne zámek a po skončení hovoru jej zase zapne."</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čtení nastavení synchronizace"</string>
- <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikaci číst nastavení synchronizace v účtu. Může například určit, zda je s účtem synchronizována aplikace Lidé."</string>
+ <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje číst nastavení synchronizace v účtu. Může například určit, zda je s účtem synchronizována aplikace Lidé."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"vypnutí nebo zapnutí synchronizace"</string>
- <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Umožňuje aplikaci změnit nastavení synchronizace v účtu. Pomocí tohoto oprávnění lze například zapnout synchronizaci aplikace Lidé s účtem."</string>
+ <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Umožňuje změnit nastavení synchronizace v účtu. Pomocí tohoto oprávnění lze například zapnout synchronizaci aplikace Lidé s účtem."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"čtení statistických údajů o synchronizaci"</string>
- <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Umožňuje aplikaci číst statistické informace o synchronizaci v účtu, včetně historie uskutečněných synchronizací a informací o množství synchronizovaných dat."</string>
+ <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Umožňuje číst statistické informace o synchronizaci v účtu, včetně historie uskutečněných synchronizací a informací o množství synchronizovaných dat."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čtení zdrojů přihlášených k odběru"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Umožňuje aplikaci získat podrobnosti o aktuálně synchronizovaných zdrojích."</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"zápis odebíraných zdrojů"</string>
- <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Umožňuje aplikaci upravit zdroje, které aktuálně synchronizujete. Škodlivé aplikace mohou synchronizované zdroje změnit."</string>
+ <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Umožňuje upravit zdroje, které aktuálně synchronizujete. Škodlivé aplikace mohou synchronizované zdroje změnit."</string>
<string name="permlab_readDictionary" msgid="4107101525746035718">"čtení výrazů přidaných do slovníku"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Umožňuje aplikaci číst slova, jména a fráze, která uživatel mohl uložit do svého slovníku."</string>
+ <string name="permdesc_readDictionary" msgid="659614600338904243">"Umožňuje číst slova, jména a fráze, která uživatel uložil do svého slovníku."</string>
<string name="permlab_writeDictionary" msgid="2183110402314441106">"přidávání slov do slovníku definovaného uživatelem"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Umožňuje aplikaci zapisovat nová slova do uživatelského slovníku."</string>
+ <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Umožňuje zapisovat nová slova do uživatelského slovníku."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"testování přístupu do chráněného úložiště"</string>
<string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"testování přístupu do chráněného úložiště"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Umožňuje aplikaci testovat oprávnění pro úložiště USB, které bude dostupné v budoucích zařízeních."</string>
- <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Umožňuje aplikaci testovat oprávnění pro kartu SD, která bude dostupná v budoucích zařízeních."</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Umožňuje testovat oprávnění pro úložiště USB, které bude dostupné v budoucích zařízeních."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Umožňuje testovat oprávnění pro kartu SD, která bude dostupná v budoucích zařízeních."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"úprava nebo mazání obsahu v úložišti USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"úprava nebo mazání obsahu na kartě SD"</string>
- <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Umožňuje aplikaci zapisovat do úložiště USB."</string>
- <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikaci zapisovat na kartu SD."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Upravit/smazat interní úlož."</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje aplikaci upravovat obsah interního úložiště médií."</string>
+ <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Umožňuje zapisovat do úložiště USB."</string>
+ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje zapisovat na kartu SD."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"upravit/smazat interní úložiště"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje upravovat obsah interního úložiště médií."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"přístup k externímu úložišti všech uživatelů"</string>
- <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje aplikaci přistupovat k externímu úložišti pro všechny uživatele."</string>
+ <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje přistupovat k externímu úložišti pro všechny uživatele."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"přistupovat do souborového systému mezipaměti"</string>
- <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Umožňuje aplikaci číst a zapisovat do souborového systému mezipaměti."</string>
+ <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Umožňuje číst a zapisovat do souborového systému mezipaměti."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"uskutečňovat a přijímat internetové hovory"</string>
- <string name="permdesc_use_sip" msgid="4717632000062674294">"Umožňuje aplikaci uskutečnit a přijímat internetové hovory pomocí služby SIP."</string>
+ <string name="permdesc_use_sip" msgid="4717632000062674294">"Umožňuje uskutečnit a přijímat internetové hovory pomocí služby SIP."</string>
<string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"číst využití sítě v historii"</string>
- <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Umožňuje aplikaci číst historii využití sítě (u určitých sítí a aplikací)."</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Umožňuje číst historii využití sítě (pro určité sítě a aplikace)."</string>
<string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"spravovat zásady sítě"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Umožňuje aplikaci spravovat zásady sítě a definovat pravidla pro konkrétní aplikace."</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Umožňuje spravovat zásady sítě a definovat pravidla pro konkrétní aplikace."</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"upravit kontrolu používání sítě"</string>
- <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Umožňuje aplikaci upravit způsob výpočtu využití sítě aplikacemi. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Umožňuje upravit způsob přidělování sítě aplikacím. Toto oprávnění není určeno pro běžné aplikace."</string>
+
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
@@ -617,59 +674,61 @@
<string name="policylab_wipeData" msgid="3910545446758639713">"Vymazání všech dat"</string>
<string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Bez upozornění smazat všechna data tabletu obnovením továrních dat."</string>
<string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Bez upozornění smazat všechna data telefonu obnovením továrních dat."</string>
- <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Nastavit globální proxy server zařízení"</string>
- <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globální proxy server, který se bude používat, když jsou zásady aktivní. Aktuální globální proxy server nastavuje pouze první správce zařízení."</string>
+ <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Nastavit globální proxy server"</string>
+ <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globální proxy server, který se bude používat při aktivaci pravidla. Aktuální globální proxy server nastavuje pouze první správce zařízení."</string>
<string name="policylab_expirePassword" msgid="885279151847254056">"Nastavit vypršení hesla zámku"</string>
<string name="policydesc_expirePassword" msgid="1729725226314691591">"Určuje, jak často je třeba měnit heslo pro uzamčení obrazovky."</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nastavit šifrování úložiště"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Požadovat šifrování uložených dat aplikací."</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"Vypnout fotoaparáty"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"Zakázat používání všech fotoaparátů zařízení."</string>
- <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Zakázat funkce v zámku zařízení"</string>
- <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Zabránit používání některých funkcí v zámku zařízení."</string>
- <string-array name="phoneTypes">
- <item msgid="8901098336658710359">"Domů"</item>
- <item msgid="869923650527136615">"Mobil"</item>
- <item msgid="7897544654242874543">"Práce"</item>
- <item msgid="1103601433382158155">"Pracovní fax"</item>
- <item msgid="1735177144948329370">"Fax domů"</item>
- <item msgid="603878674477207394">"Pager"</item>
- <item msgid="1650824275177931637">"Ostatní"</item>
- <item msgid="9192514806975898961">"Vlastní"</item>
- </string-array>
- <string-array name="emailAddressTypes">
- <item msgid="8073994352956129127">"Domů"</item>
- <item msgid="7084237356602625604">"Práce"</item>
- <item msgid="1112044410659011023">"(další)"</item>
- <item msgid="2374913952870110618">"Vlastní"</item>
- </string-array>
- <string-array name="postalAddressTypes">
- <item msgid="6880257626740047286">"Domů"</item>
- <item msgid="5629153956045109251">"Práce"</item>
- <item msgid="4966604264500343469">"Ostatní"</item>
- <item msgid="4932682847595299369">"Vlastní"</item>
- </string-array>
- <string-array name="imAddressTypes">
- <item msgid="1738585194601476694">"Domů"</item>
- <item msgid="1359644565647383708">"Práce"</item>
- <item msgid="7868549401053615677">"Ostatní"</item>
- <item msgid="3145118944639869809">"Vlastní"</item>
- </string-array>
- <string-array name="organizationTypes">
- <item msgid="7546335612189115615">"Práce"</item>
- <item msgid="4378074129049520373">"Ostatní"</item>
- <item msgid="3455047468583965104">"Vlastní"</item>
- </string-array>
- <string-array name="imProtocols">
- <item msgid="8595261363518459565">"AIM"</item>
- <item msgid="7390473628275490700">"Windows Live"</item>
- <item msgid="7882877134931458217">"Yahoo!"</item>
- <item msgid="5035376313200585242">"Skype"</item>
- <item msgid="7532363178459444943">"QQ"</item>
- <item msgid="3713441034299660749">"Google Talk"</item>
- <item msgid="2506857312718630823">"ICQ"</item>
- <item msgid="1648797903785279353">"Jabber"</item>
- </string-array>
+ <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Zakázat vlastnosti zamykání"</string>
+ <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Zabránit používání některých vlastností zamykání zařízení."</string>
+
+ <string-array name="phoneTypes">
+ <item msgid="8901098336658710359">"Domů"</item>
+ <item msgid="869923650527136615">"Mobil"</item>
+ <item msgid="7897544654242874543">"Práce"</item>
+ <item msgid="1103601433382158155">"Pracovní fax"</item>
+ <item msgid="1735177144948329370">"Fax domů"</item>
+ <item msgid="603878674477207394">"Pager"</item>
+ <item msgid="1650824275177931637">"Ostatní"</item>
+ <item msgid="9192514806975898961">"Vlastní"</item>
+ </string-array>
+ <string-array name="emailAddressTypes">
+ <item msgid="8073994352956129127">"Domů"</item>
+ <item msgid="7084237356602625604">"Práce"</item>
+ <item msgid="1112044410659011023">"Ostatní"</item>
+ <item msgid="2374913952870110618">"Vlastní"</item>
+ </string-array>
+ <string-array name="postalAddressTypes">
+ <item msgid="6880257626740047286">"Domů"</item>
+ <item msgid="5629153956045109251">"Práce"</item>
+ <item msgid="4966604264500343469">"Ostatní"</item>
+ <item msgid="4932682847595299369">"Vlastní"</item>
+ </string-array>
+ <string-array name="imAddressTypes">
+ <item msgid="1738585194601476694">"Domů"</item>
+ <item msgid="1359644565647383708">"Práce"</item>
+ <item msgid="7868549401053615677">"Ostatní"</item>
+ <item msgid="3145118944639869809">"Vlastní"</item>
+ </string-array>
+ <string-array name="organizationTypes">
+ <item msgid="7546335612189115615">"Práce"</item>
+ <item msgid="4378074129049520373">"Ostatní"</item>
+ <item msgid="3455047468583965104">"Vlastní"</item>
+ </string-array>
+ <string-array name="imProtocols">
+ <item msgid="8595261363518459565">"AIM"</item>
+ <item msgid="7390473628275490700">"Windows Live"</item>
+ <item msgid="7882877134931458217">"Yahoo!"</item>
+ <item msgid="5035376313200585242">"Skype"</item>
+ <item msgid="7532363178459444943">"QQ"</item>
+ <item msgid="3713441034299660749">"Google Talk"</item>
+ <item msgid="2506857312718630823">"ICQ"</item>
+ <item msgid="1648797903785279353">"Jabber"</item>
+ </string-array>
+
<string name="phoneTypeCustom" msgid="1644738059053355820">"Vlastní"</string>
<string name="phoneTypeHome" msgid="2570923463033985887">"Domů"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string>
@@ -691,23 +750,28 @@
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Pracovní pager"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistent"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+
<string name="eventTypeCustom" msgid="7837586198458073404">"Vlastní"</string>
<string name="eventTypeBirthday" msgid="2813379844211390740">"Narozeniny"</string>
<string name="eventTypeAnniversary" msgid="3876779744518284000">"Výročí"</string>
<string name="eventTypeOther" msgid="7388178939010143077">"Ostatní"</string>
+
<string name="emailTypeCustom" msgid="8525960257804213846">"Vlastní"</string>
<string name="emailTypeHome" msgid="449227236140433919">"Domů"</string>
<string name="emailTypeWork" msgid="3548058059601149973">"Práce"</string>
<string name="emailTypeOther" msgid="2923008695272639549">"Jiné"</string>
<string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string>
+
<string name="postalTypeCustom" msgid="8903206903060479902">"Vlastní"</string>
<string name="postalTypeHome" msgid="8165756977184483097">"Domů"</string>
<string name="postalTypeWork" msgid="5268172772387694495">"Práce"</string>
<string name="postalTypeOther" msgid="2726111966623584341">"Jiné"</string>
+
<string name="imTypeCustom" msgid="2074028755527826046">"Vlastní"</string>
<string name="imTypeHome" msgid="6241181032954263892">"Domů"</string>
<string name="imTypeWork" msgid="1371489290242433090">"Práce"</string>
<string name="imTypeOther" msgid="5377007495735915478">"Jiné"</string>
+
<string name="imProtocolCustom" msgid="6919453836618749992">"Vlastní"</string>
<string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
<string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
@@ -718,9 +782,11 @@
<string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
<string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
<string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
+
<string name="orgTypeWork" msgid="29268870505363872">"Práce"</string>
<string name="orgTypeOther" msgid="3951781131570124082">"Jiné"</string>
<string name="orgTypeCustom" msgid="225523415372088322">"Vlastní"</string>
+
<string name="relationTypeCustom" msgid="3542403679827297300">"Vlastní"</string>
<string name="relationTypeAssistant" msgid="6274334825195379076">"Asistent"</string>
<string name="relationTypeBrother" msgid="8757913506784067713">"Bratr"</string>
@@ -736,25 +802,28 @@
<string name="relationTypeRelative" msgid="1799819930085610271">"Příbuzný"</string>
<string name="relationTypeSister" msgid="1735983554479076481">"Sestra"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"Manžel(ka)"</string>
+
<string name="sipAddressTypeCustom" msgid="2473580593111590945">"Vlastní"</string>
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Domů"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Práce"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Jiné"</string>
+
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Zadejte kód PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Zadejte kód PUK a nový kód PIN."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kód PUK"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nový kód PIN"</string>
- <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotykem zadáte heslo"</font></string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Klepnutím zadáte heslo"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Zadejte heslo pro odemknutí"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Zadejte kód PIN pro odemknutí"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Nesprávný kód PIN."</string>
- <string name="keyguard_label_text" msgid="861796461028298424">"Chcete-li telefon odemknout, stiskněte Menu a poté 0."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Chcete-li telefon odemknout, stiskněte Nabídku a poté 0."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Číslo tísňové linky"</string>
+
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Žádný signál"</string>
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"Obrazovka uzamčena."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Chcete-li odemknout telefon nebo provést tísňové volání, stiskněte Menu."</string>
- <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Telefon odemknete stisknutím tlačítka Menu."</string>
- <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Odblokujte pomocí gesta"</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Chcete-li odemknout telefon nebo provést tísňové volání, stiskněte tlačítko Nabídka."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Telefon odemknete stisknutím tlačítka Nabídka."</string>
+ <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Odemkněte pomocí gesta"</string>
<string name="lockscreen_emergency_call" msgid="5347633784401285225">"Tísňové volání"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Zavolat zpět"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Správně!"</string>
@@ -762,39 +831,42 @@
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Zkusit znovu"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Překročili jste maximální povolený počet pokusů o odemknutí obličejem."</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Nabíjení - <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_discharging">Vybíjení - <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<string name="lockscreen_charged" msgid="321635745684060624">"Nabito"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Připojte dobíjecí zařízení."</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Není vložena SIM karta"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"V tabletu není SIM karta."</string>
- <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"V telefonu není žádná SIM karta."</string>
+ <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"V telefonu není SIM karta."</string>
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Vložte SIM kartu."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM karta chybí nebo je nečitelná. Vložte SIM kartu."</string>
- <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Nepoužitelná karta SIM."</string>
- <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaše SIM karta byla natrvalo zablokována."\n" Požádejte svého poskytovatele bezdrátových služeb o další SIM kartu."</string>
+ <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"SIM karta je nepoužitelná."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaše SIM karta byla natrvalo zablokována."\n" Požádejte svého operátora o jinou SIM kartu."</string>
+
<string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Tlačítko Předchozí stopa"</string>
<string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Tlačítko Další stopa"</string>
<string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tlačítko Pozastavit"</string>
<string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Tlačítko Přehrát"</string>
<string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Tlačítko Zastavit"</string>
+
<string name="emergency_calls_only" msgid="6733978304386365407">"Pouze tísňová volání"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Síť je blokována"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM karta je zablokována pomocí kódu PUK."</string>
- <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Další informace naleznete v uživatelské příručce; nebo kontaktujte zákaznickou podporu."</string>
+ <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Další informace naleznete v uživatelské příručce nebo kontaktujte zákaznickou podporu."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karta je zablokována."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odblokování SIM karty..."</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste použili nesprávné bezpečnostní gesto. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
- <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali kód PIN. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení tabletu pomocí přihlášení Google."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení telefonu pomocí přihlášení Google."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER">%d</xliff:g>krát. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Telefon jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER">%d</xliff:g>krát. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
- <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Sekundy zbývající do dalšího pokusu: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odblokování SIM karty\u2026"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Nesprávné gesto bylo zadáno <xliff:g id="NUMBER_0">%d</xliff:g>krát."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> sekund."</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Nesprávné heslo bylo zádáno <xliff:g id="NUMBER_0">%d</xliff:g>krát."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> sekund."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Nesprávný PIN byl zadán <xliff:g id="NUMBER_0">%d</xliff:g>krát."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> sekund."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Heslo pro odemknutí bylo zadáno nesprávně <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení tabletu pomocí přihlášení k účtu Google."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> sekund."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Heslo pro odemknutí bylo zadáno nesprávně <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení telefonu pomocí přihlášení k účtu Google."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> sekund."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Pokusili jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Pokusili jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Pokusili jste se <xliff:g id="NUMBER">%d</xliff:g>krát odemknout tablet nesprávným způsobem. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Pokusili jste se <xliff:g id="NUMBER">%d</xliff:g>krát odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Počet sekund do dalšího pokusu: <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Zapomněli jste gesto?"</string>
- <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Odemčení účtu"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Odemknutí účtu"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Příliš mnoho pokusů o nakreslení gesta"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Chcete-li telefon odemknout, přihlaste se pomocí svého účtu Google."</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Uživatelské jméno (e-mail)"</string>
@@ -802,14 +874,17 @@
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Přihlásit se"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neplatné uživatelské jméno nebo heslo."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zapomněli jste uživatelské jméno nebo heslo?"\n"Přejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrola..."</string>
+
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrola\u2026"</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odemknout"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zapnout zvuk"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Vypnout zvuk"</string>
+
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Bezpečnostní gesto zahájeno"</string>
<string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Bezpečnostní gesto vymazáno"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Buňka přidána"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Bezpečnostní gesto dokončeno"</string>
+
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Přidat widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdné"</string>
<string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oblast odemknutí byla rozšířena."</string>
@@ -819,8 +894,8 @@
<string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stav"</string>
<string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparát"</string>
<string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Ovládání médií"</string>
- <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Přeuspořádání widgetů bylo zahájeno."</string>
- <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Přeuspořádání widgetů bylo dokončeno."</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Zahájeno přeuspořádání widgetů."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Dokončeno přeuspořádání widgetů."</string>
<string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> byl smazán."</string>
<string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozšířit oblast odemknutí"</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odemknutí přejetím prstem."</string>
@@ -830,29 +905,35 @@
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odemknutí heslem."</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Oblast pro zadání bezpečnostního gesta."</string>
<string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblast pro přejetí prstem."</string>
+
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+
<string name="granularity_label_character" msgid="7336470535385009523">"znak"</string>
<string name="granularity_label_word" msgid="7075570328374918660">"slovo"</string>
<string name="granularity_label_link" msgid="5815508880782488267">"odkaz"</string>
<string name="granularity_label_line" msgid="5764267235026120888">"řádek"</string>
+
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
+
<string name="factorytest_failed" msgid="5410270329114212041">"Test továrního nastavení se nezdařil"</string>
- <string name="factorytest_not_system" msgid="4435201656767276723">"Test FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string>
- <string name="factorytest_no_action" msgid="872991874799998561">"Nebyl nalezen žádný balíček umožňující test FACTORY_TEST."</string>
+ <string name="factorytest_not_system" msgid="4435201656767276723">"Akci FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string>
+ <string name="factorytest_no_action" msgid="872991874799998561">"Nebyl nalezen žádný balíček umožňující provedení FACTORY_TEST."</string>
<string name="factorytest_reboot" msgid="6320168203050791643">"Restartovat"</string>
+
<string name="js_dialog_title" msgid="1987483977834603872">"Stránka <xliff:g id="TITLE">%s</xliff:g> uvádí:"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
- <string name="js_dialog_before_unload" msgid="730366588032430474">"Chcete opustit tuto stránku?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Chcete-li pokračovat, dotkněte se možnosti OK. Chcete-li zůstat na aktuální stránce, dotkněte se možnosti Zrušit."</string>
+ <string name="js_dialog_before_unload" msgid="730366588032430474">"Chcete opustit tuto stránku?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Chcete-li pokračovat, klepněte na OK. Chcete-li zůstat na aktuální stránce, klepněte na Zrušit."</string>
+
<string name="save_password_label" msgid="6860261758665825069">"Potvrdit"</string>
<string name="double_tap_toast" msgid="4595046515400268881">"Tip: Dvojitým klepnutím můžete zobrazení přiblížit nebo oddálit."</string>
<string name="autofill_this_form" msgid="4616758841157816676">"Aut.vyp."</string>
<string name="setup_autofill" msgid="7103495070180590814">"Nastav aut. vyp."</string>
- <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+ <string name="autofill_address_name_separator" msgid="6350145154779706772">"\u0020"</string>
<string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
- <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">",\u0020 "</string>
<string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="autofill_province" msgid="2231806553863422300">"Provincie"</string>
<string name="autofill_postal_code" msgid="4696430407689377108">"PSČ"</string>
@@ -861,36 +942,39 @@
<string name="autofill_county" msgid="237073771020362891">"Okres"</string>
<string name="autofill_island" msgid="4020100875984667025">"Ostrov"</string>
<string name="autofill_district" msgid="8400735073392267672">"Okres"</string>
- <string name="autofill_department" msgid="5343279462564453309">"Department"</string>
+ <string name="autofill_department" msgid="5343279462564453309">"Resort"</string>
<string name="autofill_prefecture" msgid="2028499485065800419">"Prefektura"</string>
<string name="autofill_parish" msgid="8202206105468820057">"Farnost"</string>
<string name="autofill_area" msgid="3547409050889952423">"Oblast"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"Emirát"</string>
+
<string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"čtení webových záložek a historie"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Umožňuje aplikaci číst historii všech adres URL navštívených v Prohlížeči a všechny záložky v Prohlížeči. Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Umožňuje číst historii všech adres URL navštívených v prohlížeči a všechny záložky v prohlížeči. Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"psaní webových záložek a historie"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Umožňuje aplikaci upravit historii prohlížeče nebo záložky uložené v tabletu. Aplikace s tímto oprávněním může vymazat či pozměnit data prohlížeče. Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Umožňuje aplikaci upravit historii prohlížeče nebo záložky uložené v telefonu. Aplikace s tímto oprávněním může vymazat či pozměnit data prohlížeče .Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Umožňuje upravit historii prohlížeče nebo záložky uložené v tabletu. Aplikace s tímto oprávněním může vymazat či pozměnit data prohlížeče. Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Umožňuje upravit historii prohlížeče nebo záložky uložené v telefonu. Aplikace s tímto oprávněním může vymazat či pozměnit data prohlížeče. Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"nastavení budíku"</string>
- <string name="permdesc_setAlarm" msgid="316392039157473848">"Umožňuje aplikaci nastavit budík v nainstalované aplikaci budík. Některé aplikace budík tuto funkci nemusí obsahovat."</string>
+ <string name="permdesc_setAlarm" msgid="316392039157473848">"Umožňuje nastavit budík. Některé aplikace budíku tuto funkci nemusí obsahovat."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"přidat hlasovou zprávu"</string>
- <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Umožňuje aplikaci přidávat zprávy do hlasové schránky."</string>
+ <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Umožňuje přidávat zprávy do hlasové schránky."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"změna oprávnění prohlížeče poskytovat informace o zeměpisné poloze"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Umožňuje aplikaci upravit oprávnění funkce geolokace v prohlížeči. Škodlivé aplikace toho mohou využít k odeslání údajů o poloze na libovolné webové stránky."</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Umožňuje upravit oprávnění funkce geolokace v prohlížeči. Škodlivé aplikace toho mohou využít k odeslání údajů o poloze na libovolné webové stránky."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"ověřit balíčky"</string>
- <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Umožňuje aplikaci ověřit, zda balíček lze nainstalovat."</string>
+ <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Umožňuje ověřit, zda balíček lze nainstalovat."</string>
<string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"navázat na ověřovatele balíčků"</string>
- <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Umožňuje držiteli podávat žádosti o ověření balíčků. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Umožňuje podávat žádosti o ověření balíčků. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"přístup k sériovým portům"</string>
- <string name="permdesc_serialPort" msgid="2991639985224598193">"Umožňuje držiteli přístup k sériovým portům pomocí rozhraní SerialManager API."</string>
+ <string name="permdesc_serialPort" msgid="2991639985224598193">"Umožňuje přístup k sériovým portům pomocí rozhraní SerialManager API."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"externí přístup k poskytovatelům obsahu"</string>
- <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Umožňuje držiteli získat z příkazového řádku přístup k poskytovatelům obsahu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Umožňuje získat z příkazového řádku přístup k poskytovatelům obsahu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_updateLock" msgid="3527558366616680889">"varovat před automatickou aktualizací"</string>
- <string name="permdesc_updateLock" msgid="1655625832166778492">"Umožňuje držiteli navrhnout systému informace o vhodné době pro upgrade zařízení neinteraktivním restartováním."</string>
+ <string name="permdesc_updateLock" msgid="1655625832166778492">"Umožňuje navrhnout systému informace o vhodné době pro upgrade zařízení neinteraktivním restartováním."</string>
+
<string name="save_password_message" msgid="767344687139195790">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nyní ne"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapamatovat"</string>
<string name="save_password_never" msgid="8274330296785855105">"Nikdy"</string>
+
<string name="open_permission_deny" msgid="7374036708316629800">"Nemáte povolení otevřít tuto stránku."</string>
<string name="text_copied" msgid="4985729524670131385">"Text byl zkopírován do schránky."</string>
<string name="more_item_label" msgid="4650918923083320495">"Více"</string>
@@ -898,89 +982,94 @@
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"mezerník"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="3658178007202748164">"smazat"</string>
+
<string name="search_go" msgid="8298016669822141719">"Hledat"</string>
<string name="searchview_description_search" msgid="6749826639098512120">"Vyhledávat"</string>
- <string name="searchview_description_query" msgid="5911778593125355124">"Vyhledávací dotaz"</string>
+ <string name="searchview_description_query" msgid="5911778593125355124">"Dotaz vyhledávání"</string>
<string name="searchview_description_clear" msgid="1330281990951833033">"Smazat dotaz"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Odeslat dotaz"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Hlasové vyhledávání"</string>
+
<string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Povolit funkci Prozkoumání dotykem?"</string>
<string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolení funkce Prozkoumání dotykem. Pokud je funkce Prozkoumání dotykem zapnuta, můžete slyšet nebo vidět popisy objektů pod vaším prstem nebo ovládat tablet gesty."</string>
<string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolení funkce Prozkoumání dotykem. Pokud je funkce Prozkoumání dotykem zapnuta, můžete slyšet nebo vidět popisy objektů pod vaším prstem nebo ovládat telefon gesty."</string>
+
<string name="oneMonthDurationPast" msgid="7396384508953779925">"před 1 měsícem"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Déle než před 1 měsícem"</string>
- <plurals name="num_seconds_ago">
- <item quantity="one" msgid="4869870056547896011">"před 1 sekundou"</item>
- <item quantity="other" msgid="3903706804349556379">"před <xliff:g id="COUNT">%d</xliff:g> s"</item>
- </plurals>
- <plurals name="num_minutes_ago">
- <item quantity="one" msgid="3306787433088810191">"před 1 min"</item>
- <item quantity="other" msgid="2176942008915455116">"před <xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="num_hours_ago">
- <item quantity="one" msgid="9150797944610821849">"před 1 h"</item>
- <item quantity="other" msgid="2467273239587587569">"před <xliff:g id="COUNT">%d</xliff:g> h"</item>
- </plurals>
- <plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Posledních <xliff:g id="COUNT">%d</xliff:g> dnů"</item>
- </plurals>
+ <plurals name="num_seconds_ago">
+ <item quantity="one" msgid="4869870056547896011">"před 1 sekundou"</item>
+ <item quantity="other" msgid="3903706804349556379">"před <xliff:g id="COUNT">%d</xliff:g> s"</item>
+ </plurals>
+ <plurals name="num_minutes_ago">
+ <item quantity="one" msgid="3306787433088810191">"před 1 minutou"</item>
+ <item quantity="other" msgid="2176942008915455116">"před <xliff:g id="COUNT">%d</xliff:g> min"</item>
+ </plurals>
+ <plurals name="num_hours_ago">
+ <item quantity="one" msgid="9150797944610821849">"před 1 hodinou"</item>
+ <item quantity="other" msgid="2467273239587587569">"před <xliff:g id="COUNT">%d</xliff:g> h"</item>
+ </plurals>
+ <plurals name="last_num_days">
+ <item quantity="other" msgid="3069992808164318268">"Posledních <xliff:g id="COUNT">%d</xliff:g> dnů"</item>
+ </plurals>
<string name="last_month" msgid="3959346739979055432">"Poslední měsíc"</string>
<string name="older" msgid="5211975022815554840">"Starší"</string>
- <plurals name="num_days_ago">
- <item quantity="one" msgid="861358534398115820">"včera"</item>
- <item quantity="other" msgid="2479586466153314633">"před <xliff:g id="COUNT">%d</xliff:g> dny"</item>
- </plurals>
- <plurals name="in_num_seconds">
- <item quantity="one" msgid="2729745560954905102">"za 1 sekundu"</item>
- <item quantity="other" msgid="1241926116443974687">"za <xliff:g id="COUNT">%d</xliff:g> s"</item>
- </plurals>
- <plurals name="in_num_minutes">
- <item quantity="one" msgid="8793095251325200395">"za 1 minutu"</item>
- <item quantity="other" msgid="3330713936399448749">"za <xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="in_num_hours">
- <item quantity="one" msgid="7164353342477769999">"za 1 hodinu"</item>
- <item quantity="other" msgid="547290677353727389">"za <xliff:g id="COUNT">%d</xliff:g> hod."</item>
- </plurals>
- <plurals name="in_num_days">
- <item quantity="one" msgid="5413088743009839518">"zítra"</item>
- <item quantity="other" msgid="5109449375100953247">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item>
- </plurals>
- <plurals name="abbrev_num_seconds_ago">
- <item quantity="one" msgid="1849036840200069118">"před 1 s"</item>
- <item quantity="other" msgid="3699169366650930415">"před <xliff:g id="COUNT">%d</xliff:g> s"</item>
- </plurals>
- <plurals name="abbrev_num_minutes_ago">
- <item quantity="one" msgid="6361490147113871545">"před 1 min"</item>
- <item quantity="other" msgid="851164968597150710">"před <xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="abbrev_num_hours_ago">
- <item quantity="one" msgid="4796212039724722116">"před 1 h"</item>
- <item quantity="other" msgid="6889970745748538901">"před <xliff:g id="COUNT">%d</xliff:g> h"</item>
- </plurals>
- <plurals name="abbrev_num_days_ago">
- <item quantity="one" msgid="8463161711492680309">"včera"</item>
- <item quantity="other" msgid="3453342639616481191">"před <xliff:g id="COUNT">%d</xliff:g> dny"</item>
- </plurals>
- <plurals name="abbrev_in_num_seconds">
- <item quantity="one" msgid="5842225370795066299">"za 1 s"</item>
- <item quantity="other" msgid="5495880108825805108">"za <xliff:g id="COUNT">%d</xliff:g> s"</item>
- </plurals>
- <plurals name="abbrev_in_num_minutes">
- <item quantity="one" msgid="562786149928284878">"za 1 min"</item>
- <item quantity="other" msgid="4216113292706568726">"za <xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="abbrev_in_num_hours">
- <item quantity="one" msgid="3274708118124045246">"za 1 hodinu"</item>
- <item quantity="other" msgid="3705373766798013406">"za <xliff:g id="COUNT">%d</xliff:g> hod."</item>
- </plurals>
- <plurals name="abbrev_in_num_days">
- <item quantity="one" msgid="2178576254385739855">"zítra"</item>
- <item quantity="other" msgid="2973062968038355991">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item>
- </plurals>
+ <plurals name="num_days_ago">
+ <item quantity="one" msgid="861358534398115820">"včera"</item>
+ <item quantity="other" msgid="2479586466153314633">"před <xliff:g id="COUNT">%d</xliff:g> dny"</item>
+ </plurals>
+ <plurals name="in_num_seconds">
+ <item quantity="one" msgid="2729745560954905102">"za 1 sekundu"</item>
+ <item quantity="other" msgid="1241926116443974687">"za <xliff:g id="COUNT">%d</xliff:g> s"</item>
+ </plurals>
+ <plurals name="in_num_minutes">
+ <item quantity="one" msgid="8793095251325200395">"za 1 minutu"</item>
+ <item quantity="other" msgid="3330713936399448749">"za <xliff:g id="COUNT">%d</xliff:g> min"</item>
+ </plurals>
+ <plurals name="in_num_hours">
+ <item quantity="one" msgid="7164353342477769999">"za 1 hodinu"</item>
+ <item quantity="other" msgid="547290677353727389">"za <xliff:g id="COUNT">%d</xliff:g> hod."</item>
+ </plurals>
+ <plurals name="in_num_days">
+ <item quantity="one" msgid="5413088743009839518">"zítra"</item>
+ <item quantity="other" msgid="5109449375100953247">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item>
+ </plurals>
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one" msgid="1849036840200069118">"před 1 s"</item>
+ <item quantity="other" msgid="3699169366650930415">"před <xliff:g id="COUNT">%d</xliff:g> s"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one" msgid="6361490147113871545">"před 1 min"</item>
+ <item quantity="other" msgid="851164968597150710">"před <xliff:g id="COUNT">%d</xliff:g> min"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one" msgid="4796212039724722116">"před 1 h"</item>
+ <item quantity="other" msgid="6889970745748538901">"před <xliff:g id="COUNT">%d</xliff:g> h"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one" msgid="8463161711492680309">"včera"</item>
+ <item quantity="other" msgid="3453342639616481191">"před <xliff:g id="COUNT">%d</xliff:g> dny"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one" msgid="5842225370795066299">"za 1 s"</item>
+ <item quantity="other" msgid="5495880108825805108">"za <xliff:g id="COUNT">%d</xliff:g> s"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one" msgid="562786149928284878">"za 1 min"</item>
+ <item quantity="other" msgid="4216113292706568726">"za <xliff:g id="COUNT">%d</xliff:g> min"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one" msgid="3274708118124045246">"za 1 hodinu"</item>
+ <item quantity="other" msgid="3705373766798013406">"za <xliff:g id="COUNT">%d</xliff:g> hod."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one" msgid="2178576254385739855">"zítra"</item>
+ <item quantity="other" msgid="2973062968038355991">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item>
+ </plurals>
+
<string name="preposition_for_date" msgid="9093949757757445117">"dne <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="preposition_for_time" msgid="5506831244263083793">"v <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"roku <xliff:g id="YEAR">%s</xliff:g>"</string>
+
<string name="day" msgid="8144195776058119424">"den"</string>
<string name="days" msgid="4774547661021344602">"d."</string>
<string name="hour" msgid="2126771916426189481">"hodina"</string>
@@ -1009,45 +1098,54 @@
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Toto video nelze přenášet datovým proudem do tohoto zařízení."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Toto video nelze přehrát."</string>
<string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
+
<string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+
<string name="noon" msgid="7245353528818587908">"poledne"</string>
<string name="Noon" msgid="3342127745230013127">"Poledne"</string>
<string name="midnight" msgid="7166259508850457595">"půlnoc"</string>
<string name="Midnight" msgid="5630806906897892201">"Půlnoc"</string>
+
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
+
<string name="selectAll" msgid="6876518925844129331">"Vybrat vše"</string>
<string name="cut" msgid="3092569408438626261">"Vyjmout"</string>
<string name="copy" msgid="2681946229533511987">"Kopírovat"</string>
<string name="paste" msgid="5629880836805036433">"Vložit"</string>
- <string name="replace" msgid="5781686059063148930">"Nahradit•"</string>
+ <string name="replace" msgid="5781686059063148930">"Nahradit\u2026"</string>
<string name="delete" msgid="6098684844021697789">"Smazat"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopírovat adresu URL"</string>
<string name="selectTextMode" msgid="1018691815143165326">"Vybrat text"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Výběr textu"</string>
<string name="addToDictionary" msgid="4352161534510057874">"Přidat do slovníku"</string>
<string name="deleteText" msgid="6979668428458199034">"Smazat"</string>
- <string name="inputMethod" msgid="1653630062304567879">"Metoda zadávání dat"</string>
+ <string name="inputMethod" msgid="1653630062304567879">"Metoda vstupu"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Operace s textem"</string>
+
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"V úložišti je málo místa"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"Některé systémové funkce nemusí fungovat"</string>
+
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
<string name="no" msgid="5141531044935541497">"Zrušit"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Upozornění"</string>
- <string name="loading" msgid="7933681260296021180">"Načítání..."</string>
- <string name="capital_on" msgid="1544682755514494298">"I"</string>
- <string name="capital_off" msgid="6815870386972805832">"O"</string>
+
+ <string name="loading" msgid="7933681260296021180">"Načítání\u2026"</string>
+
+ <string name="capital_on" msgid="1544682755514494298">"\u2759"</string>
+ <string name="capital_off" msgid="6815870386972805832">"\u25ef"</string>
+
<string name="whichApplication" msgid="4533185947064773386">"Dokončit akci pomocí aplikace"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Použít jako výchozí nastavení pro tuto činnost."</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Výchozí nastavení vymažete v sekci Nastavení systému &gt; Aplikace &gt; Stažené."</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Výchozí nastavení vymažete v \u201eNastavení systému\u201c \u2192 \u201eAplikace\u201c \u2192 \u201eStažené\u201c."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Vyberte akci"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"Vyberte aplikaci pro zařízení USB"</string>
<string name="noApplications" msgid="2991814273936504689">"Tuto činnost nemohou provádět žádné aplikace."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
- <string name="aerr_application" msgid="932628488013092776">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> bohužel přestala pracovat."</string>
- <string name="aerr_process" msgid="4507058997035697579">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> byl bohužel ukončen."</string>
+ <string name="aerr_application" msgid="932628488013092776">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> přestala pracovat."</string>
+ <string name="aerr_process" msgid="4507058997035697579">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> byl ukončen."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Aplikace <xliff:g id="APPLICATION">%2$s</xliff:g> nereaguje."\n\n"Chcete ji ukončit?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktivita <xliff:g id="ACTIVITY">%1$s</xliff:g> nereaguje."\n\n"Chcete ji ukončit?"</string>
@@ -1060,19 +1158,24 @@
<string name="launch_warning_title" msgid="1547997780506713581">"Přesměrování aplikace"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Je spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Původně byla spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"Měřítko"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"Vždy zobrazovat"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Tento režim znovu povolíte v sekci Nastavení systému &gt; Aplikace &gt; Stažené."</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Tento režim znovu povolíte v sekci \u201eNastavení systému\u201c \u2192 \u201eAplikace\u201c \u2192 \u201eStažené\u201c."</string>
+
<string name="smv_application" msgid="3307209192155442829">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) porušila své vlastní vynucené zásady StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> porušil své vlastní vynucené zásady StrictMode."</string>
- <string name="android_upgrading_title" msgid="1584192285441405746">"Android se upgraduje..."</string>
+
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Aktualizace Androidu\u2026"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimalizace aplikace <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Spouštění aplikací."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Probíhá dokončování spouštění."</string>
+
<string name="heavy_weight_notification" msgid="9087063985776626166">"Běží aplikace <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Dotykem přepnete aplikaci"</string>
+ <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Klepnutím přepnete aplikaci"</string>
<string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Přepnout aplikace?"</string>
<string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Než spustíte novou aplikaci, je třeba zastavit jinou spuštěnou aplikaci."</string>
+
<string name="old_app_action" msgid="493129172238566282">"Návrat do aplikace <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
<string name="old_app_description" msgid="2082094275580358049">"Nespouštět novou aplikaci."</string>
<string name="new_app_action" msgid="5472756926945440706">"Spustit aplikaci <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
@@ -1081,7 +1184,7 @@
<string name="volume_ringtone" msgid="6885421406845734650">"Hlasitost vyzvánění"</string>
<string name="volume_music" msgid="5421651157138628171">"Hlasitost médií"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Přehrávání pomocí rozhraní Bluetooth"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Je nastaven tichý vyzváněcí tón"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Je nastaveno tiché vyzvánění"</string>
<string name="volume_call" msgid="3941680041282788711">"Hlasitost hovoru"</string>
<string name="volume_bluetooth_call" msgid="2002891926351151534">"Hlasitost příchozích hovorů při připojení Bluetooth"</string>
<string name="volume_alarm" msgid="1985191616042689100">"Hlasitost budíku"</string>
@@ -1097,135 +1200,156 @@
<string name="ringtone_silent" msgid="7937634392408977062">"Žádné"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Vyzváněcí tóny"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"Neznámý vyzváněcí tón"</string>
- <plurals name="wifi_available">
- <item quantity="one" msgid="6654123987418168693">"K dispozici je síť WiFi."</item>
- <item quantity="other" msgid="4192424489168397386">"Jsou k dispozici sítě WiFi."</item>
- </plurals>
- <plurals name="wifi_available_detailed">
- <item quantity="one" msgid="1634101450343277345">"K dispozici je veřejná síť WiFi"</item>
- <item quantity="other" msgid="7915895323644292768">"Jsou k dispozici veřejné sítě WiFi"</item>
- </plurals>
- <string name="wifi_available_sign_in" msgid="4029489716605255386">"Přihlásit se k síti Wi-Fi"</string>
+
+ <plurals name="wifi_available">
+ <item quantity="one" msgid="6654123987418168693">"K dispozici je síť WiFi."</item>
+ <item quantity="other" msgid="4192424489168397386">"K dispozici jsou síťě WiFi."</item>
+ </plurals>
+ <plurals name="wifi_available_detailed">
+ <item quantity="one" msgid="1634101450343277345">"K dispozici je veřejná síť WiFi"</item>
+ <item quantity="other" msgid="7915895323644292768">"K dispozici jsou veřejné sítě WiFi"</item>
+ </plurals>
+ <string name="wifi_available_sign_in" msgid="4029489716605255386">"Přihlásit se k síti WiFi"</string>
<string name="network_available_sign_in" msgid="8495155593358054676">"Přihlášení k síti"</string>
<!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
<skip />
- <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Připojení k síti Wi-Fi se nezdařilo"</string>
- <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" má pomalé připojení k internetu."</string>
- <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Přímé připojení sítě Wi-Fi"</string>
- <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustit přímé připojení sítě Wi-Fi. Tato možnost vypne provoz sítě Wi-Fi v režimu klient/hotspot."</string>
- <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Přímé připojení sítě Wi-Fi se nepodařilo spustit."</string>
- <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Přímé připojení sítě Wi-Fi je zapnuto"</string>
- <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Nastavení otevřete dotykem"</string>
+ <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Připojení k síti WiFi se nezdařilo"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">"\u0020má pomalé připojení k internetu."</string>
+
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Přímé připojení sítě WiFi (P2P)"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustit přímé připojení sítě WiFi. Tato možnost vypne provoz sítě WiFi v režimu klient/hotspot."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Přímé připojení sítě WiFi se nepodařilo spustit."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Přímé připojení sítě WiFi je zapnuto"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Nastavení otevřete klepnutím"</string>
+
<string name="accept" msgid="1645267259272829559">"Přijmout"</string>
<string name="decline" msgid="2112225451706137894">"Odmítnout"</string>
+
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pozvánka odeslána."</string>
<string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Pozvánka k připojení"</string>
<string name="wifi_p2p_from_message" msgid="570389174731951769">"Od:"</string>
<string name="wifi_p2p_to_message" msgid="248968974522044099">"Komu:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Zadejte požadovaný kód PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" msgid="7363907213787469151">"Telefon se při připojení k zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dočasně odpojí od sítě Wi-Fi"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="7363907213787469151">"Telefon se při připojení k zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dočasně odpojí od sítě WiFi"</string>
+
<string name="select_character" msgid="3365550120617701745">"Vkládání znaků"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Odesílání zpráv SMS"</string>
<string name="sms_control_message" msgid="3867899169651496433">"Aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;odesílá velký počet SMS zpráv. Chcete aplikaci povolit, aby zprávy odesílala i nadále?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Povolit"</string>
<string name="sms_control_no" msgid="625438561395534982">"Odmítnout"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; chce odeslat zprávu na adresu &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
- <string name="sms_short_code_details" msgid="3492025719868078457"><font fgcolor="#ffffb060">"Mohou být účtovány poplatky"</font>" na váš mobilní účet."</string>
+ <string name="sms_short_code_details" msgid="3492025719868078457">"Tato akce může být "<font fgcolor="#ffffb060">"zpoplatněna"</font>"."</string>
<string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Budou účtovány poplatky na váš mobilní účet."</font></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Odeslat"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Zrušit"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Zapamatovat moji volbu"</string>
- <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Svoji volbu můžete později změnit v nabídce Nastavení &gt; Aplikace."</string>
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Svoji volbu můžete později změnit v nabídce \u201eNastavení systému\u201c \u2192 \u201eAplikace\u201c."</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Povolit vždy"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nepovolit nikdy"</string>
+
<string name="sim_removed_title" msgid="6227712319223226185">"SIM karta odebrána"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilní síť bude dostupná až poté, co vložíte platnou SIM kartu a restartujete zařízení."</string>
<string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM karta přidána."</string>
<string name="sim_added_message" msgid="6599945301141050216">"Mobilní síť bude přístupná po restartu zařízení."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"Restartovat"</string>
+
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavení času"</string>
+
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavení data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string>
<string name="date_time_done" msgid="2507683751759308828">"Hotovo"</string>
+
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOVÉ: "</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"Poskytuje: <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string>
<string name="perm_costs_money" msgid="4902470324142151116">"může vás to něco stát"</string>
+
<string name="usb_storage_activity_title" msgid="4465055157209648641">"Velkokapacitní úložiště USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB připojeno"</string>
<string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Připojili jste se k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače do úložiště USB v zařízení Android či obráceně, klepněte na tlačítko níže."</string>
<string name="usb_storage_message" product="default" msgid="805351000446037811">"Připojili jste se k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače na kartu SD v zařízení Android či obráceně, stiskněte tlačítko níže."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Zapnout úložiště USB"</string>
- <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Problém s použitím úložiště USB jako velkokapacitního úložiště USB."</string>
- <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Problém s použitím karty SD jako velkokapacitního úložiště USB."</string>
+ <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Problém s připojením úložiště USB jako disk USB."</string>
+ <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Problém s připojením karty SD jako disk USB."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB připojeno"</string>
- <string name="usb_storage_notification_message" msgid="939822783828183763">"Dotykem můžete kopírovat soubory do nebo z počítače."</string>
+ <string name="usb_storage_notification_message" msgid="939822783828183763">"Klepnutím můžete kopírovat soubory do nebo z počítače."</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Vypnout úložiště USB"</string>
- <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Dotykem vypnete úložiště USB."</string>
+ <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Klepnutím vypnete úložiště USB."</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"Úložiště USB je používáno"</string>
- <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Nejdříve úložiště USB zařízení Android v počítači odpojte (odeberte) a teprve poté jej vypněte."</string>
- <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Před vypnutím úložiště USB nejdříve kartu SD zařízení Android v počítači odpojte (odeberte)."</string>
+ <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Před vypnutím nejprve v počítači disk USB bezpečně odpojte (odeberte) a teprve poté jej zde vypněte."</string>
+ <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Před vypnutím nejprve v počítači disk USB bezpečně odpojte (odeberte) a teprve poté jej zde vypněte."</string>
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Vypnout úložiště USB"</string>
<string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Při vypínání úložiště USB došlo k chybě. Zkontrolujte, zda byl hostitel USB odpojen, a zkuste to znovu."</string>
+
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Zapnout úložiště USB"</string>
- <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Pokud zapnete úložiště USB, dojde k zastavení některých používaných aplikací. Tyto aplikace pravděpodobně nebudou k dispozici až do vypnutí úložiště USB."</string>
+ <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Pokud zapnete připojení jako disk USB, dojde k zastavení některých používaných aplikací a tyto aplikace pravděpodobně nebudou k dispozici do té doby, dokud připojení jako disk USB nevypnete."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operace rozhraní USB se nezdařila."</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Připojeno jako mediální zařízení"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Připojeno jako fotoaparát"</string>
- <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Připojeno jako instalátor"</string>
- <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Připojeno k perifernímu zařízení USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Dotykem zobrazíte další možnosti rozhraní USB."</string>
+
+ <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Připojeno jako mediální zařízení (MTP)"</string>
+ <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Připojeno jako fotoaparát (PTP)"</string>
+ <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Připojeno pro instalaci"</string>
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Připojeno jako periferní zařízení USB"</string>
+ <string name="usb_notification_message" msgid="2290859399983720271">"Klepnutím zobrazíte další možnosti rozhraní USB."</string>
+
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formátovat úložiště USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formátovat kartu SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Všechny soubory uložené v úložišti USB budou vymazány. Tuto akci nelze vrátit zpět."</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Všechna data na kartě budou ztracena."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Formátovat"</string>
+
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Klepnutím zakážete ladění USB."</string>
+
<string name="select_input_method" msgid="4653387336791222978">"Vybrat metodu zadávání"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody zadávání"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnice"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
<string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Výběr rozložení klávesnice"</string>
- <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotykem vyberte rozložení klávesnice."</string>
- <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
- <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Klepnutím vyberte rozložení klávesnice."</string>
+
+ <string name="fast_scroll_alphabet" msgid="5433275485499039199">"\u0020AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
+ <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">"\u00200123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
+
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
+
<string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Příprava úložiště USB"</string>
<string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Příprava karty SD"</string>
<string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Kontrola chyb."</string>
<string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Prázdné úložiště USB"</string>
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Prázdná karta SD"</string>
- <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"Úložiště USB je prázdné nebo obsahuje nepodporovaný systém souborů."</string>
- <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"Karta SD je prázdná nebo obsahuje nepodporovaný systém souborů."</string>
+ <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"Úložiště USB je prázdné nebo obsahuje nepodporovaný souborový systém."</string>
+ <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"Karta SD je prázdná nebo obsahuje nepodporovaný souborový systém."</string>
<string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Úložiště USB je poškozeno"</string>
- <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Poškozená karta SD"</string>
+ <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Karta SD je poškozena"</string>
<string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"Úložiště USB je poškozeno. Zkuste ho přeformátovat."</string>
<string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"Karta SD je poškozena. Zkuste ji přeformátovat."</string>
- <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Úložiště USB nečekaně odebráno"</string>
+ <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Úložiště USB bylo nečekaně odebráno"</string>
<string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Karta SD byla neočekávaně odebrána"</string>
<string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Před odebráním úložiště USB ho nejprve odpojte. Zabráníte tak ztrátě dat."</string>
- <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Chcete-li zabránit ztrátě dat, kartu SD před odebráním odpojte."</string>
- <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"Úložiště USB lze odebrat"</string>
- <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"Kartu SD je možné bezpečně odebrat"</string>
+ <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Před odebráním karty SD ji nejprve odpojte. Zabráníte tak ztrátě dat."</string>
+ <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"Úložiště USB můžete odebrat"</string>
+ <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"Kartu SD můžete odebrat"</string>
<string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Úložiště USB lze bezpečně odebrat."</string>
<string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"Kartu SD lze bezpečně odebrat."</string>
- <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Úložiště USB odebráno"</string>
- <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Karta SD byla odstraněna"</string>
+ <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Úložiště USB bylo odebráno"</string>
+ <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Karta SD byla odebrána</string>
<string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"Úložiště USB odebráno. Vložte nové médium."</string>
<string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"Karta SD byla odebrána. Vložte novou kartu."</string>
+
<string name="activity_list_empty" msgid="1675388330786841066">"Nebyly nalezeny žádné odpovídající aktivity."</string>
- <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"aktualizovat statistiku použití součástí"</string>
- <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Umožňuje aplikaci upravit shromážděné statistiky využití komponent. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"aktualizovat statistiku využití komponent"</string>
+ <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Umožňuje upravit shromážděné statistiky využití komponent. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_copyProtectedData" msgid="4341036311211406692">"kopírování obsahu"</string>
- <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje aplikaci dát výchozí službě kontejneru příkaz ke zkopírování obsahu. Toto oprávnění není určeno pro běžné aplikace."</string>
- <string name="permlab_route_media_output" msgid="1642024455750414694">"Směrování výstupu médií"</string>
- <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikaci směrovat výstup médií do dalších externích zařízení."</string>
- <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvojitým dotykem můžete ovládat přiblížení"</string>
+ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje dát výchozí službě kontejneru příkaz ke zkopírování obsahu. Toto oprávnění není určeno pro běžné aplikace."</string>
+ <string name="permlab_route_media_output" msgid="1642024455750414694">"směrování výstupu médií"</string>
+ <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje směrovat výstup médií do dalších externích zařízení."</string>
+
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvojitým klepnutím můžete ovládat přiblížení"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nelze přidat."</string>
+
<string name="ime_action_go" msgid="8320845651737369027">"Přejít"</string>
<string name="ime_action_search" msgid="658110271822807811">"Hledat"</string>
<string name="ime_action_send" msgid="2316166556349314424">"Odeslat"</string>
@@ -1233,8 +1357,10 @@
<string name="ime_action_done" msgid="8971516117910934605">"Hotovo"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"Předch."</string>
<string name="ime_action_default" msgid="2840921885558045721">"Spustit"</string>
+
<string name="dial_number_using" msgid="5789176425167573586">"Vytočit číslo"\n" <xliff:g id="NUMBER">%s</xliff:g>."</string>
<string name="create_contact_using" msgid="4947405226788104538">"Vytvořit kontakt"\n"pro <xliff:g id="NUMBER">%s</xliff:g>."</string>
+
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Následující aplikace požadují oprávnění k přístupu do vašeho účtu (nyní i v budoucnu)."</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Chcete tento požadavek povolit?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"Žádost o přístup"</string>
@@ -1242,45 +1368,54 @@
<string name="deny" msgid="2081879885755434506">"Odepřít"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"Požadováno oprávnění"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Požadováno oprávnění"\n"pro účet <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
- <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda zadávání dat"</string>
+
+ <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda vstupu"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Synchronizace"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Usnadnění"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Změnit tapetu"</string>
+
<string name="vpn_title" msgid="19615213552042827">"Síť VPN je aktivována"</string>
<string name="vpn_title_long" msgid="6400714798049252294">"Aplikace <xliff:g id="APP">%s</xliff:g> aktivovala síť VPN"</string>
- <string name="vpn_text" msgid="3011306607126450322">"Dotykem zobrazíte správu sítě."</string>
- <string name="vpn_text_long" msgid="6407351006249174473">"Připojeno k relaci <xliff:g id="SESSION">%s</xliff:g>. Dotykem můžete síť spravovat."</string>
- <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Připojování k trvalé síti VPN…"</string>
+ <string name="vpn_text" msgid="3011306607126450322">"Klepnutím zobrazíte správu sítě."</string>
+ <string name="vpn_text_long" msgid="6407351006249174473">"Připojeno k relaci <xliff:g id="SESSION">%s</xliff:g>. Klepnutím můžete síť spravovat."</string>
+ <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Připojování k trvalé síti VPN\u2026"</string>
<string name="vpn_lockdown_connected" msgid="8202679674819213931">"Je připojena trvalá síť VPN"</string>
<string name="vpn_lockdown_error" msgid="6009249814034708175">"Chyba trvalé sítě VPN"</string>
<string name="vpn_lockdown_reset" msgid="5365010427963548932">"Klepnutím resetujete připojení"</string>
+
<string name="upload_file" msgid="2897957172366730416">"Zvolit soubor"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Není vybrán žádný soubor"</string>
<string name="reset" msgid="2448168080964209908">"Resetovat"</string>
<string name="submit" msgid="1602335572089911941">"Odeslat"</string>
+
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Aktivován režim V autě"</string>
- <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Dotykem ukončíte režim V autě."</string>
- <string name="tethered_notification_title" msgid="3146694234398202601">"Je aktivní tethering nebo hotspot"</string>
- <string name="tethered_notification_message" msgid="6857031760103062982">"Dotykem nastavíte."</string>
+ <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Klepnutím ukončíte režim V autě."</string>
+ <string name="tethered_notification_title" msgid="3146694234398202601">"Je aktivní sdílené spojení nebo hotspot"</string>
+ <string name="tethered_notification_message" msgid="6857031760103062982">"Klepnutím provedete nastavení."</string>
+
<string name="back_button_label" msgid="2300470004503343439">"Zpět"</string>
<string name="next_button_label" msgid="1080555104677992408">"Další"</string>
<string name="skip_button_label" msgid="1275362299471631819">"Přeskočit"</string>
+
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"Vysoké využití mobilních dat"</string>
- <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Dotykem zobrazíte další informace o využití mobilních dat."</string>
+ <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Klepnutím zobrazíte další informace o využití mobilních dat."</string>
<string name="throttled_notification_title" msgid="6269541897729781332">"Byl překročen limit mobilních dat"</string>
- <string name="throttled_notification_message" msgid="5443457321354907181">"Dotykem zobrazíte další informace o využití mobilních dat."</string>
+ <string name="throttled_notification_message" msgid="5443457321354907181">"Klepnutím zobrazíte další informace o využití mobilních dat."</string>
+
<string name="no_matches" msgid="8129421908915840737">"Žádné shody"</string>
<string name="find_on_page" msgid="1946799233822820384">"Hledat na stránce"</string>
- <plurals name="matches_found">
- <item quantity="one" msgid="8167147081136579439">"1 shoda"</item>
- <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> z <xliff:g id="TOTAL">%d</xliff:g>"</item>
- </plurals>
+ <plurals name="matches_found">
+ <item quantity="one" msgid="8167147081136579439">"1 shoda"</item>
+ <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> z <xliff:g id="TOTAL">%d</xliff:g>"</item>
+ </plurals>
+
<string name="action_mode_done" msgid="7217581640461922289">"Hotovo"</string>
- <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Odpojování úložiště USB..."</string>
- <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Odpojování karty SD..."</string>
- <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Mazání úložiště USB..."</string>
- <string name="progress_erasing" product="default" msgid="6596988875507043042">"Mazání karty SD..."</string>
+
+ <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Odpojování úložiště USB\u2026"</string>
+ <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Odpojování karty SD\u2026"</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Mazání úložiště USB\u2026"</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"Mazání karty SD\u2026"</string>
<string name="format_error" product="nosdcard" msgid="6299769563624776948">"Úložiště USB nelze smazat."</string>
<string name="format_error" product="default" msgid="7315248696644510935">"Kartu SD nelze smazat."</string>
<string name="media_bad_removal" msgid="7960864061016603281">"Karta SD nebyla před odebráním odpojena."</string>
@@ -1290,28 +1425,32 @@
<string name="media_shared" product="nosdcard" msgid="5830814349250834225">"Úložiště USB je momentálně používáno počítačem."</string>
<string name="media_shared" product="default" msgid="5706130568133540435">"Karta SD je momentálně používána počítačem."</string>
<string name="media_unknown_state" msgid="729192782197290385">"Neznámý stav externího média."</string>
+
<string name="share" msgid="1778686618230011964">"Sdílet"</string>
<string name="find" msgid="4808270900322985960">"Najít"</string>
<string name="websearch" msgid="4337157977400211589">"Vyhledat na webu"</string>
<string name="find_next" msgid="5742124618942193978">"Najít další"</string>
<string name="find_previous" msgid="2196723669388360506">"Najít předchozí"</string>
+
<string name="gpsNotifTicker" msgid="5622683912616496172">"Požadavek na informace o poloze od uživatele <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="gpsNotifTitle" msgid="5446858717157416839">"Požadavek na informace o poloze"</string>
<string name="gpsNotifMessage" msgid="1374718023224000702">"Požadavek od uživatele <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
<string name="gpsVerifYes" msgid="2346566072867213563">"Ano"</string>
<string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
+
<string name="sync_too_many_deletes" msgid="5296321850662746890">"Byl překročen limit mazání."</string>
<string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Počet smazaných položek pro <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> (účet <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>): <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Co chcete dělat?"</string>
<string name="sync_really_delete" msgid="2572600103122596243">"Smazat položky."</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"Vrátit mazání zpět"</string>
- <string name="sync_do_nothing" msgid="3743764740430821845">"Zatím nic neprovádět."</string>
+ <string name="sync_do_nothing" msgid="3743764740430821845">"Nic neprovádět."</string>
+
<string name="choose_account_label" msgid="5655203089746423927">"Vybrat účet"</string>
<string name="add_account_label" msgid="2935267344849993553">"Přidat účet"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Přidat účet"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"Zvýšit"</string>
<string name="number_picker_decrement_button" msgid="476050778386779067">"Snížit"</string>
- <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotkněte se a podržte."</string>
- <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Chcete-li hodnotu zvýšit, přijeďte prstem nahoru, chcete-li hodnotu snížit, přejeďte prstem dolů."</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> klepněte a podržte."</string>
+ <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Chcete-li hodnotu zvýšit, přejeďte prstem nahoru, chcete-li hodnotu snížit, přejeďte prstem dolů."</string>
<string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Přidat minutu"</string>
<string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Ubrat minutu"</string>
<string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Přidat hodinu"</string>
@@ -1324,6 +1463,7 @@
<string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Ubrat den"</string>
<string name="date_picker_increment_year_button" msgid="6318697384310808899">"Přidat rok"</string>
<string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Ubrat rok"</string>
+
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
<string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Zrušit"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Smazat"</string>
@@ -1331,10 +1471,12 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Změna režimu"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+
<string name="activitychooserview_choose_application" msgid="2125168057199941199">"Vybrat aplikaci"</string>
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Sdílet s"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Sdílet s aplikací <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvník. Dotkněte se a podržte."</string>
+
<string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_down" msgid="5087739728639014595">"Přejeďte prstem dolů: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -1345,33 +1487,38 @@
<string name="description_target_soundon" msgid="30052466675500172">"Zapnout zvuk"</string>
<string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"Odemknete posunutím prstu."</string>
+
<string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Chcete-li slyšet, které klávesy jste při zadávání hesla stiskli, připojte sluchátka."</string>
<string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Tečka."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Přejít na plochu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Přejít nahoru"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Další možnosti"</string>
+
<string name="storage_internal" msgid="4891916833657929263">"Interní úložiště"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
+ <string name="storage_sd_dock_card">SD karta doku</string>
<string name="storage_usb" msgid="3017954059538517278">"Úložiště USB"</string>
+
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Upravit"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Upozornění na využití dat"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Informace o využití a nastavení"</string>
- <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Datové přenosy 2G a 3G zakázány"</string>
+ <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Datové přenosy 2G/3G zakázány"</string>
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datové přenosy 4G jsou zakázány"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilní data jsou zakázána"</string>
- <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Přenos dat přes Wi-Fi zakázán"</string>
- <string name="data_usage_limit_body" msgid="3317964706973601386">"Dotykem povolte."</string>
- <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Překročili jste limit dat 2G–3G"</string>
+ <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Přenos dat přes WiFi zakázán"</string>
+ <string name="data_usage_limit_body" msgid="3317964706973601386">"Klepnutím povolte."</string>
+ <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Překročili jste limit dat 2G/3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Překročili jste limit dat 4G."</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Překročili jste limit mobilních dat."</string>
- <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Datový limit Wi-Fi byl překročen"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Datový limit WiFi byl překročen"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> nad stanoveným limitem."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Přenos dat na pozadí je omezen"</string>
<string name="data_usage_restricted_body" msgid="6741521330997452990">"Klepnutím omezení odstraníte."</string>
+
<string name="ssl_certificate" msgid="6510040486049237639">"Certifikát zabezpečení"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Tento certifikát je platný."</string>
<string name="issued_to" msgid="454239480274921032">"Vydáno pro:"</string>
- <string name="common_name" msgid="2233209299434172646">"Běžný název:"</string>
+ <string name="common_name" msgid="2233209299434172646">"Název subjektu:"</string>
<string name="org_name" msgid="6973561190762085236">"Organizace:"</string>
<string name="org_unit" msgid="7265981890422070383">"Organizační jednotka:"</string>
<string name="issued_by" msgid="2647584988057481566">"Vydal:"</string>
@@ -1380,38 +1527,46 @@
<string name="expires_on" msgid="3676242949915959821">"Platnost vyprší:"</string>
<string name="serial_number" msgid="758814067660862493">"Sériové číslo:"</string>
<string name="fingerprints" msgid="4516019619850763049">"Digitální otisky:"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"Digitální otisk SHA-256"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"Digitální otisk SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Digitální otisk SHA-1:"</string>
+
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Zobrazit vše"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Vybrat aktivitu"</string>
+
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Sdílet s"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Zařízení je uzamčeno."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <string name="sending" msgid="3245653681008218030">"Odesílání..."</string>
+ <string name="sending" msgid="3245653681008218030">"Odesílání\u2026"</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Přijmout hovor?"</string>
+ <string name="app_killed_message">Aplikace ukončena</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
<string name="activity_resolver_use_once" msgid="2404644797149173758">"Pouze jednou"</string>
+
<string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Sluchátka"</string>
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Reproduktory doku"</string>
<string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth Audio"</string>
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Zvuk Bluetooth"</string>
+
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string>
- <string name="media_route_status_scanning" msgid="7279908761758293783">"Vyhledávání…"</string>
- <string name="media_route_status_connecting" msgid="6422571716007825440">"Připojování…"</string>
- <string name="media_route_status_available" msgid="6983258067194649391">"Dostupná"</string>
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Vyhledávání\u2026"</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Připojování\u2026"</string>
+ <string name="media_route_status_available" msgid="6983258067194649391">"Dostupné"</string>
<string name="media_route_status_not_available" msgid="6739899962681886401">"Není k dispozici"</string>
+
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Integrovaná obrazovka"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Obrazovka HDMI"</string>
- <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Překryvná vrstva č. <xliff:g id="ID">%1$d</xliff:g>"</string>
+ <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Vrstva č. <xliff:g id="ID">%1$d</xliff:g>"</string>
<string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+
<string name="wifi_display_notification_title" msgid="2223050649240326557">"Bezdrátový displej je připojen"</string>
- <string name="wifi_display_notification_message" msgid="4498802012464170685">"Tato obrazovka se zobrazuje v jiném zařízení"</string>
+ <string name="wifi_display_notification_message" msgid="4498802012464170685">"Tato obrazovka je zobrazována v jiném zařízení"</string>
<string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojit"</string>
+
<string name="kg_emergency_call_label" msgid="684946192523830531">"Tísňové volání"</string>
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zapomenuté gesto"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávné gesto"</string>
@@ -1422,15 +1577,16 @@
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadejte kód PIN SIM karty"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Zadejte kód PIN"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Zadejte heslo"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta byla deaktivována. Chcete-li pokračovat, je třeba zadat kód PUK. Podrobné informace získáte od operátora."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta byla zablokována. Chcete-li pokračovat, je třeba zadat kód PUK. Podrobné informace získáte od operátora."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Zadejte požadovaný kód PIN."</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrďte požadovaný kód PIN."</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odblokování SIM karty..."</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odemykání SIM karty\u2026"</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávný kód PIN."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadejte kód PIN o délce 4–8 číslic."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Minimální délka kódu PUK je 8 číslic."</string>
- <string name="kg_invalid_puk" msgid="3638289409676051243">"Znovu zadejte správný kód PUK. Opakovanými pokusy SIM kartu trvale deaktivujete."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Znovu zadejte správný kód PUK. Opakovanými pokusy SIM kartu trvale zablokujete."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN se neshodují."</string>
+
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Příliš mnoho pokusů o nakreslení gesta"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"Chcete-li telefon odemknout, přihlaste se pomocí svého účtu Google."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"Uživatelské jméno (e-mail)"</string>
@@ -1438,22 +1594,29 @@
<string name="kg_login_submit_button" msgid="5355904582674054702">"Přihlásit se"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné uživatelské jméno nebo heslo."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zapomněli jste uživatelské jméno nebo heslo?"\n"Přejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontrola účtu…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávný kód PIN. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
- <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontrola účtu\u2026"</string>
+
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Nesprávný kód PIN byl zadán <xliff:g id="NUMBER_0">%d</xliff:g>krát. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Nesprávné heslo bylo zadáno <xliff:g id="NUMBER_0">%d</xliff:g>krát."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Nesprávné bezpečnostní heslo bylo zadáno <xliff:g id="NUMBER_0">%d</xliff:g>krát."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Pokusili jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Pokusili jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Pokusili jste se <xliff:g id="NUMBER">%d</xliff:g>krát odemknout tablet nesprávným způsobem. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Pokusili jste se <xliff:g id="NUMBER">%d</xliff:g>krát odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Nakreslili jste špatně své heslo odemknutí <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Nakreslili jste špatně své heslo odemknutí <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu."\n\n"Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" \u2014 "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odebrat"</string>
+
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Chcete hlasitost zvýšit nad bezpečnou úroveň?"\n"Dlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
<string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Usnadnění zapnete dlouhým stisknutím dvěma prsty."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Usnadnění přístupu je aktivováno."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Usnadnění zrušeno."</string>
<string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
+
+ <string name="global_action_reboot">Restartovat</string>
+ <string name="global_action_choose_profile">Profil</string>
+ <string name="toast_rotation_unlocked">Otáčení zobrazení povoleno</string>
+ <string name="toast_rotation_locked">Otáčení zobrazení zakázáno</string>
</resources>
diff --git a/core/res/res/values-da/donottranslate-cldr.xml b/core/res/res/values-da/donottranslate-cldr.xml
index d5b9878..60af131 100644
--- a/core/res/res/values-da/donottranslate-cldr.xml
+++ b/core/res/res/values-da/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e974576..a160d7a 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1067,7 +1067,7 @@
<string name="smv_process" msgid="5120397012047462446">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> har overtrådt sin egen StrictMode-politik."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android opgraderes..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimerer app <xliff:g id="NUMBER_0">%1$d</xliff:g> ud af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Sådan åbner du dine apps."</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Åbner apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Gennemfører start."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> er i gang"</string>
<string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Tryk for at skifte til appen"</string>
@@ -1456,4 +1456,78 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgængelighed er annulleret."</string>
<string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Ejer"</string>
+
+ <!-- **** CYANOGENMOD ADDITIONS START **** -->
+
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">Standard</string>
+ <string name="profileNameWork">Arbejde</string>
+ <string name="profileNameHome">Hjem</string>
+ <string name="profileNameSilent">Lydløs</string>
+ <string name="profileNameNight">Nat</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">Telefon</string>
+ <string name="profileGroupCalendar">Kalender</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Email</string>
+ <string name="profileGroupSMS">SMS</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">Andre</string>
+
+ <!-- Button to reboot the phone, within the Phone Options dialog -->
+ <string name="reboot_system" product="tablet">Genstart tablet</string>
+ <string name="reboot_system" product="default">Genstart telefon</string>
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+
+ <!-- label for item that screenshots in phone options dialog -->
+ <string name="global_action_screenshot">Skærmbillede</string>
+
+ <!-- Expanded desktop mode -->
+ <string name="global_actions_toggle_expanded_desktop_mode">Udvidet skrivebord</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Aktiveret</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Deaktiveret</string>
+
+ <!-- Button to reboot the phone, within the Reboot Options dialog -->
+ <string name="reboot_reboot">Genstart</string>
+ <!-- Button to reboot the phone into recovery, within the Reboot Options dialog -->
+ <string name="reboot_recovery">Recovery</string>
+ <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog -->
+ <string name="reboot_bootloader">Bootloader</string>
+ <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog -->
+ <string name="reboot_bootmenu">Bootmenu</string>
+ <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog -->
+ <string name="reboot_fastboot">Fastboot</string>
+ <!-- Button to reboot the phone into download, within the Reboot Options dialog -->
+ <string name="reboot_download">Download</string>
+
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+ <string name="reboot_progress">Genstarter\u2026</string>
+ <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. -->
+ <string name="reboot_confirm">Telefonen vil genstarte.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_preventpower">Undgå tænd/sluk-knappen</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preventpower">Tillader et program at tilsidesætte tænd/sluk-knappen</string>
+
+ <!-- Lock screen discharging -->
+ <string name="lockscreen_discharging">Aflader, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+
+ <!-- Long-press back kill application -->
+ <string name="app_killed_message">Applikation lukket</string>
+
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_reboot">Genstart</string>
+
+ <!-- label for item that opens the profile choosing dialog -->
+ <string name="global_action_choose_profile">Profil</string>
+
+ <!-- Hardware Rotation lock string -->
+ <string name="toast_rotation_unlocked">Skærmrotation ulåst</string>
+ <string name="toast_rotation_locked">Skærmrotation låst</string>
+
+ <!-- **** CYANOGENMOD ADDITIONS END **** -->
+
</resources>
diff --git a/core/res/res/values-de/donottranslate-cldr.xml b/core/res/res/values-de/donottranslate-cldr.xml
index 9bdd8a3..aca3d1f 100644
--- a/core/res/res/values-de/donottranslate-cldr.xml
+++ b/core/res/res/values-de/donottranslate-cldr.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="hour_minute_24">%-k:%M</string>
@@ -8,7 +8,7 @@
<string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
- <string name="numeric_date_template">"%s.%s.%s"</string>
+ <string name="numeric_date_template">%s.%s.%s</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%d.%m.%Y, %H:%M:%S</string>
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d. MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3547321..6a72b1a 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1,22 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
+<!-- Copyright (C) 2006 The Android Open Source Project
+ Copyright (C) 2013 The CyanogenMod 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 xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
@@ -28,8 +25,8 @@
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Unbenannt&gt;"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+ <string name="ellipsis" msgid="7899829516048813237">"\u2026"</string>
+ <string name="ellipsis_two_dots" msgid="1228078994866030736">"\u2025"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Keine Telefonnummer)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Unbekannt)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Mailbox"</string>
@@ -142,7 +139,7 @@
<string name="silent_mode_silent" msgid="319298163018473078">"Klingelton aus"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Klingeltonmodus \"Vibration\""</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Klingelton ein"</string>
- <string name="shutdown_progress" msgid="2281079257329981203">"Wird heruntergefahren..."</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"Wird heruntergefahren\u2026"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ihr Tablet wird heruntergefahren."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon wird heruntergefahren."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Möchten Sie das Gerät herunterfahren?"</string>
@@ -761,7 +758,8 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Erneut versuchen"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Erneut versuchen"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Die maximal zulässige Anzahl an Face Unlock-Versuchen wurde überschritten."</string>
- <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Wird geladen... (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+ <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Wird geladen\u2026 (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+ <string name="lockscreen_discharging">"Entlädt\u2026 (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
<string name="lockscreen_charged" msgid="321635745684060624">"Aufgeladen"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Ladegerät anschließen"</string>
@@ -782,7 +780,7 @@
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"PUK-Sperre auf SIM"</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Weitere Informationen erhalten Sie im Nutzerhandbuch oder beim Kundendienst."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"PIN eingeben"</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-Karte wird entsperrt..."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-Karte wird entsperrt\u2026"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. "\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
@@ -802,7 +800,7 @@
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Anmelden"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ungültiger Nutzername oder ungültiges Passwort."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nutzernamen oder Passwort vergessen?"\n"Besuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Überprüfung..."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Überprüfung\u2026"</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Entsperren"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ton ein"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Ton aus"</string>
@@ -910,15 +908,15 @@
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Vor 1 Monat"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vor mehr als 1 Monat"</string>
<plurals name="num_seconds_ago">
- <item quantity="one" msgid="4869870056547896011">"Vor 1 Sekunde"</item>
+ <item quantity="one" msgid="4869870056547896011">"vor 1 Sekunde"</item>
<item quantity="other" msgid="3903706804349556379">"vor <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item>
</plurals>
<plurals name="num_minutes_ago">
- <item quantity="one" msgid="3306787433088810191">"Vor 1 Minute"</item>
+ <item quantity="one" msgid="3306787433088810191">"vor 1 Minute"</item>
<item quantity="other" msgid="2176942008915455116">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item>
</plurals>
<plurals name="num_hours_ago">
- <item quantity="one" msgid="9150797944610821849">"Vor 1 Stunde"</item>
+ <item quantity="one" msgid="9150797944610821849">"vor 1 Stunde"</item>
<item quantity="other" msgid="2467273239587587569">"vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
</plurals>
<plurals name="last_num_days">
@@ -927,7 +925,7 @@
<string name="last_month" msgid="3959346739979055432">"Letzter Monat"</string>
<string name="older" msgid="5211975022815554840">"Älter"</string>
<plurals name="num_days_ago">
- <item quantity="one" msgid="861358534398115820">"Gestern"</item>
+ <item quantity="one" msgid="861358534398115820">"gestern"</item>
<item quantity="other" msgid="2479586466153314633">"vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
</plurals>
<plurals name="in_num_seconds">
@@ -955,11 +953,11 @@
<item quantity="other" msgid="851164968597150710">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item>
</plurals>
<plurals name="abbrev_num_hours_ago">
- <item quantity="one" msgid="4796212039724722116">"Vor 1 Stunde"</item>
+ <item quantity="one" msgid="4796212039724722116">"vor 1 Stunde"</item>
<item quantity="other" msgid="6889970745748538901">"vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
</plurals>
<plurals name="abbrev_num_days_ago">
- <item quantity="one" msgid="8463161711492680309">"Gestern"</item>
+ <item quantity="one" msgid="8463161711492680309">"gestern"</item>
<item quantity="other" msgid="3453342639616481191">"vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
</plurals>
<plurals name="abbrev_in_num_seconds">
@@ -1020,7 +1018,7 @@
<string name="cut" msgid="3092569408438626261">"Ausschneiden"</string>
<string name="copy" msgid="2681946229533511987">"Kopieren"</string>
<string name="paste" msgid="5629880836805036433">"Einfügen"</string>
- <string name="replace" msgid="5781686059063148930">"Ersetzen..."</string>
+ <string name="replace" msgid="5781686059063148930">"Ersetzen\u2026"</string>
<string name="delete" msgid="6098684844021697789">"Löschen"</string>
<string name="copyUrl" msgid="2538211579596067402">"URL kopieren"</string>
<string name="selectTextMode" msgid="1018691815143165326">"Text auswählen"</string>
@@ -1036,7 +1034,7 @@
<string name="yes" msgid="5362982303337969312">"OK"</string>
<string name="no" msgid="5141531044935541497">"Abbrechen"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Achtung"</string>
- <string name="loading" msgid="7933681260296021180">"Wird geladen…"</string>
+ <string name="loading" msgid="7933681260296021180">"Wird geladen\u2026"</string>
<string name="capital_on" msgid="1544682755514494298">"AN"</string>
<string name="capital_off" msgid="6815870386972805832">"AUS"</string>
<string name="whichApplication" msgid="4533185947064773386">"Aktion durchführen mit"</string>
@@ -1065,10 +1063,10 @@
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"Eine erneute Aktivierung ist in den Systemeinstellungen unter \"Apps &gt; Heruntergeladen\" möglich."</string>
<string name="smv_application" msgid="3307209192155442829">"Die App <xliff:g id="APPLICATION">%1$s</xliff:g> (Prozess <xliff:g id="PROCESS">%2$s</xliff:g>) hat gegen ihre selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
<string name="smv_process" msgid="5120397012047462446">"Der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> hat gegen seine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
- <string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert..."</string>
- <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
- <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet..."</string>
- <string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert\u2026"</string>
+ <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert\u2026"</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet\u2026"</string>
+ <string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen\u2026"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> läuft"</string>
<string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Zum Wechseln in die App berühren"</string>
<string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Apps wechseln?"</string>
@@ -1195,7 +1193,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
<string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB-Speicher wird vorbereitet."</string>
- <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD-Karte wird vorbereitet..."</string>
+ <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD-Karte wird vorbereitet\u2026"</string>
<string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Suche nach Fehlern"</string>
<string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"USB-Speicher leer"</string>
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"SD-Karte leer"</string>
@@ -1251,7 +1249,7 @@
<string name="vpn_title_long" msgid="6400714798049252294">"VPN wurde von <xliff:g id="APP">%s</xliff:g> aktiviert."</string>
<string name="vpn_text" msgid="3011306607126450322">"Zum Verwalten des Netzwerks berühren"</string>
<string name="vpn_text_long" msgid="6407351006249174473">"Verbunden mit <xliff:g id="SESSION">%s</xliff:g>. Zum Verwalten des Netzwerks berühren"</string>
- <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Verbindung zu durchgehend aktivem VPN wird hergestellt…"</string>
+ <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Verbindung zu durchgehend aktivem VPN wird hergestellt\u2026"</string>
<string name="vpn_lockdown_connected" msgid="8202679674819213931">"Mit durchgehend aktivem VPN verbunden"</string>
<string name="vpn_lockdown_error" msgid="6009249814034708175">"Durchgehend aktives VPN – Verbindungsfehler"</string>
<string name="vpn_lockdown_reset" msgid="5365010427963548932">"Zum Zurücksetzen der Verbindung tippen"</string>
@@ -1277,10 +1275,10 @@
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> von <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Fertig"</string>
- <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB-Speicher wird getrennt..."</string>
- <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD-Karte wird getrennt..."</string>
- <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB-Speicher wird gelöscht..."</string>
- <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD-Karteninhalt wird gelöscht..."</string>
+ <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB-Speicher wird getrennt\u2026"</string>
+ <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD-Karte wird getrennt\u2026"</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB-Speicher wird gelöscht\u2026"</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD-Karteninhalt wird gelöscht\u2026"</string>
<string name="format_error" product="nosdcard" msgid="6299769563624776948">"Löschen des USB-Speichers nicht möglich"</string>
<string name="format_error" product="default" msgid="7315248696644510935">"Löschen der SD-Karte nicht möglich"</string>
<string name="media_bad_removal" msgid="7960864061016603281">"SD-Karte wurde vor dem Trennvorgang entfernt."</string>
@@ -1387,7 +1385,7 @@
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Teilen mit"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Gerät gesperrt"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <string name="sending" msgid="3245653681008218030">"Wird gesendet..."</string>
+ <string name="sending" msgid="3245653681008218030">"Wird gesendet\u2026"</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Anruf annehmen?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Immer"</string>
@@ -1401,8 +1399,8 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-Audio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fertig"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medienausgabe"</string>
- <string name="media_route_status_scanning" msgid="7279908761758293783">"Wird gescannt..."</string>
- <string name="media_route_status_connecting" msgid="6422571716007825440">"Verbindung wird hergestellt..."</string>
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Wird gescannt\u2026"</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Verbindung wird hergestellt\u2026"</string>
<string name="media_route_status_available" msgid="6983258067194649391">"Verfügbar"</string>
<string name="media_route_status_not_available" msgid="6739899962681886401">"Nicht verfügbar"</string>
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Integrierter Bildschirm"</string>
@@ -1425,7 +1423,7 @@
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Die SIM-Karte ist jetzt deaktiviert. Geben Sie den PUK-Code ein, um fortzufahren. Weitere Informationen erhalten Sie von Ihrem Mobilfunkanbieter."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewünschten PIN-Code eingeben"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewünschten PIN-Code bestätigen"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-Karte wird entsperrt…"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-Karte wird entsperrt\u2026"</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Falscher PIN-Code"</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Geben Sie eine 4- bis 8-stellige PIN ein."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Der PUK-Code muss mindestens 8 Ziffern betragen."</string>
@@ -1438,7 +1436,7 @@
<string name="kg_login_submit_button" msgid="5355904582674054702">"Anmelden"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Ungültiger Nutzername oder ungültiges Passwort"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nutzernamen oder Passwort vergessen?"\n"Besuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto wird geprüft…"</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto wird geprüft\u2026"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Sie haben Ihre PIN <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. "\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
@@ -1456,4 +1454,65 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Bedienungshilfen abgebrochen"</string>
<string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"Eigentümer"</string>
+
+ <!-- **** CYANOGENMOD ADDITIONS START **** -->
+
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">Standard</string>
+ <string name="profileNameWork">Arbeit</string>
+ <string name="profileNameHome">Zu Hause</string>
+ <string name="profileNameSilent">Lautlos</string>
+ <string name="profileNameNight">Nacht</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">Telefon</string>
+ <string name="profileGroupCalendar">Kalender</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">E-Mail</string>
+ <string name="profileGroupSMS">SMS/MMS</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">Anderes</string>
+
+ <!-- Button to reboot the phone -->
+ <string name="reboot_system" product="tablet">Tablet neu starten</string>
+ <string name="reboot_system" product="default">Telefon neu starten</string>
+
+ <!-- Screenshots label in phone options -->
+ <string name="global_action_screenshot">Bildschirmfoto</string>
+
+ <!-- Expand desktop mode -->
+ <string name="global_actions_toggle_expanded_desktop_mode">Erweiterter Desktop</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Aktiviert</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Deaktiviert</string>
+
+ <!-- Reboot menu -->
+ <string name="reboot_reboot">Neu starten</string>
+ <string name="reboot_recovery">Recovery</string>
+ <string name="reboot_bootloader">Bootloader</string>
+ <string name="reboot_bootmenu">Bootmenü</string>
+ <string name="reboot_fastboot">Fastboot</string>
+ <string name="reboot_download">Download</string>
+
+ <!-- Reboot Progress Dialog -->
+ <string name="reboot_progress">Neu starten\u2026</string>
+
+ <!-- Reboot Confirmation Dialog -->
+ <string name="reboot_confirm" product="tablet">Tablet wird neu gestartet</string>
+ <string name="reboot_confirm" product="default">Telefon wird neu gestartet</string>
+
+ <!-- Reboot label in phone options -->
+ <string name="global_action_reboot">Neu starten</string>
+
+ <!-- Profile choosing label -->
+ <string name="global_action_choose_profile">Profile</string>
+
+ <!-- Long-press back kill application -->
+ <string name="app_killed_message">Anwendung beendet</string>
+
+ <!-- Hardware rotation lock string -->
+ <string name="toast_rotation_unlocked">Bildschirmausrichtung sperren</string>
+ <string name="toast_rotation_locked">Bildschirmausrichtung entsperren</string>
+
+ <!-- **** CYANOGENMOD ADDITIONS END **** -->
</resources>
diff --git a/core/res/res/values-el/donottranslate-cldr.xml b/core/res/res/values-el/donottranslate-cldr.xml
index a0c69b5..87c84f9 100644
--- a/core/res/res/values-el/donottranslate-cldr.xml
+++ b/core/res/res/values-el/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 70c1550..154fdb8 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -28,8 +28,8 @@
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Χωρίς τίτλο&gt;"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+ <string name="ellipsis" msgid="7899829516048813237">"\u2026"</string>
+ <string name="ellipsis_two_dots" msgid="1228078994866030736">"\u2025"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Δεν υπάρχει τηλεφωνικός αριθμός)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Άγνωστο)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Αυτόματος τηλεφωνητής"</string>
@@ -142,7 +142,7 @@
<string name="silent_mode_silent" msgid="319298163018473078">"Ειδοποίηση ήχου ανενεργή"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Δόνηση ειδοποίησης ήχου"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Ειδοποίηση ήχου ενεργή"</string>
- <string name="shutdown_progress" msgid="2281079257329981203">"Απενεργοποίηση..."</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"Απενεργοποίηση\u2026"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Το tablet σας θα απενεργοποιηθεί."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Το τηλέφωνό σας θα απενεργοποιηθεί."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Θέλετε να γίνει τερματισμός λειτουργίας;"</string>
@@ -762,9 +762,10 @@
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Προσπαθήστε ξανά"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Έγινε υπέρβαση του μέγιστου αριθμού προσπαθειών Face Unlock"</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Φόρτιση, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_discharging">Αποφόρτιση, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<string name="lockscreen_charged" msgid="321635745684060624">"Μπαταρία πλήρης"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <string name="lockscreen_low_battery" msgid="1482873981919249740">"Συνδέστε τον φορτιστή."</string>
+ <string name="lockscreen_low_battery" msgid="1482873981919249740">"Συνδέστε τον φορτιστή, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Δεν υπάρχει κάρτα SIM"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Δεν υπάρχει κάρτα SIM στο tablet."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Δεν υπάρχει κάρτα SIM στο τηλέφωνο."</string>
@@ -782,7 +783,7 @@
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Η κάρτα SIM είναι κλειδωμένη με κωδικό PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Ανατρέξτε στον Οδηγό χρήσης ή επικοινωνήστε με την Εξυπηρέτηση πελατών."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Η κάρτα SIM είναι κλειδωμένη."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ξεκλείδωμα κάρτας SIM..."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ξεκλείδωμα κάρτας SIM\u2026"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος<xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Προσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Προσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Έχετε πληκτρολογήσει τον αριθμό σας PIN εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Προσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
@@ -802,7 +803,7 @@
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Σύνδεση"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Ξεχάσατε το όνομα χρήστη ή τον κωδικό πρόσβασής σας;"\n"Επισκεφτείτε τη διεύθυνση "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Έλεγχος..."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Έλεγχος\u2026"</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ξεκλείδωμα"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ενεργοποίηση ήχου"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Απενεργοποίηση ήχου"</string>
@@ -1020,7 +1021,7 @@
<string name="cut" msgid="3092569408438626261">"Αποκοπή"</string>
<string name="copy" msgid="2681946229533511987">"Αντιγραφή"</string>
<string name="paste" msgid="5629880836805036433">"Επικόλληση"</string>
- <string name="replace" msgid="5781686059063148930">"Αντικατάσταση..."</string>
+ <string name="replace" msgid="5781686059063148930">"Αντικατάσταση\u2026"</string>
<string name="delete" msgid="6098684844021697789">"Διαγραφή"</string>
<string name="copyUrl" msgid="2538211579596067402">"Αντιγραφή διεύθυνσης URL"</string>
<string name="selectTextMode" msgid="1018691815143165326">"Επιλογή κειμένου"</string>
@@ -1065,7 +1066,7 @@
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"Ενεργοποιήστε το ξανά στις Ρυθμίσεις συστημάτων &gt; Εφαρμογές &gt; Ληφθείσες."</string>
<string name="smv_application" msgid="3307209192155442829">"Η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> (διεργασία <xliff:g id="PROCESS">%2$s</xliff:g>) παραβίασε την αυτοεπιβαλλόμενη πολιτική StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Η διεργασία <xliff:g id="PROCESS">%1$s</xliff:g> παραβίασε την αυτοεπιβαλόμενη πολιτική StrictMode."</string>
- <string name="android_upgrading_title" msgid="1584192285441405746">"Το Android αναβαθμίζεται..."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Το Android αναβαθμίζεται\u2026"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Βελτιστοποίηση της εφαρμογής <xliff:g id="NUMBER_0">%1$d</xliff:g> από <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Έναρξη εφαρμογών."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Ολοκλήρωση εκκίνησης."</string>
@@ -1183,8 +1184,8 @@
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Όλα τα αρχεία που είναι αποθηκευμένα στον αποθηκευτικό σας χώρο USB θα διαγραφούν. Αυτή η ενέργεια δεν είναι αναστρέψιμη!"</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Όλα τα δεδομένα που υπάρχουν στην κάρτα σας θα χαθούν."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Διαμόρφωση"</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Αγγίξτε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Αγγίξτε για απενεργοποίηση του εντοπισμού σφαλμάτων."</string>
<string name="select_input_method" msgid="4653387336791222978">"Επιλογή μεθόδου εισόδου"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Ρύθμιση μεθόδων εισαγωγής"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Φυσικό πληκτρολόγιο"</string>
@@ -1277,10 +1278,10 @@
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> από <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Ολοκληρώθηκε"</string>
- <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Αποσύνδεση του χώρου αποθήκευσης USB..."</string>
- <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Αφαίρεση κάρτας SD..."</string>
- <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Διαγραφή χώρου αποθήκευσης USB..."</string>
- <string name="progress_erasing" product="default" msgid="6596988875507043042">"Διαγραφή κάρτας SD..."</string>
+ <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Αποσύνδεση του χώρου αποθήκευσης USB\u2026"</string>
+ <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Αφαίρεση κάρτας SD\u2026"</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Διαγραφή χώρου αποθήκευσης USB\u2026"</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"Διαγραφή κάρτας SD\u2026"</string>
<string name="format_error" product="nosdcard" msgid="6299769563624776948">"Δεν ήταν δυνατή η διαγραφή του χώρου αποθήκευσης USB."</string>
<string name="format_error" product="default" msgid="7315248696644510935">"Δεν ήταν δυνατή η διαγραφή της κάρτας SD."</string>
<string name="media_bad_removal" msgid="7960864061016603281">"Η κάρτα SD καταργήθηκε πριν την αποπροσάρτησή της."</string>
@@ -1425,7 +1426,7 @@
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Η κάρτα SIM είναι απενεργοποιημένη αυτή τη στιγμή. Εισαγάγετε τον κωδικό PUK για να συνεχίσετε. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας σας για λεπτομέρειες."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Εισαγάγετε τον απαιτούμενο κωδικό PIN"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Επιβεβαιώστε τον απαιτούμενο κωδικό PIN"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ξεκλείδωμα κάρτας SIM..."</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ξεκλείδωμα κάρτας SIM\u2026"</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Εσφαλμένος κωδικός PIN."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Πληκτρολογήστε έναν αριθμό PIN που να αποτελείται από 4 έως 8 αριθμούς."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Ο κωδικός PUK θα πρέπει να περιέχει τουλάχιστον 8 αριθμούς."</string>
@@ -1438,7 +1439,7 @@
<string name="kg_login_submit_button" msgid="5355904582674054702">"Σύνδεση"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ξεχάσατε το όνομα χρήστη ή τον κωδικό πρόσβασής σας;"\n"Επισκεφτείτε τη διεύθυνση "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="kg_login_checking_password" msgid="1052685197710252395">"Έλεγχος λογαριασμού…"</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Έλεγχος λογαριασμού\u2026"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Έχετε πληκτρολογήσει εσφαλμένα τον κωδικό σας PIN <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλετπα."</string>
@@ -1456,4 +1457,73 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Η λειτουργία προσβασιμότητας ακυρώθηκε."</string>
<string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Κάτοχος"</string>
+
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">Προεπιλογή</string>
+ <string name="profileNameWork">Εργασία</string>
+ <string name="profileNameHome">Σπίτι</string>
+ <string name="profileNameSilent">Αθορυβο</string>
+ <string name="profileNameNight">Νύχτα</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">Τηλέφωνο</string>
+ <string name="profileGroupCalendar">Ημερολόγιο</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Email</string>
+ <string name="profileGroupSMS">SMS</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">Άλλο</string>
+
+ <!-- Button to reboot the phone, within the Phone Options dialog -->
+ <string name="reboot_system" product="tablet">Επανεκκίνηση tablet</string>
+ <string name="reboot_system" product="default">Επανεκκίνηση τηλεφώνου</string>
+
+ <!-- label for item that screenshots in phone options dialog -->
+ <string name="global_action_screenshot">Στιγμιότυπο οθόνης</string>
+
+ <!-- label for item that toggles expand desktop mode -->
+ <string name="global_actions_toggle_expanded_desktop_mode">Επέκταση επιφάνειας</string>
+ <!-- status message in phone options dialog for when expand desktop mode is on -->
+ <string name="global_actions_expanded_desktop_mode_on_status">Ενεργή</string>
+ <!-- status message in phone options dialog for when expand desktop mode is off -->
+ <string name="global_actions_expanded_desktop_mode_off_status">Ανενεργή</string>
+
+ <!-- Button to reboot the phone, within the Reboot Options dialog -->
+ <string name="reboot_reboot">Επανεκκίνηση</string>
+ <!-- Button to reboot the phone into recovery, within the Reboot Options dialog -->
+ <string name="reboot_recovery">Recovery</string>
+ <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog -->
+ <string name="reboot_bootloader">Bootloader</string>
+ <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog -->
+ <string name="reboot_bootmenu">Bootmenu</string>
+ <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog -->
+ <string name="reboot_fastboot">Fastboot</string>
+ <!-- Button to reboot the phone into download, within the Reboot Options dialog -->
+ <string name="reboot_download">Download</string>
+
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+ <string name="reboot_progress">Επανεκκίνηση\u2026</string>
+ <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. -->
+ <string name="reboot_confirm" product="tablet">Το tablet σας θα κάνει επανεκκίνηση.</string>
+ <string name="reboot_confirm" product="default">Το τηλέφωνό σας θα κάνει επανεκκίνηση.</string>
+
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_reboot">Επανεκκίνηση</string>
+
+ <!-- label for item that opens the profile choosing dialog -->
+ <string name="global_action_choose_profile">Προφίλ</string>
+
+ <!-- Long-press back kill application -->
+ <string name="app_killed_message">Η εφαρμογή τερματίστηκε</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_preventpower">Παράκαμψη πλήκτρου λειτουργίας</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preventpower">Επιτρέπει σε μια εφαρμογή να χρησιμοποιήσει το πλήκτρο λειτουργίας για μια διαφορετική λειτουργία</string>
+
+ <!-- Hardware Rotation lock string -->
+ <string name="toast_rotation_unlocked">Η περιστροφή οθόνης ξεκλειδώθηκε</string>
+ <string name="toast_rotation_locked">Η περιστροφή οθόνης κλειδώθηκε</string>
+
</resources>
diff --git a/core/res/res/values-en-rAU/donottranslate-cldr.xml b/core/res/res/values-en-rAU/donottranslate-cldr.xml
index 947fe92..ae5ba81 100644
--- a/core/res/res/values-en-rAU/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rAU/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">E, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-en-rGB/donottranslate-cldr.xml b/core/res/res/values-en-rGB/donottranslate-cldr.xml
index a10dfa50..aa430bd 100644
--- a/core/res/res/values-en-rGB/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rGB/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">E, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-en-rIE/donottranslate-cldr.xml b/core/res/res/values-en-rIE/donottranslate-cldr.xml
index 65cab99..5e4c123 100644
--- a/core/res/res/values-en-rIE/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rIE/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">E d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-en-rIN/donottranslate-cldr.xml b/core/res/res/values-en-rIN/donottranslate-cldr.xml
index 48942fe..9304ef0 100644
--- a/core/res/res/values-en-rIN/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rIN/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">E d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-en-rNZ/donottranslate-cldr.xml b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
index 117dda8..a9a4e21 100644
--- a/core/res/res/values-en-rNZ/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">E, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-en-rZA/donottranslate-cldr.xml b/core/res/res/values-en-rZA/donottranslate-cldr.xml
index 48ebc6e..3d6b24f 100644
--- a/core/res/res/values-en-rZA/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rZA/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">E dd MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-es-rUS/donottranslate-cldr.xml b/core/res/res/values-es-rUS/donottranslate-cldr.xml
index 9224786..7e3dc56 100644
--- a/core/res/res/values-es-rUS/donottranslate-cldr.xml
+++ b/core/res/res/values-es-rUS/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_year">E d \'de\' MMM \'de\' yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd \'de\' MMMM</string>
</resources>
diff --git a/core/res/res/values-es/donottranslate-cldr.xml b/core/res/res/values-es/donottranslate-cldr.xml
index 0a680b6..877587a 100644
--- a/core/res/res/values-es/donottranslate-cldr.xml
+++ b/core/res/res/values-es/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d \'de\' MMM \'de\' yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd \'de\' MMMM</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 824b42a..c18021e 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -28,8 +28,8 @@
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sin título&gt;"</string>
- <string name="ellipsis" msgid="7899829516048813237">"…"</string>
- <string name="ellipsis_two_dots" msgid="1228078994866030736">"..."</string>
+ <string name="ellipsis" msgid="7899829516048813237">"\u2026"</string>
+ <string name="ellipsis_two_dots" msgid="1228078994866030736">"\u2025"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Sin número de teléfono)"</string>
<string name="unknownName" msgid="2277556546742746522">"Desconocido"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Buzón de voz"</string>
@@ -142,7 +142,7 @@
<string name="silent_mode_silent" msgid="319298163018473078">"Timbre desactivado"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Modo vibración"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Timbre activado"</string>
- <string name="shutdown_progress" msgid="2281079257329981203">"Apagando..."</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"Apagando\u2026"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"El tablet se apagará."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"El teléfono se apagará."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"¿Seguro que quieres apagar el teléfono?"</string>
@@ -761,7 +761,7 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Vuelve a intentarlo"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Vuelve a intentarlo"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se ha superado el número máximo de intentos de desbloqueo facial."</string>
- <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Cargando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+ <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Cargando, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_charged" msgid="321635745684060624">"Cargado"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta el cargador"</string>
@@ -782,7 +782,7 @@
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La tarjeta SIM está bloqueada con el código PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guía del usuario o ponte en contacto con el servicio de atención al cliente."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Introduce el código PIN."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando tarjeta SIM..."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando tarjeta SIM\u2026"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación de un patrón de desbloqueo. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
@@ -802,7 +802,7 @@
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Iniciar sesión"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña no válido"</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Si has olvidado tu nombre de usuario o tu contraseña,"\n"accede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
- <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Comprobando..."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Comprobando\u2026"</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Activar sonido"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Desactivar sonido"</string>
@@ -1020,7 +1020,7 @@
<string name="cut" msgid="3092569408438626261">"Cortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Pegar"</string>
- <string name="replace" msgid="5781686059063148930">"Sustituir..."</string>
+ <string name="replace" msgid="5781686059063148930">"Sustituir\u2026"</string>
<string name="delete" msgid="6098684844021697789">"Eliminar"</string>
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="1018691815143165326">"Seleccionar texto"</string>
@@ -1036,7 +1036,7 @@
<string name="yes" msgid="5362982303337969312">"Aceptar"</string>
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
- <string name="loading" msgid="7933681260296021180">"Cargando..."</string>
+ <string name="loading" msgid="7933681260296021180">"Cargando\u2026"</string>
<string name="capital_on" msgid="1544682755514494298">"SÍ"</string>
<string name="capital_off" msgid="6815870386972805832">"NO"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar acción utilizando"</string>
@@ -1066,9 +1066,9 @@
<string name="smv_application" msgid="3307209192155442829">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) ha infringido su política StrictMode autoaplicable."</string>
<string name="smv_process" msgid="5120397012047462446">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha infringido su política StrictMode autoaplicable."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Actualizando Android"</string>
- <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>..."</string>
+ <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>\u2026"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
- <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando inicio..."</string>
+ <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando inicio\u2026"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
<string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Toca esta opción para cambiar a la aplicación."</string>
<string name="heavy_weight_switcher_title" msgid="7153167085403298169">"¿Cambiar aplicaciones?"</string>
@@ -1126,7 +1126,7 @@
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="wifi_p2p_frequency_conflict_message" msgid="7363907213787469151">"El teléfono se desconectará temporalmente de la red Wi-Fi mientras está conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="select_character" msgid="3365550120617701745">"Insertar carácter"</string>
- <string name="sms_control_title" msgid="7296612781128917719">"Enviando mensajes SMS..."</string>
+ <string name="sms_control_title" msgid="7296612781128917719">"Enviando mensajes SMS\u2026"</string>
<string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; está enviando un gran número de mensajes SMS. ¿Quieres permitir que está aplicación siga enviando mensajes?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
<string name="sms_control_no" msgid="625438561395534982">"Denegar"</string>
@@ -1196,7 +1196,7 @@
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
<string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Preparando almacenamiento USB"</string>
<string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Preparando tarjeta SD"</string>
- <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Comprobando errores..."</string>
+ <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Comprobando errores\u2026"</string>
<string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Almacenamiento USB vacío"</string>
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Tarjeta SD vacía"</string>
<string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"Almacenamiento USB vacío o con sistema de archivos no admitido"</string>
@@ -1277,10 +1277,10 @@
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Listo"</string>
- <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Desactivando almacenamiento USB..."</string>
- <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Desactivando tarjeta SD..."</string>
- <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Borrando almacenamiento USB..."</string>
- <string name="progress_erasing" product="default" msgid="6596988875507043042">"Borrando tarjeta SD..."</string>
+ <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Desactivando almacenamiento USB\u2026"</string>
+ <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Desactivando tarjeta SD\u2026"</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Borrando almacenamiento USB\u2026"</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"Borrando tarjeta SD\u2026"</string>
<string name="format_error" product="nosdcard" msgid="6299769563624776948">"No se ha podido borrar el almacenamiento USB."</string>
<string name="format_error" product="default" msgid="7315248696644510935">"No se ha podido borrar la tarjeta SD."</string>
<string name="media_bad_removal" msgid="7960864061016603281">"La tarjeta SD se ha extraído antes de desactivarla."</string>
@@ -1387,7 +1387,7 @@
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartir con"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <string name="sending" msgid="3245653681008218030">"Enviando..."</string>
+ <string name="sending" msgid="3245653681008218030">"Enviando\u2026"</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"¿Iniciar el navegador?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"¿Aceptar la llamada?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Siempre"</string>
@@ -1401,8 +1401,8 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fin"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Salida multimedia"</string>
- <string name="media_route_status_scanning" msgid="7279908761758293783">"Analizando..."</string>
- <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Analizando\u2026"</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando\u2026"</string>
<string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
<string name="media_route_status_not_available" msgid="6739899962681886401">"No disponible"</string>
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Pantalla integrada"</string>
@@ -1456,4 +1456,40 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilidad cancelada"</string>
<string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
+
+ <!-- CYANOGENMOD EDITS START -->
+
+ <string name="profileNameDefault">Predeterminado</string>
+ <string name="profileNameWork">Trabajo</string>
+ <string name="profileNameHome">Casa</string>
+ <string name="profileNameSilent">Silencio</string>
+ <string name="profileNameNight">Noche</string>
+ <string name="profileGroupPhone">Teléfono</string>
+ <string name="profileGroupCalendar">Calendario</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Email</string>
+ <string name="profileGroupSMS">SMS</string>
+ <string name="wildcardProfile">Otro</string>
+ <string name="reboot_system" product="tablet">Reiniciar tablet</string>
+ <string name="reboot_system" product="default">Reiniciar teléfono</string>
+ <string name="global_action_screenshot">Captura de pantalla</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Escritorio extendido</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Activado</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Desactivado</string>
+ <string name="reboot_reboot">Reiniciar</string>
+ <string name="reboot_recovery">Modo Recovery</string>
+ <string name="reboot_bootloader">Modo Bootloader</string>
+ <string name="reboot_bootmenu">Modo Bootmenu</string>
+ <string name="reboot_fastboot">Modo Fastboot</string>
+ <string name="reboot_download">Modo Download</string>
+ <string name="reboot_progress">Reiniciando\u2026</string>
+ <string name="reboot_confirm">El terminal se reiniciará</string>
+ <string name="permlab_preventpower">Anular tecla encendido</string>
+ <string name="permdesc_preventpower">Permite que una aplicación cambie el comportamiento de la tecla de encendido</string>
+ <string name="lockscreen_discharging">Descargando, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+ <string name="app_killed_message">Aplicación finalizada</string>
+ <string name="global_action_reboot">Reiniciar</string>
+ <string name="global_action_choose_profile">Perfil</string>
+
+<!-- CYANOGENMOD ADDITIONS END -->
</resources>
diff --git a/core/res/res/values-fa/donottranslate-cldr.xml b/core/res/res/values-fa/donottranslate-cldr.xml
index 402311a..32d205d 100644
--- a/core/res/res/values-fa/donottranslate-cldr.xml
+++ b/core/res/res/values-fa/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E d LLLL</string>
<string name="abbrev_wday_month_day_no_year">E d LLLL</string>
<string name="abbrev_wday_month_day_year">E d MMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEE\nd LLLL</string>
</resources>
diff --git a/core/res/res/values-fi-rFI/donottranslate-cldr.xml b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
index 04f0a77..e20030d 100644
--- a/core/res/res/values-fi-rFI/donottranslate-cldr.xml
+++ b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-fi/donottranslate-cldr.xml b/core/res/res/values-fi/donottranslate-cldr.xml
index 543595f..abf93be 100644
--- a/core/res/res/values-fi/donottranslate-cldr.xml
+++ b/core/res/res/values-fi/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">E d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d. MMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEE\n d. MMMM</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8bbd645..b68747e 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -433,17 +433,17 @@
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"asenna sijainnintarjoaja"</string>
<string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Luo imitoituja sijaintilähteitä testaustarkoituksessa tai asenna uusi sijaintipalvelu. Sovellus voi ohittaa muiden sijaintilähteiden kuten GPS:n ja sijaintipalveluiden palauttaman sijainnin ja/tai tilan."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"tarkka sijainti (GPS- ja verkkopohjainen)"</string>
- <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Antaa sovelluksen käyttää tarkkaa sijaintiasi, joka määritetään GPS:n tai verkon sijaintilähteiden kuten radiomastojen ja wifi-verkkojen avulla. Sijaintipalveluiden täytyy olla käytössä ja laitteesi saatavilla, jotta sovellus voi käyttää niitä. Sovellus voi määrittää tämän luvan avulla sijaintisi ja lisätä akun käyttöä."</string>
+ <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Antaa sovelluksen käyttää tarkkaa sijaintiasi, joka määritetään GPS:n tai verkon sijaintilähteiden kuten radiomastojen ja Wi-Fi-verkkojen avulla. Sijaintipalveluiden täytyy olla käytössä ja laitteesi saatavilla, jotta sovellus voi käyttää niitä. Sovellus voi määrittää tämän luvan avulla sijaintisi ja lisätä akun käyttöä."</string>
<string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"likimääräinen sijainti (verkkopohjainen)"</string>
- <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Antaa sovelluksen käyttää likimääräistä sijaintiasi. Sijainnin määrittävät sijaintipalvelut verkon sijaintilähteiden kuten radiomastojen ja wifi-verkkojen avulla. Sijaintipalveluiden täytyy olla käytössä ja laitteesi saatavilla, jotta sovellus voi käyttää niitä. Sovellus voi määrittää tämän luvan avulla likimääräisen sijaintisi."</string>
+ <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Antaa sovelluksen käyttää likimääräistä sijaintiasi. Sijainnin määrittävät sijaintipalvelut verkon sijaintilähteiden kuten radiomastojen ja Wi-Fi-verkkojen avulla. Sijaintipalveluiden täytyy olla käytössä ja laitteesi saatavilla, jotta sovellus voi käyttää niitä. Sovellus voi määrittää tämän luvan avulla likimääräisen sijaintisi."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"käytä SurfaceFlinger-sovellusta"</string>
<string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Antaa sovelluksen käyttää SurfaceFlingerin matalan tason ominaisuuksia."</string>
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lue kehyspuskuria"</string>
<string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Antaa sovelluksen lukea kehyspuskurin sisältöä."</string>
- <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"määritä wifi-näyttöjen asetukset"</string>
- <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Antaa sovelluksen määrittää wifi-näyttöjä ja muodostaa yhteyden niihin."</string>
- <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"hallitse wifi-näyttöjä"</string>
- <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Antaa sovelluksen hallita wifi-näyttöjen matalan tason ominaisuuksia."</string>
+ <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"määritä Wi-Fi-näyttöjen asetukset"</string>
+ <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Antaa sovelluksen määrittää Wi-Fi-näyttöjä ja muodostaa yhteyden niihin."</string>
+ <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"hallitse Wi-Fi-näyttöjä"</string>
+ <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Antaa sovelluksen hallita Wi-Fi-näyttöjen matalan tason ominaisuuksia."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"muuta ääniasetuksia"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Antaa sovelluksen muokata yleisiä ääniasetuksia, kuten äänenvoimakkuutta ja käytettävää kaiutinta."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"tallentaa ääntä"</string>
@@ -547,13 +547,13 @@
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"Antaa sovelluksen muuttaa internetyhteyden jakamisen tilaa."</string>
<string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"muuta taustatietojen käyttöasetuksia"</string>
<string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Antaa sovelluksen muuttaa taustatietojen käyttöasetuksia."</string>
- <string name="permlab_accessWifiState" msgid="5202012949247040011">"näytä wifi-yhteydet"</string>
- <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Antaa sovelluksen tarkastella wifi-verkkoja koskevia tietoja, kuten onko wifi käytössä ja mihin wifi-laitteisiin on muodostettu yhteys."</string>
- <string name="permlab_changeWifiState" msgid="6550641188749128035">"muodosta ja katkaise wifi-yhteys"</string>
- <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Antaa sovelluksen yhdistää wifi-tukiasemiin tai katkaista yhteyden sekä tehdä muutoksia määritettyihin wifi-verkkoihin."</string>
- <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"anna ottaa vastaan wifi-ryhmälähetyksiä"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Antaa sovelluksen vastaanottaa kaikille laitteille, ei vain tablet-laitteellesi, wifi-verkon kautta monilähetystilassa lähetettyjä paketteja. Tämä käyttää enemmän virtaa kuin tavallinen lähetystila."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Antaa sovelluksen vastaanottaa kaikille laitteille, ei vain puhelimellesi, wifi-verkon kautta monilähetystilassa lähetettyjä paketteja. Tämä käyttää enemmän virtaa kuin tavallinen lähetystila."</string>
+ <string name="permlab_accessWifiState" msgid="5202012949247040011">"näytä Wi-Fi-yhteydet"</string>
+ <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Antaa sovelluksen tarkastella Wi-Fi-verkkoja koskevia tietoja, kuten onko Wi-Fi käytössä ja mihin Wi-Fi-laitteisiin on muodostettu yhteys."</string>
+ <string name="permlab_changeWifiState" msgid="6550641188749128035">"muodosta ja katkaise Wi-Fi-yhteys"</string>
+ <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Antaa sovelluksen yhdistää Wi-Fi-tukiasemiin tai katkaista yhteyden sekä tehdä muutoksia määritettyihin Wi-Fi-verkkoihin."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"anna ottaa vastaan Wi-Fi-ryhmälähetyksiä"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Antaa sovelluksen vastaanottaa kaikille laitteille, ei vain tablet-laitteellesi, Wi-Fi-verkon kautta monilähetystilassa lähetettyjä paketteja. Tämä käyttää enemmän virtaa kuin tavallinen lähetystila."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Antaa sovelluksen vastaanottaa kaikille laitteille, ei vain puhelimellesi, Wi-Fi-verkon kautta monilähetystilassa lähetettyjä paketteja. Tämä käyttää enemmän virtaa kuin tavallinen lähetystila."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"käytä Bluetooth-asetuksia"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Antaa sovelluksen määrittää paikallisen Bluetooth-tabletin asetukset sekä tunnistaa muita laitteita ja muodostaa niiden kanssa laitepareja."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Antaa sovelluksen määrittää paikallisen Bluetooth-puhelimen asetukset sekä tunnistaa muita laitteita ja muodostaa niiden kanssa laitepareja."</string>
@@ -1098,22 +1098,22 @@
<string name="ringtone_picker_title" msgid="3515143939175119094">"Soittoäänet"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"Tuntematon soittoääni"</string>
<plurals name="wifi_available">
- <item quantity="one" msgid="6654123987418168693">"Wifi-verkko käytettävissä"</item>
- <item quantity="other" msgid="4192424489168397386">"Wifi-verkkoja käytettävissä"</item>
+ <item quantity="one" msgid="6654123987418168693">"Wi-Fi-verkko käytettävissä"</item>
+ <item quantity="other" msgid="4192424489168397386">"Wi-Fi-verkkoja käytettävissä"</item>
</plurals>
<plurals name="wifi_available_detailed">
- <item quantity="one" msgid="1634101450343277345">"Avoin wifi-verkko käytettävissä"</item>
- <item quantity="other" msgid="7915895323644292768">"Avoimia wifi-verkkoja käytettävissä"</item>
+ <item quantity="one" msgid="1634101450343277345">"Avoin Wi-Fi-verkko käytettävissä"</item>
+ <item quantity="other" msgid="7915895323644292768">"Avoimia Wi-Fi-verkkoja käytettävissä"</item>
</plurals>
- <string name="wifi_available_sign_in" msgid="4029489716605255386">"Kirjaudu wifi-verkkoon"</string>
+ <string name="wifi_available_sign_in" msgid="4029489716605255386">"Kirjaudu Wi-Fi-verkkoon"</string>
<string name="network_available_sign_in" msgid="8495155593358054676">"Kirjaudu verkkoon"</string>
<!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
<skip />
- <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wifi-yhteyden muodostaminen epäonnistui"</string>
+ <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-yhteyden muodostaminen epäonnistui"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" : huono internetyhteys."</string>
- <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Suora wifi-yhteys"</string>
- <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käynnistä suora wifi-yhteys. Wifi-asiakas/-hotspot poistetaan käytöstä."</string>
- <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Suoran wifi-yhteyden käynnistäminen epäonnistui."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Suora Wi-Fi-yhteys"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käynnistä suora Wi-Fi-yhteys. Wi-Fi-asiakas/-hotspot poistetaan käytöstä."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Suoran Wi-Fi-yhteyden käynnistäminen epäonnistui."</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct on käytössä"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tarkastele asetuksia koskettamalla"</string>
<string name="accept" msgid="1645267259272829559">"Hyväksy"</string>
@@ -1124,7 +1124,7 @@
<string name="wifi_p2p_to_message" msgid="248968974522044099">"Kohde:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Kirjoita pyydetty PIN-koodi:"</string>
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-koodi:"</string>
- <string name="wifi_p2p_frequency_conflict_message" msgid="7363907213787469151">"Puhelimen yhteys wifi-verkkoon katkaistaan väliaikaisesti puhelimen ollessa yhdistettynä laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="7363907213787469151">"Puhelimen yhteys Wi-Fi-verkkoon katkaistaan väliaikaisesti puhelimen ollessa yhdistettynä laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="select_character" msgid="3365550120617701745">"Lisää merkki"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Tekstiviestien lähettäminen"</string>
<string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; lähettää suuria määriä tekstiviestejä. Annetaanko tämän sovelluksen jatkaa tekstiviestien lähettämistä?"</string>
@@ -1359,12 +1359,12 @@
<string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobiilitiedonsiirto pois käytöstä"</string>
- <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wifi-tiedonsiirto pois käytöstä"</string>
+ <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_limit_body" msgid="3317964706973601386">"Ota käyttöön koskettamalla."</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G-tiedonsiirtoraja ylitetty"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G-tiedonsiirtoraja ylitetty"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Mobiilitiedonsiirtoraja ylitetty"</string>
- <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wifi-tiedonsiirtoraja ylitetty"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi-tiedonsiirtoraja ylitetty"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> yli asetetun rajan"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Rajoitettu taustatietojen käyttö"</string>
<string name="data_usage_restricted_body" msgid="6741521330997452990">"Poista rajoitus koskettamalla."</string>
@@ -1456,4 +1456,35 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Esteettömyystila peruutettu."</string>
<string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Omistaja"</string>
+ <string name="profileNameDefault">Oletus</string>
+ <string name="profileNameWork">Työ</string>
+ <string name="profileNameHome">Koti</string>
+ <string name="profileNameSilent">Äänetön</string>
+ <string name="profileNameNight">Yö</string>
+ <string name="profileGroupPhone">Puhelin</string>
+ <string name="profileGroupCalendar">Kalenteri</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Sähköposti</string>
+ <string name="profileGroupSMS">Tekstiviesti</string>
+ <string name="wildcardProfile">Muu</string>
+ <string name="reboot_system" product="tablet">Käynnistä tablet uudelleen</string>
+ <string name="reboot_system" product="default">Käynnistä puhelin uudelleen</string>
+ <string name="global_action_screenshot">Kuvakaappaus</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Laajennettu työpöytä</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Käytössä</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Pois käytöstä</string>
+ <string name="reboot_reboot">Käynnistä uudelleen</string>
+ <string name="reboot_recovery">Recovery-tila</string>
+ <string name="reboot_bootloader">Bootloader-tila</string>
+ <string name="reboot_bootmenu">Käynnistysvalikko</string>
+ <string name="reboot_fastboot">Fastboot-tila</string>
+ <string name="reboot_download">Download-tila</string>
+ <string name="reboot_progress">Käynnistetään uudelleen\u2026</string>
+ <string name="reboot_confirm">Puhelimesi käynnistyy uudelleen.</string>
+ <string name="lockscreen_discharging">Puretaan latausta, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+ <string name="app_killed_message">Sovellus tapettu</string>
+ <string name="global_action_reboot">Käynnistä uudelleen</string>
+ <string name="global_action_choose_profile">Profiili</string>
+ <string name="toast_rotation_unlocked">Näytön asento auki</string>
+ <string name="toast_rotation_locked">Näytön asento lukittu</string>
</resources>
diff --git a/core/res/res/values-fr/donottranslate-cldr.xml b/core/res/res/values-fr/donottranslate-cldr.xml
index ff10aec..e0b0ae3 100644
--- a/core/res/res/values-fr/donottranslate-cldr.xml
+++ b/core/res/res/values-fr/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 550e09c..7f055c5 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1183,9 +1183,9 @@
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Tous les fichiers stockés sur la mémoire de stockage USB vont être effacés. Cette action est irréversible."</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Toutes les données stockées sur votre carte seront perdues."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string>
- <string name="select_input_method" msgid="4653387336791222978">"Sélectionnez le mode de saisie"</string>
+ <string name="adb_active_notification_title">Débogage android activé</string>
+ <string name="adb_active_notification_message">Désactiver le débogage android (adb).</string>
+ <string name="select_input_method">"Sélectionner le mode de saisie"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
<string name="hardware" msgid="7517821086888990278">"Matériel"</string>
@@ -1456,4 +1456,43 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string>
<string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
+
+ <!-- CYANOGENMOD ADDITIONS -->
+
+ <string name="reboot_system" product="tablet">Redémarrage de la tablette</string>
+ <string name="reboot_system" product="default">Redémarrage du téléphone</string>
+ <string name="reboot_reboot">Redémarrer</string>
+ <string name="reboot_recovery">Recovery</string>
+ <string name="reboot_bootloader">Bootloader</string>
+ <string name="reboot_bootmenu">Bootmenu</string>
+ <string name="reboot_fastboot">Fastboot</string>
+ <string name="reboot_download">Download</string>
+ <string name="reboot_confirm" product="tablet">Votre tablette va redémarrer</string>
+ <string name="reboot_confirm" product="default">Votre téléphone va redémarrer</string>
+ <string name="reboot_progress">Redémarrage en cours\u2026</string>
+ <string name="global_action_reboot">Redémarrer</string>
+ <string name="global_action_screenshot">Capture d\'écran</string>
+ <string name="global_action_choose_profile">Profils</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Bureau étendu</string>
+
+ <!-- label for item that toggles expand desktop mode -->
+ <string name="global_actions_expanded_desktop_mode_on_status">Activé</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Désactivé</string>
+
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">Défaut</string>
+ <string name="profileNameWork">Bureau</string>
+ <string name="profileNameHome">Maison</string>
+ <string name="profileNameSilent">Silencieux</string>
+ <string name="profileNameNight">Nuit</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">Téléphone</string>
+ <string name="profileGroupCalendar">Agenda</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Email</string>
+ <string name="profileGroupSMS">SMS</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">Autres</string>
</resources>
diff --git a/core/res/res/values-hi-rIN/donottranslate-cldr.xml b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
index 5371e15..f1e856a 100644
--- a/core/res/res/values-hi-rIN/donottranslate-cldr.xml
+++ b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-hr-rHR/donottranslate-cldr.xml b/core/res/res/values-hr-rHR/donottranslate-cldr.xml
index 57e0572..955e0d7 100644
--- a/core/res/res/values-hr-rHR/donottranslate-cldr.xml
+++ b/core/res/res/values-hr-rHR/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d.MMM.yyyy.</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-hr/donottranslate-cldr.xml b/core/res/res/values-hr/donottranslate-cldr.xml
index 9e4b225..47482e3 100644
--- a/core/res/res/values-hr/donottranslate-cldr.xml
+++ b/core/res/res/values-hr/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E, d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">E, d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d.MMM.y.</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-hu-rHU/donottranslate-cldr.xml b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
index 5f4b8aa..4d6669c 100644
--- a/core/res/res/values-hu-rHU/donottranslate-cldr.xml
+++ b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE MMMM d</string>
<string name="abbrev_wday_month_day_no_year">EEE MMMM d</string>
<string name="abbrev_wday_month_day_year">yyyy. MMM d., E</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-hu/donottranslate-cldr.xml b/core/res/res/values-hu/donottranslate-cldr.xml
index c925b82..e53f9a8 100644
--- a/core/res/res/values-hu/donottranslate-cldr.xml
+++ b/core/res/res/values-hu/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_year">y. MMM d., E</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index e1e7901..e2d115d 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -139,6 +139,20 @@
<string name="turn_off_radio" msgid="8198784949987062346">"Vezeték nélküli eszköz kikapcsolása"</string>
<string name="screen_lock" msgid="799094655496098153">"Képernyő lezárása"</string>
<string name="power_off" msgid="4266614107412865048">"Kikapcsolás"</string>
+ <string name="reboot_system" product="tablet">Táblagép újraindítása</string>
+ <string name="reboot_system" product="default">Telefon újraindítása</string>
+ <string name="global_action_screenshot">Képernyőmentés</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Kiterjesztett képernyő</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Engedélyezve</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Letiltva</string>
+ <string name="reboot_reboot">Újraindítás</string>
+ <string name="reboot_recovery">Recovery</string>
+ <string name="reboot_bootloader">Bootloader</string>
+ <string name="reboot_bootmenu">Bootmenü</string>
+ <string name="reboot_fastboot">Fastboot</string>
+ <string name="reboot_download">Download</string>
+ <string name="reboot_progress">Újraindítás\u2026</string>
+ <string name="reboot_confirm">A telefon újraindul.</string>
<string name="silent_mode_silent" msgid="319298163018473078">"Csengő kikapcsolva"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Csengő rezeg"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Csengő bekapcsolva"</string>
@@ -374,6 +388,8 @@
<string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Lehetővé teszi az alkalmazás számára, hogy tárhelyet szabadítson fel a telefonon azáltal, hogy fájlokat töröl más alkalmazások gyorsítótármappáiból. Ez a többi alkalmazás lassabb elindulását okozhatja, mert azoknak újra le kell kérniük az adataikat."</string>
<string name="permlab_movePackage" msgid="3289890271645921411">"alkalmazás-erőforrások áthelyezése"</string>
<string name="permdesc_movePackage" msgid="319562217778244524">"Lehetővé teszi az alkalmazás számára alkalmazás-erőforrások áthelyezését a belső tárolóról egy külső tárolóra, és fordítva."</string>
+ <string name="permlab_preventpower">kikapcsológomb felülbírálata</string>
+ <string name="permdesc_preventpower">Lehetővé teszi egy alkalmazás számára a kikapcsológomb felülbírálatát</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"érzékeny naplóadatok olvasása"</string>
<string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Lehetővé teszi az alkalmazás számára, hogy olvassa a rendszer különböző naplófájljait. Ezáltal általános információkat deríthet ki arról, hogy mire használja a táblagépét, valamint személyes, magánjellegű adatokhoz is hozzájuthat."</string>
<string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Lehetővé teszi az alkalmazás számára, hogy olvassa a rendszer különböző naplófájljait. Ezáltal általános információkat deríthet ki arról, hogy mire használja a telefonját, valamint személyes, magánjellegű adatokhoz is hozzájuthat."</string>
@@ -762,6 +778,7 @@
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Újra"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Elérte az arcalapú feloldási kísérletek maximális számát"</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Töltés (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+ <string name="lockscreen_discharging">Lemerítés, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<string name="lockscreen_charged" msgid="321635745684060624">"Feltöltve"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Csatlakoztassa a töltőt."</string>
@@ -1067,7 +1084,7 @@
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> folyamat megsértette az általa kényszerített Szigorú üzemmód irányelvet."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android frissítése folyamatban..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Alkalmazás optimalizálása: <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Kezdő alkalmazások."</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Alkalmazások indítása."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Rendszerindítás befejezése."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> fut"</string>
<string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Érintse meg az alkalmazásra váltáshoz"</string>
@@ -1352,6 +1369,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"További lehetőségek"</string>
<string name="storage_internal" msgid="4891916833657929263">"Belső tárhely"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-kártya"</string>
+ <string name="storage_sd_dock_card">Dokkoló SD-kártyája</string>
<string name="storage_usb" msgid="3017954059538517278">"USB-tár"</string>
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Szerkesztés"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Adathasználati figyelmeztetés"</string>
@@ -1390,6 +1408,7 @@
<string name="sending" msgid="3245653681008218030">"Küldés…"</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Fogadja a hívást?"</string>
+ <string name="app_killed_message">Alkalmazás leállítva</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Mindig"</string>
<string name="activity_resolver_use_once" msgid="2404644797149173758">"Csak egyszer"</string>
<string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Táblagép"</string>
@@ -1456,4 +1475,19 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hozzáférés megszakítva."</string>
<string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
<string name="owner_name" msgid="2716755460376028154">"Tulajdonos"</string>
+ <string name="global_action_reboot">Újraindítás</string>
+ <string name="global_action_choose_profile">Profil</string>
+ <string name="profileNameDefault">Alapértelmezett</string>
+ <string name="profileNameWork">Munka</string>
+ <string name="profileNameHome">Otthon</string>
+ <string name="profileNameSilent">Néma</string>
+ <string name="profileNameNight">Éjszaka</string>
+ <string name="profileGroupPhone">Telefon</string>
+ <string name="profileGroupCalendar">Naptár</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">E-mail</string>
+ <string name="profileGroupSMS">SMS</string>
+ <string name="wildcardProfile">Egyéb</string>
+ <string name="toast_rotation_unlocked">Képernyő elforgatás engedélyezve</string>
+ <string name="toast_rotation_locked">Képernyő elforgatás letiltva</string>
</resources>
diff --git a/core/res/res/values-in-rID/donottranslate-cldr.xml b/core/res/res/values-in-rID/donottranslate-cldr.xml
index 8b13bcf..8944c11 100644
--- a/core/res/res/values-in-rID/donottranslate-cldr.xml
+++ b/core/res/res/values-in-rID/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE MMMM d</string>
<string name="abbrev_wday_month_day_no_year">EEE MMMM d</string>
<string name="abbrev_wday_month_day_year">E, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-in/donottranslate-cldr.xml b/core/res/res/values-in/donottranslate-cldr.xml
index 6e9bba4..61c926f 100644
--- a/core/res/res/values-in/donottranslate-cldr.xml
+++ b/core/res/res/values-in/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_year">EEE, y MMM d</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-it/donottranslate-cldr.xml b/core/res/res/values-it/donottranslate-cldr.xml
index 9ff27e8..afb1bbb 100644
--- a/core/res/res/values-it/donottranslate-cldr.xml
+++ b/core/res/res/values-it/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2257daa..c13f8590 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -36,6 +36,17 @@
<string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
<string name="mmiError" msgid="5154499457739052907">"Problema di connessione o codice MMI non valido."</string>
<string name="mmiFdnError" msgid="5224398216385316471">"Operazione limitata solo ai numeri di selezione fissa."</string>
+ <string name="profileNameDefault">Predefinito</string>
+ <string name="profileNameWork">Lavoro</string>
+ <string name="profileNameHome">Casa</string>
+ <string name="profileNameSilent">Silenzioso</string>
+ <string name="profileNameNight">Notte</string>
+ <string name="profileGroupPhone">Telefono</string>
+ <string name="profileGroupCalendar">Calendario</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Email</string>
+ <string name="profileGroupSMS">SMS</string>
+ <string name="wildcardProfile">Altro</string>
<string name="serviceEnabled" msgid="8147278346414714315">"Il servizio è stato attivato."</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"Il servizio è stato attivato per:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"Il servizio è stato disattivato."</string>
@@ -139,6 +150,20 @@
<string name="turn_off_radio" msgid="8198784949987062346">"Disattiva wireless"</string>
<string name="screen_lock" msgid="799094655496098153">"Blocco schermo"</string>
<string name="power_off" msgid="4266614107412865048">"Spegni"</string>
+ <string name="reboot_system" product="tablet">Riavvia tablet</string>
+ <string name="reboot_system" product="default">Riavvia telefono</string>
+ <string name="global_action_screenshot">Cattura schermata</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Desktop espanso</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Attivato</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Disattivato</string>
+ <string name="reboot_reboot">Riavvia</string>
+ <string name="reboot_recovery">Recovery</string>
+ <string name="reboot_bootloader">Bootloader</string>
+ <string name="reboot_bootmenu">Bootmenu</string>
+ <string name="reboot_fastboot">Fastboot</string>
+ <string name="reboot_download">Download</string>
+ <string name="reboot_progress">Riavvio\u2026</string>
+ <string name="reboot_confirm">Il dispositivo verrà riavviato.</string>
<string name="silent_mode_silent" msgid="319298163018473078">"Suoneria disattivata"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Suoneria vibrazione"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Suoneria attiva"</string>
@@ -374,6 +399,8 @@
<string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Consente all\'applicazione di liberare memoria sul telefono eliminando file nelle directory della cache di altre applicazioni. Altre applicazioni potrebbero avviarsi più lentamente perché devono recuperare di nuovo i loro dati."</string>
<string name="permlab_movePackage" msgid="3289890271645921411">"spostamento delle risorse dell\'applicazione"</string>
<string name="permdesc_movePackage" msgid="319562217778244524">"Consente all\'applicazione di spostare le risorse delle applicazioni da supporti interni a supporti esterni e viceversa."</string>
+ <string name="permlab_preventpower">modifica azione tasto spegnimento</string>
+ <string name="permdesc_preventpower">Consente a un\'applicazione di cambiare il comportamento del tasto di spegnimento</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"Lettura dati di registro sensibili"</string>
<string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Consente all\'applicazione di leggere vari file di registro del sistema per trovare informazioni generali sulle operazioni effettuate con il tablet. Tali file potrebbero contenere informazioni personali o riservate."</string>
<string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Consente all\'applicazione di leggere vari file di registro del sistema per trovare informazioni generali sulle operazioni effettuate con il telefono. Tali file potrebbero contenere informazioni personali o riservate."</string>
@@ -762,6 +789,7 @@
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Riprova"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Numero massimo di tentativi di Sblocco col sorriso superato"</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"In carica (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+ <string name="lockscreen_discharging">In uso, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<string name="lockscreen_charged" msgid="321635745684060624">"Carica"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Collegare il caricabatterie."</string>
@@ -1390,6 +1418,7 @@
<string name="sending" msgid="3245653681008218030">"Invio..."</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"Avviare l\'applicazione Browser?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Accettare la chiamata?"</string>
+ <string name="app_killed_message">Applicazione terminata</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
<string name="activity_resolver_use_once" msgid="2404644797149173758">"Solo una volta"</string>
<string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
@@ -1456,4 +1485,8 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilità annullata."</string>
<string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Proprietario"</string>
+ <string name="global_action_reboot">Riavvia</string>
+ <string name="global_action_choose_profile">Profilo</string>
+ <string name="toast_rotation_unlocked">Rotazione schermo sbloccata</string>
+ <string name="toast_rotation_locked">Rotazione schermo bloccata</string>
</resources>
diff --git a/core/res/res/values-iw/donottranslate-cldr.xml b/core/res/res/values-iw/donottranslate-cldr.xml
index 631c059..52eb14f 100644
--- a/core/res/res/values-iw/donottranslate-cldr.xml
+++ b/core/res/res/values-iw/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_year">EEE, y MMM d</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index ce51ef4..38d0a0f 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -873,7 +873,7 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"מאפשר ליישום לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטלפון. הדבר עשוי לאפשר ליישום למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או יישומים אחרים בעלי יכולות גלישה באינטרנט."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"הגדרת התראה"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"מאפשר ליישום להגדיר התראה ביישום שעון מעורר מותקן. יישומי שעון מעורר מסוימים אינם מיישמים תכונה זו."</string>
- <string name="permlab_addVoicemail" msgid="5525660026090959044">"הוסף דואר קולי"</string>
+ <string name="permlab_addVoicemail" msgid="5525660026090959044">"הוסף הודעה קולית"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"מאפשר ליישום להוסיף הודעות לתיבת הדואר הקולי."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"שינוי הרשאות המיקום הגיאוגרפי של הדפדפן"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"מאפשר ליישום לשנות את הרשאות המיקום הגיאוגרפי של הדפדפן. יישומים זדוניים עלולים להשתמש בכך כדי לאפשר משלוח של פרטי מיקום לאתרים זדוניים אחרים."</string>
@@ -1395,7 +1395,7 @@
<string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"טאבלט"</string>
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"טלפון"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"אוזניות"</string>
- <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"רמקולים של מעגן"</string>
+ <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"רמקולים של תחנת עגינה"</string>
<string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"מערכת"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"אודיו Bluetooth"</string>
@@ -1456,4 +1456,93 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"נגישות בוטלה."</string>
<string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"בעלים"</string>
+
+<!-- **** CYANOGENMOD ADDITIONS START **** -->
+
+<!-- Profile names -->
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">ברירת מחדל</string>
+ <string name="profileNameWork">עבודה</string>
+ <string name="profileNameHome">בית</string>
+ <string name="profileNameSilent">שקט</string>
+ <string name="profileNameNight">לילה</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">טלפון</string>
+ <string name="profileGroupCalendar">יומן</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">דוא\"ל</string>
+ <string name="profileGroupSMS">SMS</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">אחר</string>
+
+<!-- Power Menu -->
+
+ <!-- Button to reboot the phone, within the Phone Options dialog -->
+ <string name="reboot_system" product="tablet">הפעלת טאבלט מחדש</string>
+ <string name="reboot_system" product="default">הפעלת טלפון מחדש</string>
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+
+ <!-- label for item that screenshots in phone options dialog -->
+ <string name="global_action_screenshot">צלם מסך</string>
+
+ <!-- label for item that toggles expand desktop mode -->
+ <string name="global_actions_toggle_expanded_desktop_mode">שולחן עבודה מורחב</string>
+ <!-- status message in phone options dialog for when expand desktop mode is on -->
+ <string name="global_actions_expanded_desktop_mode_on_status">פועל</string>
+ <!-- status message in phone options dialog for when expand desktop mode is off -->
+ <string name="global_actions_expanded_desktop_mode_off_status">מושבת</string>
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_reboot">הפעלה מחדש</string>
+ <!-- label for item that opens the profile choosing dialog -->
+ <string name="global_action_choose_profile">פרופיל</string>
+
+ <!-- Button to reboot the phone, within the Reboot Options dialog -->
+ <string name="reboot_reboot">הפעלה מחדש</string>
+ <!-- Button to reboot the phone into recovery, within the Reboot Options dialog -->
+ <string name="reboot_recovery">Recovery</string>
+ <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog -->
+ <string name="reboot_bootloader">Bootloader</string>
+ <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog -->
+ <string name="reboot_bootmenu">Bootmenu</string>
+ <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog -->
+ <string name="reboot_fastboot">Fastboot</string>
+ <!-- Button to reboot the phone into download, within the Reboot Options dialog -->
+ <string name="reboot_download">Download</string>
+
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+ <string name="reboot_progress">מפעיל מחדש...</string>
+ <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. -->
+ <string name="reboot_confirm" product="tablet">הטאבלט יופעל מחדש.</string>
+ <string name="reboot_confirm" product="default">הטלפון יופעל מחדש.</string>
+
+<!-- App Permissions -->
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_preventpower">מניעת כפתור הכיבוי</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preventpower">מאפשר ליישום לעקוף את כפתור הכיבוי.</string>
+
+<!-- Lock Screen -->
+
+ <!-- Discharging -->
+ <string name="lockscreen_discharging">פורק(<xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g>)</string>
+
+<!-- Pop-Up messages -->
+
+ <!-- Long-press back kill application -->
+ <string name="app_killed_message">התהליך נסגר</string>
+
+<!-- Dock -->
+
+ <!-- Storage description for the SD card on the dock. [CHAR LIMIT=NONE] -->
+ <string name="storage_sd_dock_card">כרטיס SD של תחנת עגינה</string>
+
+<!-- Unknown -->
+
+ <!-- Hardware Rotation lock string -->
+ <string name="toast_rotation_unlocked">סיבוב אוטומטי</string>
+ <string name="toast_rotation_locked">סיבוב נעול</string>
+<!-- **** CYANOGENMOD ADDITIONS END **** -->
</resources>
diff --git a/core/res/res/values-ja/donottranslate-cldr.xml b/core/res/res/values-ja/donottranslate-cldr.xml
index 1c1d55f..0eb9ebc 100644
--- a/core/res/res/values-ja/donottranslate-cldr.xml
+++ b/core/res/res/values-ja/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">M月d日 (E)</string>
<string name="abbrev_wday_month_day_no_year">M月d日 (E)</string>
<string name="abbrev_wday_month_day_year">yyyy年M月d日 (E)</string>
+ <string name="full_wday_month_day_no_year_split">M月d日\n(EEEE)</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index f2ca7c6..4c158f0 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1456,4 +1456,66 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"ユーザー補助をキャンセルしました。"</string>
<string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
<string name="owner_name" msgid="2716755460376028154">"所有者"</string>
+
+ <!-- CM Extra entries -->
+ <string name="lockscreen_discharging">放電中, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+ <string name="global_actions_toggle_expanded_desktop_mode">拡張デスクトップ</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">有効</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">無効</string>
+ <string name="reboot_confirm" product="tablet">タブレットは再起動します。</string>
+ <string name="reboot_confirm" product="default">携帯電話は再起動します。</string>
+ <string name="toast_rotation_unlocked">ディスプレイの回転をロック解除しました</string>
+ <string name="toast_rotation_locked">ディスプレイの回転をロックしました</string>
+
+ <!-- Button to reboot the phone, within the Phone Options dialog -->
+ <string name="reboot_system" product="tablet">タブレットを再起動</string>
+ <string name="reboot_system" product="default">携帯電話を再起動</string>
+
+ <!-- label for item that screenshots in phone options dialog -->
+ <string name="global_action_screenshot">スクリーンショット</string>
+
+ <!-- Button to reboot the phone, within the Reboot Options dialog -->
+ <string name="reboot_reboot">再起動</string>
+ <!-- Button to reboot the phone into recovery, within the Reboot Options dialog -->
+ <string name="reboot_recovery">リカバリー</string>
+ <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog -->
+ <string name="reboot_bootloader">ブートローダー</string>
+ <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog -->
+ <string name="reboot_bootmenu">ブートメニュー</string>
+ <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog -->
+ <string name="reboot_fastboot">ファストブート</string>
+ <!-- Button to reboot the phone into download, within the Reboot Options dialog -->
+ <string name="reboot_download">ダウンロード</string>
+
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+ <string name="reboot_progress">再起動中\u2026</string>
+
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_reboot">再起動</string>
+
+ <string name="permlab_preventpower">電源キーを保護</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preventpower">アプリケーションが電源キーを置き換えるのを許可する</string>
+
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_choose_profile">プロファイル選択</string>
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">デフォルト</string>
+ <string name="profileNameWork">仕事</string>
+ <string name="profileNameHome">自宅</string>
+ <string name="profileNameSilent">サイレント</string>
+ <string name="profileNameNight">夜</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">電話</string>
+ <string name="profileGroupCalendar">カレンダー</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Eメール</string>
+ <string name="profileGroupSMS">SMS</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">その他</string>
+
+ <string name="app_killed_message">アプリケーションを強制終了しました</string>
+
</resources>
diff --git a/core/res/res/values-ko/donottranslate-cldr.xml b/core/res/res/values-ko/donottranslate-cldr.xml
index 59b975f..088100c 100644
--- a/core/res/res/values-ko/donottranslate-cldr.xml
+++ b/core/res/res/values-ko/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">MMMM d일 EEEE</string>
<string name="abbrev_wday_month_day_no_year">MMMM d일 EEE</string>
<string name="abbrev_wday_month_day_year">yyyy년 MMM d일 EEE</string>
+ <string name="full_wday_month_day_no_year_split">MMMM d\n일 EEEE</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 3e17643..6b175f5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1456,4 +1456,70 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"접근성이 취소되었습니다."</string>
<string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
<string name="owner_name" msgid="2716755460376028154">"소유자"</string>
+
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_reboot">다시 시작</string>
+
+ <!-- label for item that opens the profile choosing dialog -->
+ <string name="global_action_choose_profile">프로파일</string>
+
+ <!-- Hardware Rotation lock string -->
+ <string name="toast_rotation_unlocked">방향 전환 잠김</string>
+ <string name="toast_rotation_locked">방향 전환 잠금 풀림</string>
+
+ <string name="lockscreen_discharging">방전 중, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+
+ <!-- Button to reboot the phone, within the Phone Options dialog -->
+ <string name="reboot_system" product="tablet">태블릿 다시 시작</string>
+ <string name="reboot_system" product="default">휴대전화 다시 시작</string>
+
+ <!-- label for item that screenshots in phone options dialog -->
+ <string name="global_action_screenshot">스크린샷</string>
+
+ <!-- label for item that toggles expand desktop mode -->
+ <string name="global_actions_toggle_expanded_desktop_mode">데스크탑 확장</string>
+ <!-- status message in phone options dialog for when expand desktop mode is on -->
+ <string name="global_actions_expanded_desktop_mode_on_status">활성화됨</string>
+ <!-- status message in phone options dialog for when expand desktop mode is off -->
+ <string name="global_actions_expanded_desktop_mode_off_status">비활성화됨</string>
+
+ <!-- Button to reboot the phone, within the Reboot Options dialog -->
+ <string name="reboot_reboot">다시 시작</string>
+ <!-- Button to reboot the phone into recovery, within the Reboot Options dialog -->
+ <string name="reboot_recovery">복구 모드</string>
+ <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog -->
+ <string name="reboot_bootloader">부트로더</string>
+ <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog -->
+ <string name="reboot_bootmenu">부트메뉴</string>
+ <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog -->
+ <string name="reboot_fastboot">패스트부트</string>
+ <!-- Button to reboot the phone into download, within the Reboot Options dialog -->
+ <string name="reboot_download">다운로드</string>
+
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+ <string name="reboot_progress">다시 시작하는 중\u2026</string>
+ <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. -->
+ <string name="reboot_confirm" product="tablet">태블릿이 다시 시작됩니다.</string>
+ <string name="reboot_confirm" product="default">휴대전화가 다시 시작됩니다.</string>
+
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">기본</string>
+ <string name="profileNameWork">직장</string>
+ <string name="profileNameHome">집</string>
+ <string name="profileNameSilent">음소거</string>
+ <string name="profileNameNight">야간</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">통화</string>
+ <string name="profileGroupCalendar">일정</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">이메일</string>
+ <string name="profileGroupSMS">메시지</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">기타</string>
+
+ <!-- Long-press back kill application -->
+ <string name="app_killed_message">애플리케이션 종료됨</string>
+
</resources>
diff --git a/core/res/res/values-land/integers.xml b/core/res/res/values-land/integers.xml
index 020fd23..9cf1d42 100644
--- a/core/res/res/values-land/integers.xml
+++ b/core/res/res/values-land/integers.xml
@@ -22,5 +22,5 @@
<integer name="kg_selector_gravity">0x13</integer>
<integer name="kg_widget_region_weight">45</integer>
<integer name="kg_security_flipper_weight">55</integer>
- <integer name="kg_glowpad_rotation_offset">-90</integer>
+ <integer name="kg_glowpad_rotation_offset">0</integer>
</resources>
diff --git a/core/res/res/values-lt-rLT/donottranslate-cldr.xml b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
index 6cf6098..d282291 100644
--- a/core/res/res/values-lt-rLT/donottranslate-cldr.xml
+++ b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">MMMM d \'d\'., EEEE</string>
<string name="abbrev_wday_month_day_no_year">MMMM d \'d\'., EEE</string>
<string name="abbrev_wday_month_day_year">yyyy \'m\'. MMM d \'d\'., E</string>
+ <string name="full_wday_month_day_no_year_split">MMMM d \'d\'.\nEEEE</string>
</resources>
diff --git a/core/res/res/values-lt/donottranslate-cldr.xml b/core/res/res/values-lt/donottranslate-cldr.xml
index b1a94f3..40e2611 100644
--- a/core/res/res/values-lt/donottranslate-cldr.xml
+++ b/core/res/res/values-lt/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_year">y \'m\'. MMM d \'d\'.,E</string>
+ <string name="full_wday_month_day_no_year_split">EEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-lv-rLV/donottranslate-cldr.xml b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
index 3922f6b..9933775 100644
--- a/core/res/res/values-lv-rLV/donottranslate-cldr.xml
+++ b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, yyyy. \'g\'. dd. MMM</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-lv/donottranslate-cldr.xml b/core/res/res/values-lv/donottranslate-cldr.xml
index ec768bc..758b33a 100644
--- a/core/res/res/values-lv/donottranslate-cldr.xml
+++ b/core/res/res/values-lv/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E, d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">E, d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, yyyy. \'g\'. dd. MMM</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-mcc450-ko/config.xml b/core/res/res/values-mcc450-ko/config.xml
deleted file mode 100644
index 335b967..0000000
--- a/core/res/res/values-mcc450-ko/config.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
- <string name="gsm_alphabet_default_charset">euc-kr</string>
-</resources>
diff --git a/core/res/res/values-nb/donottranslate-cldr.xml b/core/res/res/values-nb/donottranslate-cldr.xml
index 8eb1ff6..b86c62b 100644
--- a/core/res/res/values-nb/donottranslate-cldr.xml
+++ b/core/res/res/values-nb/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-nl/donottranslate-cldr.xml b/core/res/res/values-nl/donottranslate-cldr.xml
index 1495a48..f19794c 100644
--- a/core/res/res/values-nl/donottranslate-cldr.xml
+++ b/core/res/res/values-nl/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 0f0e3d9..84702c5 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1456,4 +1456,41 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toegankelijkheid geannuleerd."</string>
<string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Eigenaar"</string>
+
+ <!-- CYANOGENMOD EDITS -->
+
+ <string name="profileNameDefault">Standaard</string>
+ <string name="profileNameWork">Zakelijk</string>
+ <string name="profileNameHome">Thuis</string>
+ <string name="profileNameSilent">Stil</string>
+ <string name="profileNameNight">\'s Nachts</string>
+ <string name="profileGroupPhone">Telefoon</string>
+ <string name="profileGroupCalendar">Agenda</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">E-mail</string>
+ <string name="profileGroupSMS">Sms</string>
+ <string name="wildcardProfile">Anders</string>
+ <string name="reboot_system" product="tablet">Tablet herstarten</string>
+ <string name="global_action_screenshot">Schermafdruk</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Uitgebreid bureaublad</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Ingeschakeld</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Uitgeschakeld</string>
+ <string name="reboot_reboot">Herstarten</string>
+ <string name="reboot_recovery">Recovery</string>
+ <string name="reboot_bootloader">Bootloader</string>
+ <string name="reboot_bootmenu">Bootmenu</string>
+ <string name="reboot_fastboot">Fastboot</string>
+ <string name="reboot_download">Download</string>
+ <string name="reboot_progress">Herstarten\u2026</string>
+ <string name="reboot_confirm" product="tablet">Uw tablet wordt herstart.</string>
+ <string name="reboot_confirm" product="default">Uw telefoon wordt herstart.</string>
+ <string name="permlab_preventpower">aan/uit-knop beheren</string>
+ <string name="permdesc_preventpower">Hiermee kan een app het gedrag van de aan/uit-knop wijzigen</string>
+ <string name="lockscreen_discharging">Ontladen, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+ <string name="app_killed_message">App afgesloten</string>
+ <string name="global_action_reboot">Herstarten</string>
+ <string name="global_action_choose_profile">Profiel</string>
+ <string name="toast_rotation_unlocked">Scherm wordt automatisch gedraaid</string>
+ <string name="toast_rotation_locked">Scherm wordt niet automatisch gedraaid</string>
+ <string name="storage_sd_dock_card">SD-kaart in dock</string>
</resources>
diff --git a/core/res/res/values-pl/donottranslate-cldr.xml b/core/res/res/values-pl/donottranslate-cldr.xml
index 53f0c36..48c91f4 100644
--- a/core/res/res/values-pl/donottranslate-cldr.xml
+++ b/core/res/res/values-pl/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/donottranslate-cldr.xml b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
index 26d8371..d27d3a2 100644
--- a/core/res/res/values-pt-rPT/donottranslate-cldr.xml
+++ b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEE, d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d \'de\' MMM \'de\' yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd \'de\' MMMM</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index ba97b8f..82c817a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1037,8 +1037,8 @@
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atenção"</string>
<string name="loading" msgid="7933681260296021180">"A carregar…"</string>
- <string name="capital_on" msgid="1544682755514494298">"Activado"</string>
- <string name="capital_off" msgid="6815870386972805832">"Desactivar"</string>
+ <string name="capital_on" msgid="1544682755514494298">"ON"</string>
+ <string name="capital_off" msgid="6815870386972805832">"OFF"</string>
<string name="whichApplication" msgid="4533185947064773386">"Concluir acção utilizando"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar por predefinição para esta acção."</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Limpar a predefinição nas Definições do Sistema &gt; Aplicações &gt; Transferidas."</string>
diff --git a/core/res/res/values-pt/donottranslate-cldr.xml b/core/res/res/values-pt/donottranslate-cldr.xml
index c3e6c29..ffc691f 100644
--- a/core/res/res/values-pt/donottranslate-cldr.xml
+++ b/core/res/res/values-pt/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEE, d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d \'de\' MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d \'de\' MMM \'de\' yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd \'de\' MMMM</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 5dfbe05..9ef0939 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1180,8 +1180,8 @@
<string name="usb_notification_message" msgid="2290859399983720271">"Toque para obter outras opções USB."</string>
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formatar armaz. USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formatar cartão SD?"</string>
- <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Todos os arquivos armazenados em sua unidade armazenamento USB serão apagados. Não é possível reverter essa ação."</string>
- <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Todos os dados em seu cartão serão perdidos."</string>
+ <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Todos os arquivos armazenados em sua unidade armazenamento USB (no caminho \'%1$s\') serão apagados. Não é possível reverter essa ação."</string>
+ <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Todos os dados em seu cartão (no caminho \'%1$s\') serão apagados. Não é possível reverter essa ação."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
<string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string>
@@ -1456,4 +1456,37 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string>
<string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Proprietário"</string>
+ <string name="profileNameDefault">Padrão</string>
+ <string name="profileNameWork">Trabalho</string>
+ <string name="profileNameHome">Casa</string>
+ <string name="profileNameSilent">Silêncio</string>
+ <string name="profileNameNight">Noite</string>
+ <string name="profileGroupPhone">Telefone</string>
+ <string name="profileGroupCalendar">Agenda</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Email</string>
+ <string name="profileGroupSMS">SMS</string>
+ <string name="wildcardProfile">Outro</string>
+ <string name="reboot_system" product="tablet">Reiniciar tablet</string>
+ <string name="global_action_screenshot">Capturar tela</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Área de trabalho expandida</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Ativada</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Desativada</string>
+ <string name="reboot_reboot">Reiniciar</string>
+ <string name="reboot_recovery">Recuperação</string>
+ <string name="reboot_bootloader">Bootloader</string>
+ <string name="reboot_bootmenu">Menu de boot</string>
+ <string name="reboot_fastboot">Fastboot</string>
+ <string name="reboot_download">Download</string>
+ <string name="reboot_progress">Reiniciando\u2026</string>
+ <string name="reboot_confirm">Seu telefone vai reiniciar.</string>
+ <string name="permlab_preventpower">substituir tecla de energia</string>
+ <string name="permdesc_preventpower">Permite a uma aplicação a substituir o tecla de energia</string>
+ <string name="lockscreen_discharging">Descarregando, <xliff:g id="number" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g><xliff:g id="percent" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%%</xliff:g></string>
+ <string name="app_killed_message">Aplicação terminada</string>
+ <string name="global_action_reboot">Reiniciar</string>
+ <string name="global_action_choose_profile">Perfil</string>
+ <string name="toast_rotation_unlocked">Rotação da tela está destravada</string>
+ <string name="toast_rotation_locked">Rotação da tela está travada</string>
+ <string name="storage_sd_dock_card">Dock cartão SD</string>
</resources>
diff --git a/core/res/res/values-ro-rRO/donottranslate-cldr.xml b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
index 7056803..7bbdb9e 100644
--- a/core/res/res/values-ro-rRO/donottranslate-cldr.xml
+++ b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-ro/donottranslate-cldr.xml b/core/res/res/values-ro/donottranslate-cldr.xml
index 935c6af..eec2ca0 100644
--- a/core/res/res/values-ro/donottranslate-cldr.xml
+++ b/core/res/res/values-ro/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">E, d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 94f6263..16e99fe 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1037,8 +1037,8 @@
<string name="no" msgid="5141531044935541497">"Anulaţi"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atenţie"</string>
<string name="loading" msgid="7933681260296021180">"Se încarcă…"</string>
- <string name="capital_on" msgid="1544682755514494298">"ACTIVAT"</string>
- <string name="capital_off" msgid="6815870386972805832">"DEZACTIVAT"</string>
+ <string name="capital_on" msgid="1544682755514494298">"PORNIT"</string>
+ <string name="capital_off" msgid="6815870386972805832">"OPRIT"</string>
<string name="whichApplication" msgid="4533185947064773386">"Finalizare acţiune utilizând"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Se utilizează în mod prestabilit pentru această acţiune."</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Ştergeţi setările prestabilite din Setări de sistem &gt; Aplicaţii &gt; Descărcate."</string>
@@ -1352,7 +1352,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opţiuni"</string>
<string name="storage_internal" msgid="4891916833657929263">"Stocare internă"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"Card SD"</string>
- <string name="storage_usb" msgid="3017954059538517278">"Dsipozitiv de stocare USB"</string>
+ <string name="storage_usb" msgid="3017954059538517278">"Dispozitiv de stocare USB"</string>
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Editaţi"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Avertisment de utiliz. a datelor"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Atingeţi pt. a afişa utiliz./set."</string>
@@ -1456,4 +1456,30 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilitatea a fost anulată"</string>
<string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Proprietar"</string>
+
+ <string name="reboot_system" product="tablet">"Reporniţi tablet PC"</string>
+ <string name="reboot_system" product="default">"Reporniţi telefonul"</string>
+ <string name="reboot_reboot">"Repornire"</string>
+ <string name="reboot_progress">"Repornire..."</string>
+ <string name="reboot_recovery">"Recuperare"</string>
+ <string name="reboot_confirm">"Telefonul dvs. va reporni."</string>
+ <string name="profileNameDefault">"General"</string>
+ <string name="profileNameWork">"Serviciu"</string>
+ <string name="profileNameHome">"Acasă"</string>
+ <string name="profileNameSilent">"Silenţios"</string>
+ <string name="profileNameNight">"Noapte"</string>
+ <string name="profileGroupPhone">"Telefon"</string>
+ <string name="profileGroupCalendar">"Calendar"</string>
+ <string name="profileGroupGmail">"Gmail"</string>
+ <string name="profileGroupEmail">"Email"</string>
+ <string name="profileGroupSMS">"SMS"</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">"Desktop extins"</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">"Activat"</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">"Dezactivat"</string>
+ <string name="global_action_reboot">"Repornire"</string>
+ <string name="global_action_choose_profile">"Profil"</string>
+ <string name="lockscreen_discharging">"Descărcare, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="toast_rotation_unlocked">"Rotire Ecran Deblocată"</string>
+ <string name="toast_rotation_locked">"Rotire Ecran Blocată"</string>
+ <string name="app_killed_message">"Aplicaţie oprită"</string>
</resources>
diff --git a/core/res/res/values-ru/donottranslate-cldr.xml b/core/res/res/values-ru/donottranslate-cldr.xml
index 03c64ab..17e6f1e 100644
--- a/core/res/res/values-ru/donottranslate-cldr.xml
+++ b/core/res/res/values-ru/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">E, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 9ff53cd..1c79fa6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -143,7 +143,7 @@
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Вибросигнал"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Звонок включен"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string>
- <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет выключен."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефон будет выключен."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Завершить работу?"</string>
<string name="reboot_safemode_title" msgid="7054509914500140361">"Переход в безопасный режим"</string>
@@ -761,7 +761,8 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Повторите попытку"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Повторите попытку"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Все попытки войти с помощью Фейсконтроля использованы"</string>
- <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Идет зарядка (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+ <string name="lockscreen_plugged_in">Зарядка батареи (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)</string>
+ <string name="lockscreen_discharging">Разрядка батареи (<xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g>)</string>
<string name="lockscreen_charged" msgid="321635745684060624">"Заряжено"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Подключите зарядное устройство"</string>
@@ -1456,4 +1457,25 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Специальные возможности не будут включены."</string>
<string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Владелец"</string>
+
+ <string name="reboot_system" product="tablet">Перезагрузка планшетного ПК</string>
+ <string name="reboot_system" product="default">Перезагрузка телефона</string>
+ <string name="global_action_screenshot">Скриншот</string>
+ <string name="global_actions_toggle_expanded_desktop_mode">Расширенный экран</string>
+ <string name="global_actions_expanded_desktop_mode_on_status">Включен</string>
+ <string name="global_actions_expanded_desktop_mode_off_status">Выключен</string>
+ <string name="reboot_reboot">Перезагрузка</string>
+ <string name="reboot_progress">Перезагрузка\u2026</string>
+ <string name="reboot_confirm">Ваш телефон будет перезагружен</string>
+ <string name="global_action_reboot">Перезагрузка</string>
+ <string name="global_action_choose_profile">Выбрать профиль</string>
+ <string name="app_killed_message">Приложение закрыто</string>
+ <string name="profileNameDefault">Стандартный</string>
+ <string name="profileNameWork">Работа</string>
+ <string name="profileNameHome">Дом</string>
+ <string name="profileNameSilent">Без звука</string>
+ <string name="profileNameNight">Ночь</string>
+ <string name="profileGroupPhone">Телефон</string>
+ <string name="profileGroupCalendar">Календарь</string>
+ <string name="wildcardProfile">Другой</string>
</resources>
diff --git a/core/res/res/values-sk-rSK/donottranslate-cldr.xml b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
index 651c58c..cd06cb7 100644
--- a/core/res/res/values-sk-rSK/donottranslate-cldr.xml
+++ b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-sk/donottranslate-cldr.xml b/core/res/res/values-sk/donottranslate-cldr.xml
index 48c644a..7e22e7d 100644
--- a/core/res/res/values-sk/donottranslate-cldr.xml
+++ b/core/res/res/values-sk/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E, d. MMMM</string>
<string name="abbrev_wday_month_day_no_year">E, d. MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d. MMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEE\nd. MMMM</string>
</resources>
diff --git a/core/res/res/values-sl-rSI/donottranslate-cldr.xml b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
index 84fffbd..05e464c 100644
--- a/core/res/res/values-sl-rSI/donottranslate-cldr.xml
+++ b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE MMMM d</string>
<string name="abbrev_wday_month_day_no_year">EEE MMMM d</string>
<string name="abbrev_wday_month_day_year">E, d. MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-sl/donottranslate-cldr.xml b/core/res/res/values-sl/donottranslate-cldr.xml
index 137ed3f..85332c5 100644
--- a/core/res/res/values-sl/donottranslate-cldr.xml
+++ b/core/res/res/values-sl/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_year">E., d. MMM. y</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-sr-rRS/donottranslate-cldr.xml b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
index 996c75e..6515e4c 100644
--- a/core/res/res/values-sr-rRS/donottranslate-cldr.xml
+++ b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE MMMM d</string>
<string name="abbrev_wday_month_day_no_year">EEE MMMM d</string>
<string name="abbrev_wday_month_day_year">EEE, d. MMM yyyy.</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-sr/donottranslate-cldr.xml b/core/res/res/values-sr/donottranslate-cldr.xml
index 7fca1a2..fd8539e 100644
--- a/core/res/res/values-sr/donottranslate-cldr.xml
+++ b/core/res/res/values-sr/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_year">EEE, d. MMM y.</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-sv/donottranslate-cldr.xml b/core/res/res/values-sv/donottranslate-cldr.xml
index 64c83f2..4730e48 100644
--- a/core/res/res/values-sv/donottranslate-cldr.xml
+++ b/core/res/res/values-sv/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-sw360dp/dimens.xml b/core/res/res/values-sw360dp/dimens.xml
new file mode 100644
index 0000000..850fa5a
--- /dev/null
+++ b/core/res/res/values-sw360dp/dimens.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+** Copyright 2012, The CyanogenMod 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>
+ <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_height">400dp</dimen>
+
+ <!-- Height of the sliding KeyguardSecurityContainer with hidden widget (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_no_widget_height">400dp</dimen>
+
+ <!-- Left padding of num pad key on keyguard -->
+ <dimen name="kg_num_pad_key_padding_left">20dp</dimen>
+</resources> \ No newline at end of file
diff --git a/core/res/res/values-sw720dp/dimens.xml b/core/res/res/values-sw720dp/dimens.xml
index ccdb4be..654fdd5 100644
--- a/core/res/res/values-sw720dp/dimens.xml
+++ b/core/res/res/values-sw720dp/dimens.xml
@@ -73,7 +73,7 @@
<!-- Keyguard dimensions -->
<!-- Size of the clock font in keyguard's status view -->
- <dimen name="kg_status_clock_font_size">188dp</dimen>
+ <dimen name="kg_status_clock_font_size">170dp</dimen>
<!-- Size of the date font in keyguard's status view -->
<dimen name="kg_status_date_font_size">34dp</dimen>
diff --git a/core/res/res/values-th-rTH/donottranslate-cldr.xml b/core/res/res/values-th-rTH/donottranslate-cldr.xml
index 2517143..66c72ed 100644
--- a/core/res/res/values-th-rTH/donottranslate-cldr.xml
+++ b/core/res/res/values-th-rTH/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-th/donottranslate-cldr.xml b/core/res/res/values-th/donottranslate-cldr.xml
index 7ab4191..6706a8f 100644
--- a/core/res/res/values-th/donottranslate-cldr.xml
+++ b/core/res/res/values-th/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E d MMMM</string>
<string name="abbrev_wday_month_day_no_year">E d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE d MMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-tl/donottranslate-cldr.xml b/core/res/res/values-tl/donottranslate-cldr.xml
index 4545fb5..ae280b1 100644
--- a/core/res/res/values-tl/donottranslate-cldr.xml
+++ b/core/res/res/values-tl/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_no_year">E MMMM d</string>
<string name="abbrev_wday_month_day_year">EEE, y MMM d</string>
+ <string name="full_wday_month_day_no_year_split">EEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values-tr/donottranslate-cldr.xml b/core/res/res/values-tr/donottranslate-cldr.xml
index 1ab4ff7..bff1b0e 100644
--- a/core/res/res/values-tr/donottranslate-cldr.xml
+++ b/core/res/res/values-tr/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">dd MMMM EEEE</string>
<string name="abbrev_wday_month_day_no_year">dd MMMM EEE</string>
<string name="abbrev_wday_month_day_year">dd MMM yyyy EEE</string>
+ <string name="full_wday_month_day_no_year_split">dd MMMM\nEEEE</string>
</resources>
diff --git a/core/res/res/values-uk-rUA/donottranslate-cldr.xml b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
index f7ca458..5467c7d 100644
--- a/core/res/res/values-uk-rUA/donottranslate-cldr.xml
+++ b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM yyyy \'р\'.</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-uk/donottranslate-cldr.xml b/core/res/res/values-uk/donottranslate-cldr.xml
index 51c2cb5..e6ed045 100644
--- a/core/res/res/values-uk/donottranslate-cldr.xml
+++ b/core/res/res/values-uk/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E, d MMMM</string>
<string name="abbrev_wday_month_day_no_year">E, d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-vi-rVN/donottranslate-cldr.xml b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
index a385015..5c7bbae 100644
--- a/core/res/res/values-vi-rVN/donottranslate-cldr.xml
+++ b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE d MMMM</string>
<string name="abbrev_wday_month_day_no_year">EEE d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-vi/donottranslate-cldr.xml b/core/res/res/values-vi/donottranslate-cldr.xml
index 977e021..8e7622e 100644
--- a/core/res/res/values-vi/donottranslate-cldr.xml
+++ b/core/res/res/values-vi/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">E d MMMM</string>
<string name="abbrev_wday_month_day_no_year">E d MMMM</string>
<string name="abbrev_wday_month_day_year">EEE, d MMM y</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nd MMMM</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/donottranslate-cldr.xml b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
index b34b8b3..6269cdf 100644
--- a/core/res/res/values-zh-rCN/donottranslate-cldr.xml
+++ b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">M 月 d 日 E</string>
<string name="abbrev_wday_month_day_no_year">M 月 d 日 E</string>
<string name="abbrev_wday_month_day_year">yyyy 年 M 月 d 日 EEE</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nM 月 d 日</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 425c497..3879947 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -36,6 +36,24 @@
<string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
<string name="mmiError" msgid="5154499457739052907">"出现连接问题或 MMI 码无效。"</string>
<string name="mmiFdnError" msgid="5224398216385316471">"只能对固定拨号号码执行此类操作。"</string>
+
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">默认</string>
+ <string name="profileNameWork">工作</string>
+ <string name="profileNameHome">住宅</string>
+ <string name="profileNameSilent">静音</string>
+ <string name="profileNameNight">夜晚</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">电话</string>
+ <string name="profileGroupCalendar">日历</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">电子邮件</string>
+ <string name="profileGroupSMS">短信</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">其他</string>
+
<string name="serviceEnabled" msgid="8147278346414714315">"已启用服务。"</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"已针对以下内容启用了服务:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"已停用服务。"</string>
@@ -135,16 +153,51 @@
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"平板电脑选项"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"手机选项"</string>
<string name="silent_mode" msgid="7167703389802618663">"静音模式"</string>
- <string name="turn_on_radio" msgid="3912793092339962371">"打开收音机"</string>
- <string name="turn_off_radio" msgid="8198784949987062346">"关闭收音机"</string>
+ <string name="turn_on_radio" msgid="3912793092339962371">"打开无线电"</string>
+ <string name="turn_off_radio" msgid="8198784949987062346">"关闭无线电"</string>
<string name="screen_lock" msgid="799094655496098153">"屏幕锁定"</string>
<string name="power_off" msgid="4266614107412865048">"关机"</string>
+
+ <!-- Button to reboot the phone, within the Phone Options dialog -->
+ <string name="reboot_system" product="tablet">重启平板</string>
+ <string name="reboot_system" product="default">重启手机</string>
+
+ <!-- label for item that screenshots in phone options dialog -->
+ <string name="global_action_screenshot">屏幕截图</string>
+
+ <!-- label for item that toggles expand desktop mode -->
+ <string name="global_actions_toggle_expanded_desktop_mode">扩展桌面</string>
+ <!-- status message in phone options dialog for when expand desktop mode is on -->
+ <string name="global_actions_expanded_desktop_mode_on_status">已启用</string>
+ <!-- status message in phone options dialog for when expand desktop mode is off -->
+ <string name="global_actions_expanded_desktop_mode_off_status">已禁用</string>
+
+ <!-- Button to reboot the phone, within the Reboot Options dialog -->
+ <string name="reboot_reboot">重新启动</string>
+ <!-- Button to reboot the phone into recovery, within the Reboot Options dialog -->
+ <string name="reboot_recovery">恢复模式</string>
+ <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog -->
+ <string name="reboot_bootloader">引导程序</string>
+ <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog -->
+ <string name="reboot_bootmenu">引导菜单</string>
+ <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog -->
+ <string name="reboot_fastboot">Fastboot</string>
+ <!-- Button to reboot the phone into download, within the Reboot Options dialog -->
+ <string name="reboot_download">下载模式</string>
+
+
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+ <string name="reboot_progress">正在重启\u2026</string>
+ <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. -->
+ <string name="reboot_confirm" product="tablet">您的平板电脑将会重启.</string>
+ <string name="reboot_confirm" product="default">您的手机将会重启.</string>
+
<string name="silent_mode_silent" msgid="319298163018473078">"振铃器关闭"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"振铃器振动"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"振铃器开启"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"正在关机..."</string>
- <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"您的平板电脑会关闭。"</string>
- <string name="shutdown_confirm" product="default" msgid="649792175242821353">"您的手机将会关机。"</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"您的平板电脑将会关机."</string>
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"您的手机将会关机."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"您要关机吗?"</string>
<string name="reboot_safemode_title" msgid="7054509914500140361">"重新启动并进入安全模式"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"您要重新启动并进入安全模式吗?这样会停用您已安装的所有第三方应用。再次重新启动将恢复这些应用。"</string>
@@ -374,6 +427,12 @@
<string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"允许该应用删除其他应用的缓存目录中的文件,从而释放手机存储空间。此权限可能会导致其他应用的启动速度变慢,因为应用必须重新检索数据。"</string>
<string name="permlab_movePackage" msgid="3289890271645921411">"移动应用资源"</string>
<string name="permdesc_movePackage" msgid="319562217778244524">"允许应用在内部与外部媒体之间移动应用资源。"</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_preventpower">阻止电源键</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preventpower">允许应用程序完全掌控电源键</string>
+
<string name="permlab_readLogs" msgid="6615778543198967614">"查阅敏感日志数据"</string>
<string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"允许应用从系统的各种日志文件中读取信息。这样,应用就可以发现关于您平板电脑使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
<string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允许应用从系统的各个日志文件中读取信息。这样,应用就可以发现关于您手机使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
@@ -750,7 +809,7 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 码有误。"</string>
<string name="keyguard_label_text" msgid="861796461028298424">"要解锁,请先按 MENU 再按 0。"</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"急救或报警电话"</string>
- <string name="lockscreen_carrier_default" msgid="8963839242565653192">"无服务。"</string>
+ <string name="lockscreen_carrier_default" msgid="8963839242565653192">"无服务."</string>
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"屏幕已锁定。"</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"按 Menu 解锁或进行紧急呼救。"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"按 MENU 解锁。"</string>
@@ -761,10 +820,11 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"重试"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"重试"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超过“人脸解锁”尝试次数上限"</string>
- <string name="lockscreen_plugged_in" msgid="8057762828355572315">"正在充电,<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_plugged_in" msgid="8057762828355572315">"正在充电, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_discharging">正在放电, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<string name="lockscreen_charged" msgid="321635745684060624">"充电完成"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <string name="lockscreen_low_battery" msgid="1482873981919249740">"连接您的充电器。"</string>
+ <string name="lockscreen_low_battery" msgid="1482873981919249740">"连接您的充电器, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g>"</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"没有 SIM 卡"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"平板电脑中没有 SIM 卡。"</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"手机中无 SIM 卡"</string>
@@ -1180,11 +1240,11 @@
<string name="usb_notification_message" msgid="2290859399983720271">"触摸可显示其他 USB 选项。"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"格式化 USB 存储设备吗?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"要格式化 SD 卡吗?"</string>
- <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"您的 USB 存储设备中存储的所有文件都将清除。该操作无法撤消!"</string>
- <string name="extmedia_format_message" product="default" msgid="14131895027543830">"您卡上的所有数据都会丢失。"</string>
+ <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"您在 USB 存储设备里 (\'%1$s\' 路径下) 存储的所有文件都将被删除. 该操作将无法被撤消!"</string>
+ <string name="extmedia_format_message" product="default" msgid="14131895027543830">"您卡上 (在 \'%1$s\' 路径下) 的所有数据都将被删除. 该操作将无法被撤消!"</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接 USB 调试"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸可停用 USB 调试。"</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"Android 调试模式已启用"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"选择即可停用调试模式."</string>
<string name="select_input_method" msgid="4653387336791222978">"选择输入法"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"设置输入法"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"物理键盘"</string>
@@ -1352,6 +1412,8 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"更多选项"</string>
<string name="storage_internal" msgid="4891916833657929263">"内存设备"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD 卡"</string>
+ <!-- Storage description for the SD card on the dock. [CHAR LIMIT=NONE] -->
+ <string name="storage_sd_dock_card">底座 SD 卡</string>
<string name="storage_usb" msgid="3017954059538517278">"USB 存储器"</string>
<string name="extract_edit_menu_button" msgid="8940478730496610137">"修改"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"流量使用警告"</string>
@@ -1390,6 +1452,10 @@
<string name="sending" msgid="3245653681008218030">"正在发送..."</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"要启动浏览器吗?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"要接听电话吗?"</string>
+
+ <!-- Long-press back kill application -->
+ <string name="app_killed_message">应用程序已被终止</string>
+
<string name="activity_resolver_use_always" msgid="8017770747801494933">"始终"</string>
<string name="activity_resolver_use_once" msgid="2404644797149173758">"仅此一次"</string>
<string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"平板电脑"</string>
@@ -1456,4 +1522,14 @@
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消辅助功能。"</string>
<string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="owner_name" msgid="2716755460376028154">"机主"</string>
+
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_reboot">重启</string>
+
+ <!-- label for item that opens the profile choosing dialog -->
+ <string name="global_action_choose_profile">情景模式</string>
+
+ <!-- Hardware Rotation lock string -->
+ <string name="toast_rotation_unlocked">屏幕方向已解锁</string>
+ <string name="toast_rotation_locked">屏幕方向已锁定</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/donottranslate-cldr.xml b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
index 869705e..4a67cb1 100644
--- a/core/res/res/values-zh-rTW/donottranslate-cldr.xml
+++ b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">M 月 d 日E</string>
<string name="abbrev_wday_month_day_no_year">M 月 d 日E</string>
<string name="abbrev_wday_month_day_year">yyyy 年 M 月 d 日EEE</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nM 月 d 日</string>
</resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f7ff77b..1a37ccc 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -413,4 +413,28 @@
<item>TUV</item><!-- 8 -->
<item>WXYZ</item><!-- 9 -->
</string-array>
+
+ <!-- Defines the shutdown options shown in the reboot dialog. -->
+ <array name="shutdown_reboot_options" translatable="false">
+ <item>@string/reboot_reboot</item>
+ <item>@string/reboot_recovery</item>
+ <item>@string/reboot_bootloader</item>
+ </array>
+
+ <!-- Do not translate. Defines the shutdown actions passed to the kernel.
+ The first item should be empty for regular reboot. -->
+ <string-array name="shutdown_reboot_actions" translatable="false">
+ <item></item>
+ <item>recovery</item>
+ <item>bootloader</item>
+ </string-array>
+
+ <!-- Do not translate. Defines the mapping of notification package names
+ from the actual triggering package to the user selectable package.
+ E.g. GTalk notifications come via Google Services Framework
+ Format: [triggering package]|[user package] -->
+ <string-array name="notification_light_package_mapping" translatable="false">
+ <item>com.google.android.gsf|com.google.android.talk</item>
+ </string-array>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cb7804c..d44079e 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -274,6 +274,9 @@
note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
<string translatable="false" name="config_tether_apndata"></string>
+ <!-- Boolean indicating whether Softap requires reloading AP firmware -->
+ <bool name="config_wifiApFirmwareReload">true</bool>
+
<!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
<bool translatable="false" name="config_wifi_dual_band_support">false</bool>
@@ -305,6 +308,10 @@
Default value is 2 minutes. -->
<integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer>
+ <!-- Boolean indicating whether the start command should be called on the wireless interface
+ when starting the SoftAp -->
+ <bool name="config_wifiApStartInterface">false</bool>
+
<!-- Flag indicating whether the we should enable the automatic brightness in Settings.
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">false</bool>
@@ -514,6 +521,12 @@
<!-- Is the notification LED intrusive? Used to decide if there should be a disable option -->
<bool name="config_intrusiveNotificationLed">false</bool>
+ <!-- Is the battery LED intrusive? Used to decide if there should be a disable option -->
+ <bool name="config_intrusiveBatteryLed">false</bool>
+
+ <!-- Does the battery LED support multiple colors? Used to decide if the user can change the colors -->
+ <bool name="config_multiColorBatteryLed">false</bool>
+
<!-- Default value for LED off time when the battery is low on charge in miliseconds -->
<integer name="config_notificationsBatteryLedOff">2875</integer>
@@ -699,6 +712,9 @@
cell broadcasting sms, and MMS. -->
<bool name="config_sms_capable">true</bool>
+ <!-- If this value is true, we handle Samsung CDMA's message ID method -->
+ <bool name="config_smsSamsungCdmaAlternateMessageIDEncoding">false</bool>
+
<!-- Enable/disable default bluetooth profiles:
HSP_AG, ObexObjectPush, Audio, NAP -->
<bool name="config_bluetooth_default_profiles">true</bool>
@@ -797,6 +813,14 @@
<!-- The VoiceMail default value is displayed to my own number if it is true -->
<bool name="config_telephony_use_own_number_for_voicemail">false</bool>
+ <!-- Set additional audio parameters for incall audio
+ Usage: parameter=onstring=offstring
+ Examples: <item>realcall=on=off</item>
+ <item>dualmic_enabled=true=false</item>
+ <item>mic_boost=yes=no</item> -->
+ <string-array name="config_telephony_set_audioparameters" translatable="false">
+ </string-array>
+
<!-- If this value is true, Sms encoded as octet is decoded by utf8 decoder.
If false, decoded by Latin decoder. -->
<bool name="config_sms_utf8_support">false</bool>
@@ -1024,4 +1048,80 @@
<!-- Flag indicating if the speed up audio on mt call code should be executed -->
<bool name="config_speed_up_audio_on_mt_calls">false</bool>
+
+ <!-- Values greater or equal to 0 will enable electronbeam screen-on
+ animation with the specified delay (in milliseconds), -1 will disable the animation -->
+ <integer name="config_screenOnAnimation">-1</integer>
+
+ <!-- True will enable the electron beam screen-off animation. -->
+ <bool name="config_screenOffAnimation">true</bool>
+
+ <!-- Timeout in MS for how long you have to long-press the back key to
+ kill the foreground app. -->
+ <integer name="config_backKillTimeout">2000</integer>
+
+ <!-- Device has a h/w rotation lock switch -->
+ <bool name="config_hasRotationLockSwitch">false</bool>
+
+ <!-- Workaround for devices with broken keyboards -->
+ <bool name="config_forceDisableHardwareKeyboard">false</bool>
+
+ <!-- Setting to false will disable CM's IME switcher implementation for tablets -->
+ <bool name="config_show_cmIMESwitcher">true</bool>
+
+ <!-- Boolean to enable stk functionality on Samsung phones -->
+ <bool name="config_samsung_stk">false</bool>
+
+ <!-- Disable the home key unlock setting -->
+ <bool name="config_disableHomeUnlockSetting">true</bool>
+
+ <!-- Hardware 'face' keys present on the device, stored as a bit field.
+ This integer should equal the sum of the corresponding value for each
+ of the following keys present:
+ 1 - Home
+ 2 - Back
+ 4 - Menu
+ 8 - Assistant (search)
+ 16 - App switch
+ For example, a device with Home, Back and Menu keys would set this
+ config to 7. -->
+ <integer name="config_deviceHardwareKeys">15</integer>
+
+ <!-- Maximum wallpaper width for devices with very high-res screen (1920x1200)
+ the wallpaper width suggestion by the launcher may be too large for
+ the GPU to handle. -->
+ <integer name="config_wallpaperMaxWidth">-1</integer>
+
+ <!-- Name of that dock battery handler class -->
+ <string name="config_deviceDockBatteryHandlerClass" translatable="false"></string>
+
+ <!-- LUN file to be used by legacy USB manager.
+ The existence of this file will be used to determine in the
+ legacy USB manager should be started. -->
+ <string name="config_legacyUmsLunFile">/sys/devices/platform/usb_mass_storage/lun0/file</string>
+
+ <!-- If a dock provides a lid switch, that lid can be removed. This
+ setting is used to determine, whether lidOpenRotation has to be
+ applied. -->
+ <bool name="config_hasRemovableLid">false</bool>
+
+ <!-- If true, adds support for no delay A2DP in Samsung devices -->
+ <bool name="config_noDelayInATwoDP">false</bool>
+
+ <!-- Dock battery compatibility (disabled by default) -->
+ <bool name="config_hasDockBattery">false</bool>
+
+ <!-- The list absolute paths of jar/apk files containing the device specific handlers,
+ delimited by File.pathSeparator, which defaults to ":" on Android -->
+ <string name="config_deviceHandlersLib" translatable="false"></string>
+
+ <!-- Full qualified name of the class that implements
+ com.android.internal.os.DeviceKeyHandler interface. -->
+ <string name="config_deviceKeyHandlerClass" translatable="false"></string>
+
+ <!-- Full qualified name of the class that implements
+ com.android.internal.os.DeviceDockBatteryHandler interface.
+ Requires config_hasDockBattery set to true. -->
+ <string name="config_deviceDockBatteryHandlerLib" translatable="false"></string>
+
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 637128a5..26fb4a0 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -241,6 +241,9 @@
<!-- Size of smaller notification text (see TextAppearance.StatusBar.EventContent.Line2, Info, Time) -->
<dimen name="notification_subtext_size">12dp</dimen>
+ <!-- Lockscreen target insets -->
+ <item type="dimen" name="lockscreen_target_inset">25dp</item>
+
<!-- Keyguard dimensions -->
<!-- TEMP -->
<dimen name="kg_security_panel_height">600dp</dimen>
@@ -307,7 +310,10 @@
<dimen name="keyguard_security_width">320dp</dimen>
<!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
- <dimen name="keyguard_security_height">400dp</dimen>
+ <dimen name="keyguard_security_height">350dp</dimen>
+
+ <!-- Height of the sliding KeyguardSecurityContainer with hidden widget (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_no_widget_height">450dp</dimen>
<!-- Margin around the various security views -->
<dimen name="keyguard_security_view_margin">8dp</dimen>
@@ -340,4 +346,7 @@
security mode. -->
<dimen name="kg_small_widget_height">160dp</dimen>
+ <!-- Left padding of num pad key on keyguard -->
+ <dimen name="kg_num_pad_key_padding_left">10dp</dimen>
+
</resources>
diff --git a/core/res/res/values/donottranslate-cldr.xml b/core/res/res/values/donottranslate-cldr.xml
index 0587c16..2df29f8 100644
--- a/core/res/res/values/donottranslate-cldr.xml
+++ b/core/res/res/values/donottranslate-cldr.xml
@@ -57,4 +57,5 @@
<string name="full_wday_month_day_no_year">EEEE, MMMM d</string>
<string name="abbrev_wday_month_day_no_year">EEE, MMMM d</string>
<string name="abbrev_wday_month_day_year">EEE, MMM d, yyyy</string>
+ <string name="full_wday_month_day_no_year_split">EEEE\nMMMM d</string>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index a5dae7e..75d66bb 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1,28 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This file defines the base public resources exported by the
- platform, which must always exist. -->
+ platform, which must always exist. -->
<!-- ***************************************************************
- ***************************************************************
- IMPORTANT NOTE FOR ANYONE MODIFYING THIS FILE
- READ THIS BEFORE YOU MAKE ANY CHANGES
+ ***************************************************************
+ IMPORTANT NOTE FOR ANYONE MODIFYING THIS FILE
+ READ THIS BEFORE YOU MAKE ANY CHANGES
- This file defines the binary compatibility for resources. As such,
- you must be very careful when making changes here, or you will
- completely break backwards compatibility with old applications.
+ This file defines the binary compatibility for resources. As such,
+ you must be very careful when making changes here, or you will
+ completely break backwards compatibility with old applications.
- To avoid breaking compatibility, all new resources must be placed
- at the end of the list of resources of the same type. Placing a resource
- in the middle of type will cause all following resources to be
- assigned new resource numbers, breaking compatibility.
+ To avoid breaking compatibility, all new resources must be placed
+ at the end of the list of resources of the same type. Placing a resource
+ in the middle of type will cause all following resources to be
+ assigned new resource numbers, breaking compatibility.
- ***************************************************************
- *************************************************************** -->
+ ***************************************************************
+ *************************************************************** -->
<resources>
<!-- ===============================================================
- Resources for version 1 of the platform.
- =============================================================== -->
+ Resources for version 1 of the platform.
+ =============================================================== -->
<eat-comment />
<public type="attr" name="theme" id="0x01010000" />
@@ -927,15 +927,15 @@
<public type="anim" name="decelerate_interpolator" id="0x010a0006" />
<!-- ===============================================================
- Resources added in version 2 of the platform.
- =============================================================== -->
+ Resources added in version 2 of the platform.
+ =============================================================== -->
<eat-comment />
<public type="attr" name="marqueeRepeatLimit" id="0x0101021d" />
<!-- ===============================================================
- Resources added in version 3 of the platform (Cupcake).
- =============================================================== -->
+ Resources added in version 3 of the platform (Cupcake).
+ =============================================================== -->
<eat-comment />
<public type="attr" name="windowNoDisplay" id="0x0101021e" />
@@ -1015,44 +1015,44 @@
<public type="attr" name="imeExtractExitAnimation" id="0x01010269" />
<!-- The part of the UI shown by an
- {@link android.inputmethodservice.InputMethodService} that contains the
- views for interacting with the user in extraction mode. -->
+ {@link android.inputmethodservice.InputMethodService} that contains the
+ views for interacting with the user in extraction mode. -->
<public type="id" name="extractArea" id="0x0102001c" />
<!-- The part of the UI shown by an
- {@link android.inputmethodservice.InputMethodService} that contains the
- views for displaying candidates for what the user has entered. -->
+ {@link android.inputmethodservice.InputMethodService} that contains the
+ views for displaying candidates for what the user has entered. -->
<public type="id" name="candidatesArea" id="0x0102001d" />
<!-- The part of the UI shown by an
- {@link android.inputmethodservice.InputMethodService} that contains the
- views for entering text using the screen. -->
+ {@link android.inputmethodservice.InputMethodService} that contains the
+ views for entering text using the screen. -->
<public type="id" name="inputArea" id="0x0102001e" />
<!-- Context menu ID for the "Select All" menu item to select all text
- in a text view. -->
+ in a text view. -->
<public type="id" name="selectAll" id="0x0102001f" />
<!-- Context menu ID for the "Cut" menu item to copy and delete the currently
- selected (or all) text in a text view to the clipboard. -->
+ selected (or all) text in a text view to the clipboard. -->
<public type="id" name="cut" id="0x01020020" />
<!-- Context menu ID for the "Copy" menu item to copy the currently
- selected (or all) text in a text view to the clipboard. -->
+ selected (or all) text in a text view to the clipboard. -->
<public type="id" name="copy" id="0x01020021" />
<!-- Context menu ID for the "Paste" menu item to copy the current contents
- of the clipboard into the text view. -->
+ of the clipboard into the text view. -->
<public type="id" name="paste" id="0x01020022" />
<!-- Context menu ID for the "Copy URL" menu item to copy the currently
- selected URL from the text view to the clipboard. -->
+ selected URL from the text view to the clipboard. -->
<public type="id" name="copyUrl" id="0x01020023" />
<!-- Context menu ID for the "Input Method" menu item to being up the
- input method picker dialog, allowing the user to switch to another
- input method. -->
+ input method picker dialog, allowing the user to switch to another
+ input method. -->
<public type="id" name="switchInputMethod" id="0x01020024" />
<!-- View ID of the text editor inside of an extracted text layout. -->
<public type="id" name="inputExtractEditText" id="0x01020025" />
<!-- View ID of the {@link android.inputmethodservice.KeyboardView} within
- an input method's input area. -->
+ an input method's input area. -->
<public type="id" name="keyboardView" id="0x01020026" />
<!-- View ID of a {@link android.view.View} to close a popup keyboard -->
<public type="id" name="closeButton" id="0x01020027" />
@@ -1088,8 +1088,8 @@
<public type="integer" name="config_longAnimTime" id="0x010e0002" />
<!-- ===============================================================
- Resources added in version 4 of the platform (Donut).
- =============================================================== -->
+ Resources added in version 4 of the platform (Donut).
+ =============================================================== -->
<eat-comment />
<public type="attr" name="tension" id="0x0101026a" />
@@ -1145,8 +1145,8 @@
<public type="anim" name="linear_interpolator" id="0x010a000b" />
<!-- ===============================================================
- Resources added in version 5 of the platform (Eclair).
- =============================================================== -->
+ Resources added in version 5 of the platform (Eclair).
+ =============================================================== -->
<eat-comment />
<public type="attr" name="required" id="0x0101028e" />
@@ -1191,16 +1191,16 @@
<public type="style" name="TextAppearance.SearchResult.Subtitle" id="0x01030064" />
<!-- Semi-transparent background that can be used when placing a dark
- themed UI on top of some arbitrary background (such as the
- wallpaper). This darkens the background sufficiently that the UI
- can be seen. -->
+ themed UI on top of some arbitrary background (such as the
+ wallpaper). This darkens the background sufficiently that the UI
+ can be seen. -->
<public type="drawable" name="screen_background_dark_transparent" id="0x010800a9" />
<public type="drawable" name="screen_background_light_transparent" id="0x010800aa" />
<public type="drawable" name="stat_notify_sdcard_prepare" id="0x010800ab" />
<!-- ===============================================================
- Resources added in version 6 of the platform (Eclair 2.0.1).
- =============================================================== -->
+ Resources added in version 6 of the platform (Eclair 2.0.1).
+ =============================================================== -->
<eat-comment />
<public type="attr" name="quickContactBadgeStyleWindowSmall" id="0x010102ae" />
@@ -1211,8 +1211,8 @@
<public type="attr" name="quickContactBadgeStyleSmallWindowLarge" id="0x010102b3" />
<!-- ===============================================================
- Resources added in version 7 of the platform (Eclair MR1).
- =============================================================== -->
+ Resources added in version 7 of the platform (Eclair MR1).
+ =============================================================== -->
<eat-comment />
<public type="attr" name="author" id="0x010102b4" />
@@ -1220,15 +1220,15 @@
<!-- ===============================================================
- Resources added in version 8 of the platform (Eclair MR2).
- =============================================================== -->
+ Resources added in version 8 of the platform (Eclair MR2).
+ =============================================================== -->
<eat-comment />
<public type="attr" name="expandableListViewWhiteStyle" id="0x010102b6" />
<!-- ===============================================================
- Resources added in version 8 of the platform (Froyo / 2.2)
- =============================================================== -->
+ Resources added in version 8 of the platform (Froyo / 2.2)
+ =============================================================== -->
<eat-comment />
<public type="attr" name="installLocation" id="0x010102b7" />
<public type="attr" name="vmSafeMode" id="0x010102b8" />
@@ -1243,8 +1243,8 @@
<public type="anim" name="cycle_interpolator" id="0x010a000c" />
<!-- ===============================================================
- Resources added in version 9 of the platform (Gingerbread / 2.3)
- =============================================================== -->
+ Resources added in version 9 of the platform (Gingerbread / 2.3)
+ =============================================================== -->
<eat-comment />
<public type="attr" name="logo" id="0x010102be" />
<public type="attr" name="xlargeScreens" id="0x010102bf" />
@@ -1275,8 +1275,8 @@
<public type="style" name="TextAppearance.StatusBar.EventContent.Title" id="0x01030068" />
<!-- ===============================================================
- Resources added in version 11 of the platform (Honeycomb / 3.0).
- =============================================================== -->
+ Resources added in version 11 of the platform (Honeycomb / 3.0).
+ =============================================================== -->
<eat-comment />
<public type="attr" name="allContactsName" id="0x010102cc" />
@@ -1454,22 +1454,22 @@
<!-- An interpolator where the change starts backward then flings forward. -->
<public type="interpolator" name="anticipate" id="0x010c0007" />
<!-- An interpolator where the change flings forward and overshoots the last
- value then comes back. -->
+ value then comes back. -->
<public type="interpolator" name="overshoot" id="0x010c0008" />
<!-- An interpolator where the change starts backward then flings forward and
- overshoots the target value and finally goes back to the final value. -->
+ overshoots the target value and finally goes back to the final value. -->
<public type="interpolator" name="anticipate_overshoot" id="0x010c0009" />
<!-- An interpolator where the change bounces at the end. -->
<public type="interpolator" name="bounce" id="0x010c000a" />
<!-- An interpolator where the rate of change is constant. -->
<public type="interpolator" name="linear" id="0x010c000b" />
<!-- Repeats the animation for one cycle. The rate of change follows a
- sinusoidal pattern. -->
+ sinusoidal pattern. -->
<public type="interpolator" name="cycle" id="0x010c000c" />
<public type="id" name="home" id="0x0102002c" />
<!-- Context menu ID for the "Select text..." menu item to switch to text
- selection context mode in text views. -->
+ selection context mode in text views. -->
<public type="id" name="selectTextMode" id="0x0102002d" />
<public type="dimen" name="dialog_min_width_major" id="0x01050003" />
@@ -1478,23 +1478,23 @@
<public type="dimen" name="notification_large_icon_height" id="0x01050006" />
<!-- Standard content view for a {@link android.app.ListFragment}.
- If you are implementing a subclass of ListFragment with your
- own customized content, you can include this layout in that
- content to still retain all of the standard functionality of
- the base class. -->
+ If you are implementing a subclass of ListFragment with your
+ own customized content, you can include this layout in that
+ content to still retain all of the standard functionality of
+ the base class. -->
<public type="layout" name="list_content" id="0x01090014" />
<!-- A simple ListView item layout which can contain text and support (single or multiple) item selection. -->
<public type="layout" name="simple_selectable_list_item" id="0x01090015" />
<!-- A version of {@link #simple_list_item_1} that is able to change its
- background state to indicate when it is activated (that is checked by
- a ListView). -->
+ background state to indicate when it is activated (that is checked by
+ a ListView). -->
<public type="layout" name="simple_list_item_activated_1" id="0x01090016" />
<!-- A version of {@link #simple_list_item_2} that is able to change its
- background state to indicate when it is activated (that is checked by
- a ListView). -->
+ background state to indicate when it is activated (that is checked by
+ a ListView). -->
<public type="layout" name="simple_list_item_activated_2" id="0x01090017" />
<public type="drawable" name="dialog_holo_dark_frame" id="0x010800b2" />
@@ -1642,15 +1642,15 @@
<public type="mipmap" name="sym_def_app_icon" id="0x010d0000" />
<!-- ===============================================================
- Resources added in version 12 of the platform (Honeycomb MR 1 / 3.1)
- =============================================================== -->
+ Resources added in version 12 of the platform (Honeycomb MR 1 / 3.1)
+ =============================================================== -->
<eat-comment />
<public type="attr" name="textCursorDrawable" id="0x01010362" />
<public type="attr" name="resizeMode" id="0x01010363" />
<!-- ===============================================================
- Resources added in version 13 of the platform (Honeycomb MR 2 / 3.2)
- =============================================================== -->
+ Resources added in version 13 of the platform (Honeycomb MR 2 / 3.2)
+ =============================================================== -->
<eat-comment />
<public type="attr" name="requiresSmallestWidthDp" id="0x01010364" />
<public type="attr" name="compatibleWidthLimitDp" id="0x01010365" />
@@ -1699,8 +1699,8 @@
<public type="style" name="TextAppearance.Holo.DialogWindowTitle" id="0x01030117" />
<!-- ===============================================================
- Resources added in version 14 of the platform (Ice Cream Sandwich / 4.0)
- =============================================================== -->
+ Resources added in version 14 of the platform (Ice Cream Sandwich / 4.0)
+ =============================================================== -->
<eat-comment />
<public type="attr" name="state_hovered" id="0x01010367" />
<public type="attr" name="state_drag_can_accept" id="0x01010368" />
@@ -1973,8 +1973,8 @@
<public type="color" name="holo_blue_bright" id="0x0106001b" />
<!-- ===============================================================
- Resources added in version 16 of the platform (Jelly Bean)
- =============================================================== -->
+ Resources added in version 16 of the platform (Jelly Bean)
+ =============================================================== -->
<eat-comment />
<public type="attr" name="parentActivityName" id="0x010103a7" />
<public type="attr" name="isolatedProcess" id="0x010103a9" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 99fbf95..969cc5f 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -68,6 +68,23 @@
could not be performed because FDN is enabled. This will be displayed in a toast. -->
<string name="mmiFdnError">Operation is restricted to fixed dialing numbers only.</string>
+ <!-- Names of default profiles. -->
+ <string name="profileNameDefault">Default</string>
+ <string name="profileNameWork">Work</string>
+ <string name="profileNameHome">Home</string>
+ <string name="profileNameSilent">Silent</string>
+ <string name="profileNameNight">Night</string>
+
+ <!-- Names of application groups. -->
+ <string name="profileGroupPhone">Phone</string>
+ <string name="profileGroupCalendar">Calendar</string>
+ <string name="profileGroupGmail">Gmail</string>
+ <string name="profileGroupEmail">Email</string>
+ <string name="profileGroupSMS">SMS</string>
+
+ <!-- Name of wildcard profile. -->
+ <string name="wildcardProfile">Other</string>
+
<!-- Displayed when a phone feature such as call barring was activated. -->
<string name="serviceEnabled">Service was enabled.</string>
<!-- Displayed in front of the list of a set of service classes
@@ -292,6 +309,41 @@
<string name="screen_lock">Screen lock</string>
<!-- Button to turn off the phone, within the Phone Options dialog -->
<string name="power_off">Power off</string>
+
+ <!-- Button to reboot the phone, within the Phone Options dialog -->
+ <string name="reboot_system" product="tablet">Reboot tablet</string>
+ <string name="reboot_system" product="default">Reboot phone</string>
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+
+ <!-- label for item that screenshots in phone options dialog -->
+ <string name="global_action_screenshot">Screenshot</string>
+
+ <!-- label for item that toggles expand desktop mode -->
+ <string name="global_actions_toggle_expanded_desktop_mode">Expanded desktop</string>
+ <!-- status message in phone options dialog for when expand desktop mode is on -->
+ <string name="global_actions_expanded_desktop_mode_on_status">Enabled</string>
+ <!-- status message in phone options dialog for when expand desktop mode is off -->
+ <string name="global_actions_expanded_desktop_mode_off_status">Disabled</string>
+
+ <!-- Button to reboot the phone, within the Reboot Options dialog -->
+ <string name="reboot_reboot">Reboot</string>
+ <!-- Button to reboot the phone into recovery, within the Reboot Options dialog -->
+ <string name="reboot_recovery">Recovery</string>
+ <!-- Button to reboot the phone into bootloader, within the Reboot Options dialog -->
+ <string name="reboot_bootloader">Bootloader</string>
+ <!-- Button to reboot the phone into bootmenu, within the Reboot Options dialog -->
+ <string name="reboot_bootmenu">Bootmenu</string>
+ <!-- Button to reboot the phone into fastboot, within the Reboot Options dialog -->
+ <string name="reboot_fastboot">Fastboot</string>
+ <!-- Button to reboot the phone into download, within the Reboot Options dialog -->
+ <string name="reboot_download">Download</string>
+
+ <!-- Reboot Progress Dialog. This is shown if the user chooses to reboot the phone. -->
+ <string name="reboot_progress">Rebooting\u2026</string>
+ <!-- Reboot Confirmation Dialog. When the user chooses to reboot the phone, there will be a confirmation dialog. This is the message. -->
+ <string name="reboot_confirm" product="tablet">Your tablet will reboot.</string>
+ <string name="reboot_confirm" product="default">Your phone will reboot.</string>
+
<!-- Spoken description for ringer silent option. [CHAR LIMIT=NONE] -->
<string name="silent_mode_silent">Ringer off</string>
<!-- Spoken description for ringer vibrate option. [CHAR LIMIT=NONE] -->
@@ -356,7 +408,6 @@
current device state, to send as an e-mail message. It will take a little
time from starting the bug report until it is ready to be sent; please be
patient.</string>
-
<!-- label for item that enables silent mode in phone options dialog -->
<string name="global_action_toggle_silent_mode">Silent mode</string>
@@ -1023,6 +1074,11 @@
<string name="permdesc_movePackage">Allows the app to move app resources from internal to external media and vice versa.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_preventpower">prevent power key</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preventpower">Allows an application to override the power key</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readLogs">read sensitive log data</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readLogs" product="tablet">Allows the app to read from the
@@ -1392,6 +1448,18 @@
<string name="permdesc_vibrate">Allows the app to control the vibrator.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_fm_radio_receiver">control FM receiver</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_fm_radio_receiver">Allows the application to control
+ the FM receiver.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_fm_radio_transmitter">control FM transmitter</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_fm_radio_transmitter">Allows the application to control
+ the FM transmitter.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_flashlight">control flashlight</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_flashlight">Allows the app to control the flashlight.</string>
@@ -2099,6 +2167,7 @@
<!-- When the lock screen is showing and the phone plugged in, and the battery
is not fully charged, show the current charge %. -->
<string name="lockscreen_plugged_in">Charging, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+ <string name="lockscreen_discharging">Discharging, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<!-- When the lock screen is showing, the phone is plugged in and the battery is fully
charged, say that it is charged. -->
<string name="lockscreen_charged">Charged</string>
@@ -2106,8 +2175,8 @@
<string name="lockscreen_battery_short"><xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<!-- When the lock screen is showing and the battery is low, warn user to plug
- in the phone soon. -->
- <string name="lockscreen_low_battery">Connect your charger.</string>
+ in the phone soon and show current percentage. -->
+ <string name="lockscreen_low_battery">Connect your charger, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
<!-- Shown in the lock screen when there is no SIM card. -->
<string name="lockscreen_missing_sim_message_short">No SIM card</string>
@@ -3281,16 +3350,16 @@
<!-- See EXTMEDIA_FORMAT. EXTMEDIA_FORMAT_DIALOG: After the user selects the notification, a dialog is shown asking if he wants to format the SD card. This is the title. -->
<string name="extmedia_format_title" product="default">Format SD card?</string>
<!-- See EXTMEDIA_FORMAT. This is the message. [CHAR LIMIT=NONE] -->
- <string name="extmedia_format_message" product="nosdcard">All files stored in your USB storage will be erased. This action can\'t be reversed!</string>
+ <string name="extmedia_format_message" product="nosdcard">All files stored in your USB storage (under path \'%1$s\') will be erased. This action can\'t be reversed!</string>
<!-- See EXTMEDIA_FORMAT. This is the message. -->
- <string name="extmedia_format_message" product="default">All data on your card will be lost.</string>
+ <string name="extmedia_format_message" product="default">All data on your card (under path \'%1$s\') will be erased. This action can\'t be reversed!</string>
<!-- See EXTMEDIA_FORMAT. This is the button text to format the sd card. -->
<string name="extmedia_format_button_format">Format</string>
<!-- Title of notification shown when ADB is actively connected to the phone. -->
- <string name="adb_active_notification_title">USB debugging connected</string>
+ <string name="adb_active_notification_title">Android debugging enabled</string>
<!-- Message of notification shown when ADB is actively connected to the phone. -->
- <string name="adb_active_notification_message">Touch to disable USB debugging.</string>
+ <string name="adb_active_notification_message">Select to disable debugging.</string>
<!-- Used to replace %s in urls retreived from the signin server with locales. For Some -->
<!-- devices we don't support all the locales we ship to and need to replace the '%s' with a -->
@@ -3711,6 +3780,9 @@
<!-- Storage description for the SD card. [CHAR LIMIT=NONE] -->
<string name="storage_sd_card">SD card</string>
+ <!-- Storage description for the SD card on the dock. [CHAR LIMIT=NONE] -->
+ <string name="storage_sd_dock_card">Dock SD card</string>
+
<!-- Storage description for USB storage. [CHAR LIMIT=NONE] -->
<string name="storage_usb">USB storage</string>
@@ -3804,6 +3876,9 @@
<!-- STK setup Call -->
<string name="SetupCallDefault">Accept call?</string>
+ <!-- Long-press back kill application -->
+ <string name="app_killed_message">Application killed</string>
+
<!-- Title for a button to choose the currently selected activity
as the default in the activity resolver. [CHAR LIMIT=25] -->
<string name="activity_resolver_use_always">Always</string>
@@ -4005,4 +4080,13 @@
<!-- Default name of the owner user [CHAR LIMIT=20] -->
<string name="owner_name" msgid="3879126011135546571">Owner</string>
+ <!-- label for item that reboots the phone in phone options dialog -->
+ <string name="global_action_reboot">Reboot</string>
+
+ <!-- label for item that opens the profile choosing dialog -->
+ <string name="global_action_choose_profile">Profile</string>
+
+ <!-- Hardware Rotation lock string -->
+ <string name="toast_rotation_unlocked">Display rotation unlocked</string>
+ <string name="toast_rotation_locked">Display rotation locked</string>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f489786..d269601 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2489,7 +2489,7 @@ please see styles_device_defaults.xml.
<item name="android:textStyle">normal</item>
<item name="android:textColor">#ffffff</item>
<item name="android:paddingBottom">10dp</item>
- <item name="android:paddingLeft">20dp</item>
+ <item name="android:paddingLeft">@dimen/kg_num_pad_key_padding_left</item>
</style>
<style name="TextAppearance.NumPadKey"
parent="@android:style/TextAppearance">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 391320b..99b3866 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -587,6 +587,7 @@
<java-symbol type="string" name="lockscreen_transport_pause_description" />
<java-symbol type="string" name="lockscreen_transport_play_description" />
<java-symbol type="string" name="lockscreen_transport_stop_description" />
+
<java-symbol type="string" name="low_memory" />
<java-symbol type="string" name="media_bad_removal" />
<java-symbol type="string" name="media_checking" />
@@ -977,6 +978,8 @@
<java-symbol type="drawable" name="picture_emergency" />
<java-symbol type="drawable" name="platlogo" />
<java-symbol type="drawable" name="platlogo_alt" />
+ <java-symbol type="drawable" name="cidlogo" />
+ <java-symbol type="drawable" name="cidlogo_alt" />
<java-symbol type="drawable" name="stat_notify_sync_error" />
<java-symbol type="drawable" name="stat_notify_wifi_in_range" />
<java-symbol type="drawable" name="stat_notify_rssi_in_range" />
@@ -1247,12 +1250,17 @@
<java-symbol type="dimen" name="kg_edge_swipe_region_size" />
<java-symbol type="dimen" name="kg_squashed_layout_threshold" />
<java-symbol type="dimen" name="kg_small_widget_height" />
+ <java-symbol type="dimen" name="lockscreen_target_inset" />
<java-symbol type="drawable" name="ic_jog_dial_sound_off" />
<java-symbol type="drawable" name="ic_jog_dial_sound_on" />
<java-symbol type="drawable" name="ic_jog_dial_unlock" />
<java-symbol type="drawable" name="ic_jog_dial_vibrate_on" />
<java-symbol type="drawable" name="ic_lock_airplane_mode" />
<java-symbol type="drawable" name="ic_lock_airplane_mode_off" />
+ <java-symbol type="drawable" name="ic_lockscreen_lock_pressed" />
+ <java-symbol type="drawable" name="ic_lockscreen_target_activated" />
+ <java-symbol type="drawable" name="ic_lockscreen_unlock_activated" />
+ <java-symbol type="drawable" name="ic_lockscreen_unlock_normal" />
<java-symbol type="drawable" name="ic_menu_cc" />
<java-symbol type="drawable" name="jog_tab_bar_left_unlock" />
<java-symbol type="drawable" name="jog_tab_bar_right_sound_off" />
@@ -1752,6 +1760,7 @@
<!-- From Settings -->
<java-symbol type="array" name="config_mobile_hotspot_provision_app" />
<java-symbol type="bool" name="config_intrusiveNotificationLed" />
+ <java-symbol type="bool" name="config_intrusiveBatteryLed" />
<java-symbol type="dimen" name="preference_fragment_padding_bottom" />
<java-symbol type="dimen" name="preference_fragment_padding_side" />
<java-symbol type="drawable" name="expander_ic_maximized" />
@@ -1819,4 +1828,84 @@
<!-- From PinyinIME(!!!) -->
<java-symbol type="string" name="inputMethod" />
+
+<!-- ===============================================================
+ Resources added in version 10 of CyanogenMod
+ =============================================================== -->
+ <eat-comment />
+
+ <!-- Config.xml entries -->
+ <java-symbol type="bool" name="config_forceDisableHardwareKeyboard" />
+ <java-symbol type="bool" name="config_hasRotationLockSwitch" />
+ <java-symbol type="integer" name="config_backKillTimeout" />
+ <java-symbol type="bool" name="config_show_cmIMESwitcher"/>
+ <java-symbol type="integer" name="config_wallpaperMaxWidth" />
+ <java-symbol type="string" name="config_legacyUmsLunFile" />
+ <java-symbol type="bool" name="config_hasRemovableLid" />
+ <java-symbol type="bool" name="config_hasDockBattery" />
+ <java-symbol type="bool" name="config_noDelayInATwoDP" />
+
+ <!-- Telephony -->
+ <java-symbol type="bool" name="config_smsSamsungCdmaAlternateMessageIDEncoding" />
+ <java-symbol type="bool" name="config_samsung_stk" />
+ <java-symbol type="array" name="config_telephony_set_audioparameters" />
+
+ <!-- Hardware Key ReMapping -->
+ <java-symbol type="integer" name="config_deviceHardwareKeys" />
+
+ <!-- Notification and battery light -->
+ <java-symbol type="bool" name="config_intrusiveBatteryLed" />
+ <java-symbol type="bool" name="config_multiColorBatteryLed" />
+ <java-symbol type="array" name="notification_light_package_mapping" />
+
+ <!-- Power menu -->
+ <java-symbol type="string" name="global_action_screenshot" />
+ <java-symbol type="string" name="global_action_choose_profile" />
+ <java-symbol type="string" name="global_action_reboot" />
+ <java-symbol type="string" name="global_actions_toggle_expanded_desktop_mode" />
+ <java-symbol type="string" name="global_actions_expanded_desktop_mode_off_status" />
+ <java-symbol type="string" name="global_actions_expanded_desktop_mode_on_status" />
+ <java-symbol type="string" name="global_actions" />
+ <java-symbol type="string" name="reboot_system" />
+ <java-symbol type="string" name="reboot_progress" />
+ <java-symbol type="array" name="shutdown_reboot_options" />
+ <java-symbol type="array" name="shutdown_reboot_actions" />
+ <java-symbol type="drawable" name="ic_lock_screenshot" />
+ <java-symbol type="drawable" name="ic_lock_reboot" />
+ <java-symbol type="drawable" name="ic_lock_profile" />
+ <java-symbol type="drawable" name="ic_lock_expanded_desktop" />
+
+ <!-- Profiles -->
+ <java-symbol type="xml" name="profile_default" />
+ <java-symbol type="string" name="wildcardProfile" />
+
+ <!-- Power widget -->
+ <java-symbol type="string" name="hour" />
+ <java-symbol type="string" name="hours" />
+ <java-symbol type="string" name="minute" />
+ <java-symbol type="string" name="minutes" />
+ <java-symbol type="string" name="second" />
+ <java-symbol type="string" name="seconds" />
+
+ <!-- Developer settings - Kill app back press -->
+ <java-symbol type="string" name="app_killed_message" />
+
+ <!-- Lockscreen -->
+ <java-symbol type="bool" name="config_disableHomeUnlockSetting" />
+ <java-symbol type="id" name="expand_challenge_handle" />
+ <!-- Lock screen always show battery -->
+ <java-symbol type="string" name="lockscreen_discharging" />
+
+ <!-- HW rotation lock -->
+ <java-symbol type="string" name="toast_rotation_unlocked" />
+ <java-symbol type="string" name="toast_rotation_locked" />
+
+ <!-- Wifi -->
+ <java-symbol type="bool" name="config_wifiApStartInterface" />
+ <java-symbol type="bool" name="config_wifiApFirmwareReload" />
+
+ <!-- Device specific handlers -->
+ <java-symbol type="string" name="config_deviceHandlersLib" />
+ <java-symbol type="string" name="config_deviceKeyHandlerClass" />
+ <java-symbol type="string" name="config_deviceDockBatteryHandlerClass" />
</resources>
diff --git a/core/res/res/xml/profile_default.xml b/core/res/res/xml/profile_default.xml
new file mode 100644
index 0000000..824a73c
--- /dev/null
+++ b/core/res/res/xml/profile_default.xml
@@ -0,0 +1,267 @@
+<profiles>
+ <profile nameres="profileNameDefault">
+ <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ </profile>
+ <profile nameres="profileNameWork">
+ <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>OVERRIDE</soundMode>
+ <ringerMode>OVERRIDE</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>OVERRIDE</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>OVERRIDE</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>SUPPRESS</vibrateMode>
+ <lightsMode>SUPPRESS</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>OVERRIDE</soundMode>
+ <ringerMode>OVERRIDE</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ </profile>
+ <profile nameres="profileNameHome">
+ <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1">
+ <sound>content://media/external/audio/media/11</sound>
+ <ringer>content://media/external/audio/media/5</ringer>
+ <soundMode>OVERRIDE</soundMode>
+ <ringerMode>OVERRIDE</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>OVERRIDE</soundMode>
+ <ringerMode>OVERRIDE</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>OVERRIDE</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>OVERRIDE</soundMode>
+ <ringerMode>OVERRIDE</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>OVERRIDE</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>OVERRIDE</soundMode>
+ <ringerMode>OVERRIDE</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>DEFAULT</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ </profile>
+ <profile nameres="profileNameSilent">
+ <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>SUPPRESS</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ </profile>
+ <profile nameres="profileNameNight">
+ <profileGroup uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>OVERRIDE</soundMode>
+ <ringerMode>OVERRIDE</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>SUPPRESS</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>SUPPRESS</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="db3318cd-1964-4732-b913-1f83d73a3dea">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>SUPPRESS</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>SUPPRESS</ringerMode>
+ <vibrateMode>OVERRIDE</vibrateMode>
+ <lightsMode>SUPPRESS</lightsMode>
+ </profileGroup>
+ <profileGroup uuid="a126d48a-aaef-47c4-baed-7f0e44aeffe5" default="true">
+ <sound>content://settings/system/notification_sound</sound>
+ <ringer>content://settings/system/ringtone</ringer>
+ <soundMode>SUPPRESS</soundMode>
+ <ringerMode>DEFAULT</ringerMode>
+ <vibrateMode>DEFAULT</vibrateMode>
+ <lightsMode>DEFAULT</lightsMode>
+ </profileGroup>
+ </profile>
+ <notificationGroup nameres="profileGroupPhone" uuid="d393035d-ea71-4f2a-bdbd-b65f6bf298f1">
+ <package>com.android.phone</package>
+ </notificationGroup>
+ <notificationGroup nameres="profileGroupCalendar" uuid="66bc93e4-775a-4ac2-9da1-752178fcdcaf">
+ <package>com.android.calendar</package>
+ </notificationGroup>
+ <notificationGroup nameres="profileGroupGmail" uuid="d2ebb02a-5205-47c5-8e39-f55823d4082a">
+ <package>com.google.android.gm</package>
+ </notificationGroup>
+ <notificationGroup nameres="profileGroupEmail" uuid="db3318cd-1964-4732-b913-1f83d73a3dea">
+ <package>com.android.email</package>
+ </notificationGroup>
+ <notificationGroup nameres="profileGroupSMS" uuid="da4f1e2d-0e50-4789-acd4-5ca2b53a981b">
+ <package>com.android.mms</package>
+ </notificationGroup>
+</profiles>
diff --git a/data/etc/com.stericsson.hardware.fm.receiver.xml b/data/etc/com.stericsson.hardware.fm.receiver.xml
new file mode 100644
index 0000000..13092fa
--- /dev/null
+++ b/data/etc/com.stericsson.hardware.fm.receiver.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is the standard feature indicating that the device includes FM receiver. -->
+<permissions>
+ <feature name="com.stericsson.hardware.fm.receiver" />
+</permissions>
diff --git a/data/etc/com.stericsson.hardware.fm.transmitter.xml b/data/etc/com.stericsson.hardware.fm.transmitter.xml
new file mode 100644
index 0000000..9b51c03
--- /dev/null
+++ b/data/etc/com.stericsson.hardware.fm.transmitter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is the standard feature indicating that the device includes FM transmitter. -->
+<permissions>
+ <feature name="com.stericsson.hardware.fm.transmitter" />
+</permissions>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 83ecdd9..12f62fe 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -106,6 +106,11 @@
<group gid="net_bw_acct" />
</permission>
+ <!-- Permissions to read DRM-protected theme resources. -->
+ <permission name="com.tmobile.permission.ACCESS_DRM_THEME" >
+ <group gid="theme_manager" />
+ </permission>
+
<!-- ================================================================== -->
<!-- ================================================================== -->
<!-- ================================================================== -->
diff --git a/data/sounds/Alarm_Classic.wav b/data/sounds/Alarm_Classic.wav
deleted file mode 100644
index bd41869..0000000
--- a/data/sounds/Alarm_Classic.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/AllAudio.mk b/data/sounds/AllAudio.mk
deleted file mode 100644
index e403205..0000000
--- a/data/sounds/AllAudio.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-$(call inherit-product, frameworks/base/data/sounds/OriginalAudio.mk)
-$(call inherit-product, frameworks/base/data/sounds/AudioPackage2.mk)
-$(call inherit-product, frameworks/base/data/sounds/AudioPackage3.mk)
-$(call inherit-product, frameworks/base/data/sounds/AudioPackage4.mk)
-$(call inherit-product, frameworks/base/data/sounds/AudioPackage5.mk)
-$(call inherit-product, frameworks/base/data/sounds/AudioPackage6.mk)
-$(call inherit-product, frameworks/base/data/sounds/AudioPackage7.mk)
-$(call inherit-product, frameworks/base/data/sounds/AudioPackage7alt.mk)
diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk
deleted file mode 100644
index 1a36cba..0000000
--- a/data/sounds/AudioPackage2.mk
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# Audio Package 2
-#
-# Include this file in a product makefile to include these audio files
-#
-# This is a larger package of sounds than the 1.0 release for devices
-# that have larger internal flash.
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
- $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
- $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
- $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
- $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
- $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
- $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
- $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
- $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
- $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \
- $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
- $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
- $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
- $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
- $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
- $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
- $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
- $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
- $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
- $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
- $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
- $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
- $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
- $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
- $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
- $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
- $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
- $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
-
-ifneq ($(MINIMAL_NEWWAVELABS),true)
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
- $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
- $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \
- $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \
- $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \
- $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:system/media/audio/ringtones/FriendlyGhost.ogg \
- $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:system/media/audio/ringtones/GameOverGuitar.ogg \
- $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \
- $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:system/media/audio/ringtones/InsertCoin.ogg \
- $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \
- $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \
- $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \
- $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \
- $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \
- $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \
- $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:system/media/audio/ringtones/RomancingTheTone.ogg \
- $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:system/media/audio/ringtones/SitarVsSitar.ogg \
- $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:system/media/audio/ringtones/SpringyJalopy.ogg \
- $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \
- $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
- $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \
- $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \
- $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
- $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
- $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
- $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
- $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
- $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
- $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \
- $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg \
- $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
- $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
- $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \
- $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \
- $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \
- $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \
- $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \
- $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \
- $(LOCAL_PATH)/newwavelabs/Savannah.ogg:system/media/audio/ringtones/Savannah.ogg \
- $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \
- $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \
- $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \
- $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \
- $(LOCAL_PATH)/newwavelabs/Revelation.ogg:system/media/audio/ringtones/Revelation.ogg \
- $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \
- $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \
- $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \
- $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \
- $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \
- $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg
-endif
diff --git a/data/sounds/AudioPackage3.mk b/data/sounds/AudioPackage3.mk
deleted file mode 100644
index 146c2e4..0000000
--- a/data/sounds/AudioPackage3.mk
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# Audio Package 3
-#
-# Include this file in a product makefile to include these audio files
-#
-# This is a larger package of sounds than the 1.0 release for devices
-# that have larger internal flash.
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
- $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
- $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
- $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
- $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
- $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
- $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
- $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
- $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
- $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \
- $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
- $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
- $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
- $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
- $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
- $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
- $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
- $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
- $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
- $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
- $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
- $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
- $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
- $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
- $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
- $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
- $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
- $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
-
-ifneq ($(MINIMAL_NEWWAVELABS),true)
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
- $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
- $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \
- $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \
- $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \
- $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \
- $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \
- $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \
- $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \
- $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \
- $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \
- $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \
- $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
- $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \
- $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
- $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
- $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
- $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
- $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
- $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
- $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
- $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
- $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \
- $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \
- $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \
- $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \
- $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \
- $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \
- $(LOCAL_PATH)/newwavelabs/Savannah.ogg:system/media/audio/ringtones/Savannah.ogg \
- $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \
- $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \
- $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \
- $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \
- $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \
- $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \
- $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \
- $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \
- $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \
- $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg \
- $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:system/media/audio/ringtones/HalfwayHome.ogg \
- $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:system/media/audio/ringtones/CrayonRock.ogg \
- $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:system/media/audio/ringtones/DancinFool.ogg \
- $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:system/media/audio/ringtones/BussaMove.ogg \
- $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:system/media/audio/ringtones/DonMessWivIt.ogg \
- $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:system/media/audio/ringtones/SilkyWay.ogg \
- $(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg
-endif
diff --git a/data/sounds/AudioPackage4.mk b/data/sounds/AudioPackage4.mk
deleted file mode 100644
index 712d7aa..0000000
--- a/data/sounds/AudioPackage4.mk
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# Audio Package 4
-#
-# Include this file in a product makefile to include these audio files
-#
-# This is a larger package of sounds than the 1.0 release for devices
-# that have larger internal flash.
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
- $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
- $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
- $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
- $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
- $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
- $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
- $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
- $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
- $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
- $(LOCAL_PATH)/notifications/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \
- $(LOCAL_PATH)/notifications/Doink.ogg:system/media/audio/notifications/Doink.ogg \
- $(LOCAL_PATH)/notifications/Drip.ogg:system/media/audio/notifications/Drip.ogg \
- $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
- $(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \
- $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
- $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
- $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
- $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
- $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
- $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \
- $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
- $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
- $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
- $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
- $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
- $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
- $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \
- $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
- $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
- $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
- $(LOCAL_PATH)/ringtones/FreeFlight.ogg:system/media/audio/ringtones/FreeFlight.ogg \
- $(LOCAL_PATH)/newwavelabs/Backroad.ogg:system/media/audio/ringtones/Backroad.ogg \
- $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
-
-ifneq ($(MINIMAL_NEWWAVELABS),true)
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
- $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
- $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
- $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
- $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
- $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
- $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
- $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
- $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
- $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:system/media/audio/ringtones/BussaMove.ogg \
- $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \
- $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \
- $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \
- $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \
- $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:system/media/audio/ringtones/CrayonRock.ogg \
- $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \
- $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:system/media/audio/ringtones/DancinFool.ogg \
- $(LOCAL_PATH)/newwavelabs/Ding.ogg:system/media/audio/ringtones/Ding.ogg \
- $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:system/media/audio/ringtones/DonMessWivIt.ogg \
- $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \
- $(LOCAL_PATH)/newwavelabs/Enter_the_Nexus.ogg:system/media/audio/ringtones/Enter_the_Nexus.ogg \
- $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \
- $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \
- $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \
- $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \
- $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \
- $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:system/media/audio/ringtones/HalfwayHome.ogg \
- $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \
- $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \
- $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \
- $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \
- $(LOCAL_PATH)/newwavelabs/Nairobi.ogg:system/media/audio/ringtones/Nairobi.ogg \
- $(LOCAL_PATH)/newwavelabs/Nassau.ogg:system/media/audio/ringtones/Nassau.ogg \
- $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \
- $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \
- $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \
- $(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg \
- $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \
- $(LOCAL_PATH)/newwavelabs/Safari.ogg:system/media/audio/ringtones/Safari.ogg \
- $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \
- $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \
- $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:system/media/audio/ringtones/SilkyWay.ogg \
- $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \
- $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \
- $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \
- $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
- $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg
-endif
diff --git a/data/sounds/AudioPackage5.mk b/data/sounds/AudioPackage5.mk
deleted file mode 100755
index 5961f06..0000000
--- a/data/sounds/AudioPackage5.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Audio Package 5 - Crespo/Soju
-#
-# Include this file in a product makefile to include these audio files
-#
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
- $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
- $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
- $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
- $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
- $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
- $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
- $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
- $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
- $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
- $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
- $(LOCAL_PATH)/notifications/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \
- $(LOCAL_PATH)/notifications/Altair.ogg:system/media/audio/notifications/Altair.ogg \
- $(LOCAL_PATH)/notifications/Antares.ogg:system/media/audio/notifications/Antares.ogg \
- $(LOCAL_PATH)/notifications/arcturus.ogg:system/media/audio/notifications/arcturus.ogg \
- $(LOCAL_PATH)/notifications/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
- $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \
- $(LOCAL_PATH)/notifications/Capella.ogg:system/media/audio/notifications/Capella.ogg \
- $(LOCAL_PATH)/notifications/Castor.ogg:system/media/audio/notifications/Castor.ogg \
- $(LOCAL_PATH)/notifications/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
- $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
- $(LOCAL_PATH)/notifications/Electra.ogg:system/media/audio/notifications/Electra.ogg \
- $(LOCAL_PATH)/notifications/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \
- $(LOCAL_PATH)/notifications/Merope.ogg:system/media/audio/notifications/Merope.ogg \
- $(LOCAL_PATH)/notifications/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
- $(LOCAL_PATH)/notifications/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
- $(LOCAL_PATH)/notifications/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
- $(LOCAL_PATH)/notifications/regulus.ogg:system/media/audio/notifications/regulus.ogg \
- $(LOCAL_PATH)/notifications/sirius.ogg:system/media/audio/notifications/sirius.ogg \
- $(LOCAL_PATH)/notifications/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \
- $(LOCAL_PATH)/notifications/vega.ogg:system/media/audio/notifications/vega.ogg \
- $(LOCAL_PATH)/ringtones/ANDROMEDA.ogg:system/media/audio/ringtones/ANDROMEDA.ogg \
- $(LOCAL_PATH)/ringtones/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
- $(LOCAL_PATH)/ringtones/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
- $(LOCAL_PATH)/ringtones/BOOTES.ogg:system/media/audio/ringtones/BOOTES.ogg \
- $(LOCAL_PATH)/ringtones/CANISMAJOR.ogg:system/media/audio/ringtones/CANISMAJOR.ogg \
- $(LOCAL_PATH)/ringtones/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
- $(LOCAL_PATH)/ringtones/CASSIOPEIA.ogg:system/media/audio/ringtones/CASSIOPEIA.ogg \
- $(LOCAL_PATH)/ringtones/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
- $(LOCAL_PATH)/ringtones/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \
- $(LOCAL_PATH)/ringtones/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
- $(LOCAL_PATH)/ringtones/Eridani.ogg:system/media/audio/ringtones/Eridani.ogg \
- $(LOCAL_PATH)/ringtones/hydra.ogg:system/media/audio/ringtones/hydra.ogg \
- $(LOCAL_PATH)/ringtones/Lyra.ogg:system/media/audio/ringtones/Lyra.ogg \
- $(LOCAL_PATH)/ringtones/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
- $(LOCAL_PATH)/ringtones/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
- $(LOCAL_PATH)/ringtones/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
- $(LOCAL_PATH)/ringtones/PERSEUS.ogg:system/media/audio/ringtones/PERSEUS.ogg \
- $(LOCAL_PATH)/ringtones/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
- $(LOCAL_PATH)/ringtones/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
- $(LOCAL_PATH)/ringtones/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
- $(LOCAL_PATH)/ringtones/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
- $(LOCAL_PATH)/ringtones/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
- $(LOCAL_PATH)/ringtones/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \
- $(LOCAL_PATH)/ringtones/URSAMINOR.ogg:system/media/audio/ringtones/URSAMINOR.ogg \
- $(LOCAL_PATH)/ringtones/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg
diff --git a/data/sounds/AudioPackage6.mk b/data/sounds/AudioPackage6.mk
deleted file mode 100755
index d113a29..0000000
--- a/data/sounds/AudioPackage6.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Audio Package 6 - Trygon/Stingray
-#
-# Include this file in a product makefile to include these audio files
-#
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \
- $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
- $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
- $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
- $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
- $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
- $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
- $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \
- $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \
- $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \
- $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \
- $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \
- $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \
- $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \
- $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \
- $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
deleted file mode 100755
index 6ae624e..0000000
--- a/data/sounds/AudioPackage7.mk
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# Audio Package 7 - Tuna
-#
-# Include this file in a product makefile to include these audio files
-#
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \
- $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
- $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
- $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
- $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
- $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
- $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
- $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
- $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
- $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
- $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
- $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
- $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
- $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
- $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
- $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
- $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
- $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
- $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
- $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
- $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
- $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
- $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
- $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
- $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
- $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
- $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \
- $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg
diff --git a/data/sounds/AudioPackage7alt.mk b/data/sounds/AudioPackage7alt.mk
deleted file mode 100755
index 11409f2..0000000
--- a/data/sounds/AudioPackage7alt.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Audio Package 7 - Tuna - Alternate names
-#
-# Include this file in a product makefile to include these audio files
-#
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/alarms/ogg-jp/Argon.ogg:system/media/audio/alarms/Argon.ogg \
- $(LOCAL_PATH)/alarms/ogg-jp/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
- $(LOCAL_PATH)/alarms/ogg-jp/Helium.ogg:system/media/audio/alarms/Helium.ogg \
- $(LOCAL_PATH)/alarms/ogg-jp/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
- $(LOCAL_PATH)/alarms/ogg-jp/Neon.ogg:system/media/audio/alarms/Neon.ogg \
- $(LOCAL_PATH)/alarms/ogg-jp/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
- $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
- $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
- $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
- $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
- $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
- $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
- $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
- $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
- $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
- $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
- $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
- $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
- $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
- $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
- $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
- $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
- $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
- $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
- $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
- $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
- $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
- $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
- $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
- $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \
- $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg
diff --git a/data/sounds/AudioPackageElements.mk b/data/sounds/AudioPackageElements.mk
new file mode 100644
index 0000000..09b3fb8
--- /dev/null
+++ b/data/sounds/AudioPackageElements.mk
@@ -0,0 +1,41 @@
+#
+# Elements Audio Package
+#
+# Include this file in a product makefile to include these audio files
+#
+#
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+# Alarms
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Copernicium.ogg:system/media/audio/alarms/Copernicium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Curium.ogg:system/media/audio/alarms/Curium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg
+
+# Notifications
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg
diff --git a/data/sounds/AudioPackageNewWave.mk b/data/sounds/AudioPackageNewWave.mk
new file mode 100644
index 0000000..eb2debb
--- /dev/null
+++ b/data/sounds/AudioPackageNewWave.mk
@@ -0,0 +1,76 @@
+#
+# New Wave Audio Package
+#
+# Include this file in a product makefile to include these audio files
+#
+#
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+# Ringtones
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
+ $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
+ $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \
+ $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \
+ $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \
+ $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:system/media/audio/ringtones/FriendlyGhost.ogg \
+ $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:system/media/audio/ringtones/GameOverGuitar.ogg \
+ $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \
+ $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:system/media/audio/ringtones/InsertCoin.ogg \
+ $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \
+ $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \
+ $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \
+ $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \
+ $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \
+ $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \
+ $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \
+ $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \
+ $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \
+ $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:system/media/audio/ringtones/RomancingTheTone.ogg \
+ $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:system/media/audio/ringtones/SitarVsSitar.ogg \
+ $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:system/media/audio/ringtones/SpringyJalopy.ogg \
+ $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \
+ $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
+ $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \
+ $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \
+ $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
+ $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
+ $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
+ $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
+ $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
+ $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
+ $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \
+ $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg \
+ $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
+ $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
+ $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \
+ $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \
+ $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \
+ $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \
+ $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \
+ $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \
+ $(LOCAL_PATH)/newwavelabs/Savannah.ogg:system/media/audio/ringtones/Savannah.ogg \
+ $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \
+ $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \
+ $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \
+ $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \
+ $(LOCAL_PATH)/newwavelabs/Revelation.ogg:system/media/audio/ringtones/Revelation.ogg \
+ $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \
+ $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \
+ $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \
+ $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \
+ $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \
+ $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg \
+ $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:system/media/audio/ringtones/HalfwayHome.ogg \
+ $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:system/media/audio/ringtones/CrayonRock.ogg \
+ $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:system/media/audio/ringtones/DancinFool.ogg \
+ $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:system/media/audio/ringtones/BussaMove.ogg \
+ $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:system/media/audio/ringtones/DonMessWivIt.ogg \
+ $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:system/media/audio/ringtones/SilkyWay.ogg \
+ $(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg \
+ $(LOCAL_PATH)/newwavelabs/Ding.ogg:system/media/audio/ringtones/Ding.ogg \
+ $(LOCAL_PATH)/newwavelabs/Enter_the_Nexus.ogg:system/media/audio/ringtones/Enter_the_Nexus.ogg \
+ $(LOCAL_PATH)/newwavelabs/Nairobi.ogg:system/media/audio/ringtones/Nairobi.ogg \
+ $(LOCAL_PATH)/newwavelabs/Nassau.ogg:system/media/audio/ringtones/Nassau.ogg \
+ $(LOCAL_PATH)/newwavelabs/Safari.ogg:system/media/audio/ringtones/Safari.ogg \
diff --git a/data/sounds/AudioPackageStars.mk b/data/sounds/AudioPackageStars.mk
new file mode 100644
index 0000000..b62b6be
--- /dev/null
+++ b/data/sounds/AudioPackageStars.mk
@@ -0,0 +1,93 @@
+#
+# Stars Audio Package
+#
+# Include this file in a product makefile to include these audio files
+#
+#
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+# Effects
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
+ $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
+ $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/ogg/Media_Volume.ogg:system/media/audio/ui/Media_Volume.ogg \
+ $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+ $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+ $(LOCAL_PATH)/effects/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
+ $(LOCAL_PATH)/effects/ogg/VolumeIncremental.ogg:system/media/audio/ui/VolumeIncremental.ogg \
+
+# Notifications
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Antares.ogg:system/media/audio/notifications/Antares.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Castor.ogg:system/media/audio/notifications/Castor.ogg \
+ $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Electra.ogg:system/media/audio/notifications/Electra.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Merope.ogg:system/media/audio/notifications/Merope.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Regulus.ogg:system/media/audio/notifications/Regulus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Sirius.ogg:system/media/audio/notifications/Sirius.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg
+
+# Ringtones
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/ringtones/ogg/Acheron.ogg:system/media/audio/ringtones/Acheron.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Bootes.ogg:system/media/audio/ringtones/Bootes.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Cassiopeia.ogg:system/media/audio/ringtones/Cassiopeia.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Eridani.ogg:system/media/audio/ringtones/Eridani.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Iridium.ogg:system/media/audio/ringtones/Iridium.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Lyra.ogg:system/media/audio/ringtones/Lyra.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Nasqueron.ogg:system/media/audio/ringtones/Nasqueron.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg
diff --git a/data/sounds/NewAudio.mk b/data/sounds/NewAudio.mk
new file mode 100644
index 0000000..cedf570
--- /dev/null
+++ b/data/sounds/NewAudio.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+$(call inherit-product, frameworks/base/data/sounds/AudioPackageElements.mk)
+$(call inherit-product, frameworks/base/data/sounds/AudioPackageStars.mk)
diff --git a/data/sounds/OldAudio.mk b/data/sounds/OldAudio.mk
new file mode 100644
index 0000000..adced91
--- /dev/null
+++ b/data/sounds/OldAudio.mk
@@ -0,0 +1,73 @@
+#
+# Old Audio Files
+#
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+# Alarms
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/alarms/old/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
+ $(LOCAL_PATH)/alarms/old/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
+ $(LOCAL_PATH)/alarms/old/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
+ $(LOCAL_PATH)/alarms/old/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
+ $(LOCAL_PATH)/alarms/old/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
+ $(LOCAL_PATH)/alarms/old/Alarm_Rooster_01.ogg:system/media/audio/alarms/Alarm_Rooster_01.ogg \
+ $(LOCAL_PATH)/alarms/old/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
+
+# Effects
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/effects/old/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/old/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/old/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+ $(LOCAL_PATH)/effects/old/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+ $(LOCAL_PATH)/effects/old/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
+ $(LOCAL_PATH)/effects/old/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+ $(LOCAL_PATH)/effects/old/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
+ $(LOCAL_PATH)/effects/old/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/old/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/old/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+ $(LOCAL_PATH)/effects/old/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/old/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+
+# Notifications
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/notifications/old/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
+ $(LOCAL_PATH)/notifications/old/Bees_Knees.ogg:system/media/audio/notifications/Bees_Knees.ogg \
+ $(LOCAL_PATH)/notifications/old/Cheeper.ogg:system/media/audio/notifications/Cheeper.ogg \
+ $(LOCAL_PATH)/notifications/old/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \
+ $(LOCAL_PATH)/notifications/old/Doink.ogg:system/media/audio/notifications/Doink.ogg \
+ $(LOCAL_PATH)/notifications/old/Drip.ogg:system/media/audio/notifications/Drip.ogg \
+ $(LOCAL_PATH)/notifications/old/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
+ $(LOCAL_PATH)/notifications/old/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
+ $(LOCAL_PATH)/notifications/old/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
+ $(LOCAL_PATH)/notifications/old/F1_NewVoicemail.ogg:system/media/audio/notifications/F1_NewVoicemail \
+ $(LOCAL_PATH)/notifications/old/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
+ $(LOCAL_PATH)/notifications/old/IM_Me.ogg:system/media/audio/notifications/IM_Me.ogg \
+ $(LOCAL_PATH)/notifications/old/Moonbeam.ogg:system/media/audio/notifications/Moonbeam.ogg \
+ $(LOCAL_PATH)/notifications/old/Pixiedust.ogg:system/media/audio/notifications/Pixiedust.ogg \
+ $(LOCAL_PATH)/notifications/old/Pizzicato.ogg:system/media/audio/notifications/Pizzicato.ogg \
+ $(LOCAL_PATH)/notifications/old/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \
+ $(LOCAL_PATH)/notifications/old/ShortCircuit.ogg:system/media/audio/notifications/ShortCircuit.ogg \
+ $(LOCAL_PATH)/notifications/old/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \
+ $(LOCAL_PATH)/notifications/old/Star_Struck.ogg:system/media/audio/notifications/Star_Struck.ogg \
+ $(LOCAL_PATH)/notifications/old/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
+ $(LOCAL_PATH)/notifications/old/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
+ $(LOCAL_PATH)/notifications/old/Tweeters.ogg:system/media/audio/notifications/Tweeters.ogg \
+
+# Ringtones
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/ringtones/old/Ring_Classic_01.ogg:system/media/audio/ringtones/Ring_Classic_01.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Classic_03.ogg:system/media/audio/ringtones/Ring_Classic_03.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Classic_04.ogg:system/media/audio/ringtones/Ring_Classic_04.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Classic_05.ogg:system/media/audio/ringtones/Ring_Classic_05.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Digital_01.ogg:system/media/audio/ringtones/Ring_Digital_01.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Digital_03.ogg:system/media/audio/ringtones/Ring_Digital_03.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Digital_04.ogg:system/media/audio/ringtones/Ring_Digital_04.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Digital_05.ogg:system/media/audio/ringtones/Ring_Digital_05.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Synth_01.ogg:system/media/audio/ringtones/Ring_Synth_01.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Synth_03.ogg:system/media/audio/ringtones/Ring_Synth_03.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
+ $(LOCAL_PATH)/ringtones/old/Ring_Synth_05.ogg:system/media/audio/ringtones/Ring_Synth_05.ogg \
diff --git a/data/sounds/OriginalAudio.mk b/data/sounds/OriginalAudio.mk
deleted file mode 100644
index e1ca24b..0000000
--- a/data/sounds/OriginalAudio.mk
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Original audio package that shipped on G1
-#
-# This file is included from core.mk so that all devices will have these sounds
-#
-# TODO: Clean up for future releases
-#
-
-LOCAL_PATH:= frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
- $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
- $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
- $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
- $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
- $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
- $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
- $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
- $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
- $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \
- $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
- $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
- $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
- $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
- $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
- $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
- $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
- $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
- $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
- $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
- $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
- $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
- $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
- $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
- $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
- $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
-
-ifneq ($(MINIMAL_NEWWAVELABS),true)
-PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
- $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
- $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \
- $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \
- $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \
- $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:system/media/audio/ringtones/FriendlyGhost.ogg \
- $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:system/media/audio/ringtones/GameOverGuitar.ogg \
- $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \
- $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:system/media/audio/ringtones/InsertCoin.ogg \
- $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \
- $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \
- $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \
- $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \
- $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \
- $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \
- $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \
- $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:system/media/audio/ringtones/RomancingTheTone.ogg \
- $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:system/media/audio/ringtones/SitarVsSitar.ogg \
- $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:system/media/audio/ringtones/SpringyJalopy.ogg \
- $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \
- $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \
- $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \
- $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \
- $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \
- $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \
- $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \
- $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \
- $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \
- $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \
- $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \
- $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg
-endif
diff --git a/data/sounds/alarms/Cesium.ogg b/data/sounds/alarms/Cesium.ogg
deleted file mode 100644
index a8c379a..0000000
--- a/data/sounds/alarms/Cesium.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg-jp/Argon.ogg b/data/sounds/alarms/ogg-jp/Argon.ogg
deleted file mode 100755
index 2ff6600..0000000
--- a/data/sounds/alarms/ogg-jp/Argon.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg-jp/Carbon.ogg b/data/sounds/alarms/ogg-jp/Carbon.ogg
deleted file mode 100755
index c994f28..0000000
--- a/data/sounds/alarms/ogg-jp/Carbon.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg-jp/Helium.ogg b/data/sounds/alarms/ogg-jp/Helium.ogg
deleted file mode 100755
index 94f13ce..0000000
--- a/data/sounds/alarms/ogg-jp/Helium.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg-jp/Krypton.ogg b/data/sounds/alarms/ogg-jp/Krypton.ogg
deleted file mode 100755
index 48f956b..0000000
--- a/data/sounds/alarms/ogg-jp/Krypton.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg-jp/Neon.ogg b/data/sounds/alarms/ogg-jp/Neon.ogg
deleted file mode 100755
index 3089a27..0000000
--- a/data/sounds/alarms/ogg-jp/Neon.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg-jp/Oxygen.ogg b/data/sounds/alarms/ogg-jp/Oxygen.ogg
deleted file mode 100755
index 4dc8ade..0000000
--- a/data/sounds/alarms/ogg-jp/Oxygen.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg/Analysis.ogg b/data/sounds/alarms/ogg/Analysis.ogg
deleted file mode 100644
index cef9bd8..0000000
--- a/data/sounds/alarms/ogg/Analysis.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg/Departure.ogg b/data/sounds/alarms/ogg/Departure.ogg
deleted file mode 100644
index fe83899..0000000
--- a/data/sounds/alarms/ogg/Departure.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg/FireDrill.ogg b/data/sounds/alarms/ogg/FireDrill.ogg
deleted file mode 100644
index 038353c..0000000
--- a/data/sounds/alarms/ogg/FireDrill.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/ogg/Timing.ogg b/data/sounds/alarms/ogg/Timing.ogg
deleted file mode 100644
index 45a213b..0000000
--- a/data/sounds/alarms/ogg/Timing.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/Alarm_Beep_01.ogg b/data/sounds/alarms/old/Alarm_Beep_01.ogg
index b7de5af..b7de5af 100644
--- a/data/sounds/Alarm_Beep_01.ogg
+++ b/data/sounds/alarms/old/Alarm_Beep_01.ogg
Binary files differ
diff --git a/data/sounds/Alarm_Beep_02.ogg b/data/sounds/alarms/old/Alarm_Beep_02.ogg
index 43ea34e..43ea34e 100644
--- a/data/sounds/Alarm_Beep_02.ogg
+++ b/data/sounds/alarms/old/Alarm_Beep_02.ogg
Binary files differ
diff --git a/data/sounds/Alarm_Beep_03.ogg b/data/sounds/alarms/old/Alarm_Beep_03.ogg
index 9d80037..9d80037 100644
--- a/data/sounds/Alarm_Beep_03.ogg
+++ b/data/sounds/alarms/old/Alarm_Beep_03.ogg
Binary files differ
diff --git a/data/sounds/Alarm_Buzzer.ogg b/data/sounds/alarms/old/Alarm_Buzzer.ogg
index 4234f37..4234f37 100644
--- a/data/sounds/Alarm_Buzzer.ogg
+++ b/data/sounds/alarms/old/Alarm_Buzzer.ogg
Binary files differ
diff --git a/data/sounds/Alarm_Classic.ogg b/data/sounds/alarms/old/Alarm_Classic.ogg
index 695434f..695434f 100644
--- a/data/sounds/Alarm_Classic.ogg
+++ b/data/sounds/alarms/old/Alarm_Classic.ogg
Binary files differ
diff --git a/data/sounds/Alarm_Rooster_01.ogg b/data/sounds/alarms/old/Alarm_Rooster_01.ogg
index 36b57b7..36b57b7 100644
--- a/data/sounds/Alarm_Rooster_01.ogg
+++ b/data/sounds/alarms/old/Alarm_Rooster_01.ogg
Binary files differ
diff --git a/data/sounds/Alarm_Rooster_02.ogg b/data/sounds/alarms/old/Alarm_Rooster_02.ogg
index d20bd1d..d20bd1d 100644
--- a/data/sounds/Alarm_Rooster_02.ogg
+++ b/data/sounds/alarms/old/Alarm_Rooster_02.ogg
Binary files differ
diff --git a/data/sounds/alarms/wav/Barium.wav b/data/sounds/alarms/wav/Barium.wav
deleted file mode 100644
index 2f4c894..0000000
--- a/data/sounds/alarms/wav/Barium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Cesium.wav b/data/sounds/alarms/wav/Cesium.wav
deleted file mode 100644
index bd41869..0000000
--- a/data/sounds/alarms/wav/Cesium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Copernicium.wav b/data/sounds/alarms/wav/Copernicium.wav
deleted file mode 100644
index 935ea75..0000000
--- a/data/sounds/alarms/wav/Copernicium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Curium.wav b/data/sounds/alarms/wav/Curium.wav
deleted file mode 100644
index a9942d3..0000000
--- a/data/sounds/alarms/wav/Curium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Fermium.wav b/data/sounds/alarms/wav/Fermium.wav
deleted file mode 100644
index 56e57fc..0000000
--- a/data/sounds/alarms/wav/Fermium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Hassium.wav b/data/sounds/alarms/wav/Hassium.wav
deleted file mode 100644
index 17710b0..0000000
--- a/data/sounds/alarms/wav/Hassium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Neptunium.wav b/data/sounds/alarms/wav/Neptunium.wav
deleted file mode 100644
index 2b855e1..0000000
--- a/data/sounds/alarms/wav/Neptunium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Nobelium.wav b/data/sounds/alarms/wav/Nobelium.wav
deleted file mode 100644
index 0e9101a..0000000
--- a/data/sounds/alarms/wav/Nobelium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Plutonium.wav b/data/sounds/alarms/wav/Plutonium.wav
deleted file mode 100644
index 9095e30..0000000
--- a/data/sounds/alarms/wav/Plutonium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/alarms/wav/Scandium.wav b/data/sounds/alarms/wav/Scandium.wav
deleted file mode 100644
index a30d329..0000000
--- a/data/sounds/alarms/wav/Scandium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/Dock.aif b/data/sounds/effects/Dock.aif
deleted file mode 100644
index 9f408cc..0000000
--- a/data/sounds/effects/Dock.aif
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/KeypressDelete.wav b/data/sounds/effects/KeypressDelete.wav
deleted file mode 100644
index 0a2f3cc..0000000
--- a/data/sounds/effects/KeypressDelete.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/KeypressReturn.wav b/data/sounds/effects/KeypressReturn.wav
deleted file mode 100644
index 59ff13a..0000000
--- a/data/sounds/effects/KeypressReturn.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/KeypressSpacebar.wav b/data/sounds/effects/KeypressSpacebar.wav
deleted file mode 100644
index 1f819c9..0000000
--- a/data/sounds/effects/KeypressSpacebar.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/KeypressStandard.wav b/data/sounds/effects/KeypressStandard.wav
deleted file mode 100644
index 56a7911..0000000
--- a/data/sounds/effects/KeypressStandard.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/Lock.wav b/data/sounds/effects/Lock.wav
deleted file mode 100644
index b807636..0000000
--- a/data/sounds/effects/Lock.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/LowBattery.aif b/data/sounds/effects/LowBattery.aif
deleted file mode 100644
index 9216583..0000000
--- a/data/sounds/effects/LowBattery.aif
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/Undock.aif b/data/sounds/effects/Undock.aif
deleted file mode 100644
index fe9d0b0..0000000
--- a/data/sounds/effects/Undock.aif
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/Unlock.wav b/data/sounds/effects/Unlock.wav
deleted file mode 100644
index e1d475e..0000000
--- a/data/sounds/effects/Unlock.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/VideoRecord.wav b/data/sounds/effects/VideoRecord.wav
deleted file mode 100644
index 5809d93..0000000
--- a/data/sounds/effects/VideoRecord.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/camera_click.wav b/data/sounds/effects/camera_click.wav
deleted file mode 100644
index 7043bc7..0000000
--- a/data/sounds/effects/camera_click.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressDelete.ogg b/data/sounds/effects/ogg/KeypressDelete.ogg
index 38c3244..f2851f7 100755..100644
--- a/data/sounds/effects/ogg/KeypressDelete.ogg
+++ b/data/sounds/effects/ogg/KeypressDelete.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressDelete_120.ogg b/data/sounds/effects/ogg/KeypressDelete_120.ogg
deleted file mode 100644
index f2851f7..0000000
--- a/data/sounds/effects/ogg/KeypressDelete_120.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressDelete_14.ogg b/data/sounds/effects/ogg/KeypressDelete_14.ogg
deleted file mode 100644
index 0baea25..0000000
--- a/data/sounds/effects/ogg/KeypressDelete_14.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressDelete_49.ogg b/data/sounds/effects/ogg/KeypressDelete_49.ogg
deleted file mode 100644
index f5e9deb..0000000
--- a/data/sounds/effects/ogg/KeypressDelete_49.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressReturn.ogg b/data/sounds/effects/ogg/KeypressReturn.ogg
index 1bd5b73..48a26b4 100755..100644
--- a/data/sounds/effects/ogg/KeypressReturn.ogg
+++ b/data/sounds/effects/ogg/KeypressReturn.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressReturn_120.ogg b/data/sounds/effects/ogg/KeypressReturn_120.ogg
deleted file mode 100644
index 48a26b4..0000000
--- a/data/sounds/effects/ogg/KeypressReturn_120.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressReturn_14.ogg b/data/sounds/effects/ogg/KeypressReturn_14.ogg
deleted file mode 100644
index 86a5a0e..0000000
--- a/data/sounds/effects/ogg/KeypressReturn_14.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressReturn_49.ogg b/data/sounds/effects/ogg/KeypressReturn_49.ogg
deleted file mode 100644
index b0ddee5..0000000
--- a/data/sounds/effects/ogg/KeypressReturn_49.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressSpacebar.ogg b/data/sounds/effects/ogg/KeypressSpacebar.ogg
index 3a83594..9620927 100755..100644
--- a/data/sounds/effects/ogg/KeypressSpacebar.ogg
+++ b/data/sounds/effects/ogg/KeypressSpacebar.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressSpacebar_120.ogg b/data/sounds/effects/ogg/KeypressSpacebar_120.ogg
deleted file mode 100644
index 9620927..0000000
--- a/data/sounds/effects/ogg/KeypressSpacebar_120.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressSpacebar_14.ogg b/data/sounds/effects/ogg/KeypressSpacebar_14.ogg
deleted file mode 100644
index 058534a..0000000
--- a/data/sounds/effects/ogg/KeypressSpacebar_14.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressSpacebar_49.ogg b/data/sounds/effects/ogg/KeypressSpacebar_49.ogg
deleted file mode 100644
index 3866e0e..0000000
--- a/data/sounds/effects/ogg/KeypressSpacebar_49.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressStandard.ogg b/data/sounds/effects/ogg/KeypressStandard.ogg
index 4b8d128..e4d916a 100755..100644
--- a/data/sounds/effects/ogg/KeypressStandard.ogg
+++ b/data/sounds/effects/ogg/KeypressStandard.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressStandard_120.ogg b/data/sounds/effects/ogg/KeypressStandard_120.ogg
deleted file mode 100644
index e4d916a..0000000
--- a/data/sounds/effects/ogg/KeypressStandard_120.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressStandard_14.ogg b/data/sounds/effects/ogg/KeypressStandard_14.ogg
deleted file mode 100644
index 317c8f3..0000000
--- a/data/sounds/effects/ogg/KeypressStandard_14.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressStandard_49.ogg b/data/sounds/effects/ogg/KeypressStandard_49.ogg
deleted file mode 100644
index 893bb52..0000000
--- a/data/sounds/effects/ogg/KeypressStandard_49.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/Dock.ogg b/data/sounds/effects/old/Dock.ogg
index 1462813d..1462813d 100644
--- a/data/sounds/effects/Dock.ogg
+++ b/data/sounds/effects/old/Dock.ogg
Binary files differ
diff --git a/data/sounds/effects/Effect_Tick.ogg b/data/sounds/effects/old/Effect_Tick.ogg
index c899a7d..c899a7d 100644
--- a/data/sounds/effects/Effect_Tick.ogg
+++ b/data/sounds/effects/old/Effect_Tick.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressDelete.ogg b/data/sounds/effects/old/KeypressDelete.ogg
index 738f6ae..738f6ae 100644
--- a/data/sounds/effects/KeypressDelete.ogg
+++ b/data/sounds/effects/old/KeypressDelete.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressReturn.ogg b/data/sounds/effects/old/KeypressReturn.ogg
index 6c807b0..6c807b0 100644
--- a/data/sounds/effects/KeypressReturn.ogg
+++ b/data/sounds/effects/old/KeypressReturn.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressSpacebar.ogg b/data/sounds/effects/old/KeypressSpacebar.ogg
index b59c8ce..b59c8ce 100644
--- a/data/sounds/effects/KeypressSpacebar.ogg
+++ b/data/sounds/effects/old/KeypressSpacebar.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressStandard.ogg b/data/sounds/effects/old/KeypressStandard.ogg
index a465cf8..a465cf8 100644
--- a/data/sounds/effects/KeypressStandard.ogg
+++ b/data/sounds/effects/old/KeypressStandard.ogg
Binary files differ
diff --git a/data/sounds/effects/Lock.ogg b/data/sounds/effects/old/Lock.ogg
index e7928e4..e7928e4 100644
--- a/data/sounds/effects/Lock.ogg
+++ b/data/sounds/effects/old/Lock.ogg
Binary files differ
diff --git a/data/sounds/effects/LowBattery.ogg b/data/sounds/effects/old/LowBattery.ogg
index 68eb2c3..68eb2c3 100644
--- a/data/sounds/effects/LowBattery.ogg
+++ b/data/sounds/effects/old/LowBattery.ogg
Binary files differ
diff --git a/data/sounds/effects/Undock.ogg b/data/sounds/effects/old/Undock.ogg
index 0053066..0053066 100644
--- a/data/sounds/effects/Undock.ogg
+++ b/data/sounds/effects/old/Undock.ogg
Binary files differ
diff --git a/data/sounds/effects/Unlock.ogg b/data/sounds/effects/old/Unlock.ogg
index cca9594..cca9594 100644
--- a/data/sounds/effects/Unlock.ogg
+++ b/data/sounds/effects/old/Unlock.ogg
Binary files differ
diff --git a/data/sounds/effects/VideoRecord.ogg b/data/sounds/effects/old/VideoRecord.ogg
index 1450522..1450522 100644
--- a/data/sounds/effects/VideoRecord.ogg
+++ b/data/sounds/effects/old/VideoRecord.ogg
Binary files differ
diff --git a/data/sounds/effects/camera_click.ogg b/data/sounds/effects/old/camera_click.ogg
index 52512ac..52512ac 100644
--- a/data/sounds/effects/camera_click.ogg
+++ b/data/sounds/effects/old/camera_click.ogg
Binary files differ
diff --git a/data/sounds/effects/wav/CameraClick.wav b/data/sounds/effects/wav/CameraClick.wav
deleted file mode 100644
index 1077f41..0000000
--- a/data/sounds/effects/wav/CameraClick.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/CameraFocus.wav b/data/sounds/effects/wav/CameraFocus.wav
deleted file mode 100644
index cbe6b37..0000000
--- a/data/sounds/effects/wav/CameraFocus.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/Dock.wav b/data/sounds/effects/wav/Dock.wav
deleted file mode 100644
index 864a7dd..0000000
--- a/data/sounds/effects/wav/Dock.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/Effect_Tick.wav b/data/sounds/effects/wav/Effect_Tick.wav
deleted file mode 100644
index 6a56ad7..0000000
--- a/data/sounds/effects/wav/Effect_Tick.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressDelete.wav b/data/sounds/effects/wav/KeypressDelete.wav
deleted file mode 100644
index e4a4af7..0000000
--- a/data/sounds/effects/wav/KeypressDelete.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressDelete_14.wav b/data/sounds/effects/wav/KeypressDelete_14.wav
deleted file mode 100644
index 1d3498e..0000000
--- a/data/sounds/effects/wav/KeypressDelete_14.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressDelete_49.wav b/data/sounds/effects/wav/KeypressDelete_49.wav
deleted file mode 100644
index 2404759..0000000
--- a/data/sounds/effects/wav/KeypressDelete_49.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressReturn.wav b/data/sounds/effects/wav/KeypressReturn.wav
deleted file mode 100644
index 8b666ce..0000000
--- a/data/sounds/effects/wav/KeypressReturn.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressReturn_14.wav b/data/sounds/effects/wav/KeypressReturn_14.wav
deleted file mode 100644
index 01573ff..0000000
--- a/data/sounds/effects/wav/KeypressReturn_14.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressReturn_49.wav b/data/sounds/effects/wav/KeypressReturn_49.wav
deleted file mode 100644
index 6bf216f..0000000
--- a/data/sounds/effects/wav/KeypressReturn_49.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressSpacebar.wav b/data/sounds/effects/wav/KeypressSpacebar.wav
deleted file mode 100644
index 84743a0..0000000
--- a/data/sounds/effects/wav/KeypressSpacebar.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressSpacebar_14.wav b/data/sounds/effects/wav/KeypressSpacebar_14.wav
deleted file mode 100644
index 77269a6..0000000
--- a/data/sounds/effects/wav/KeypressSpacebar_14.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressSpacebar_49.wav b/data/sounds/effects/wav/KeypressSpacebar_49.wav
deleted file mode 100644
index 8504a25..0000000
--- a/data/sounds/effects/wav/KeypressSpacebar_49.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressStandard.wav b/data/sounds/effects/wav/KeypressStandard.wav
deleted file mode 100644
index 42dcef5a08..0000000
--- a/data/sounds/effects/wav/KeypressStandard.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressStandard_14.wav b/data/sounds/effects/wav/KeypressStandard_14.wav
deleted file mode 100644
index 93389ac..0000000
--- a/data/sounds/effects/wav/KeypressStandard_14.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressStandard_49.wav b/data/sounds/effects/wav/KeypressStandard_49.wav
deleted file mode 100644
index 9a660a1..0000000
--- a/data/sounds/effects/wav/KeypressStandard_49.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/Lock.wav b/data/sounds/effects/wav/Lock.wav
deleted file mode 100644
index b807636..0000000
--- a/data/sounds/effects/wav/Lock.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/LowBattery.wav b/data/sounds/effects/wav/LowBattery.wav
deleted file mode 100644
index 876a564..0000000
--- a/data/sounds/effects/wav/LowBattery.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/Media_Volume.wav b/data/sounds/effects/wav/Media_Volume.wav
deleted file mode 100644
index 54eb638..0000000
--- a/data/sounds/effects/wav/Media_Volume.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/NFCFailure.wav b/data/sounds/effects/wav/NFCFailure.wav
deleted file mode 100644
index 8715f87..0000000
--- a/data/sounds/effects/wav/NFCFailure.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/NFCInitiated.wav b/data/sounds/effects/wav/NFCInitiated.wav
deleted file mode 100644
index 2f20869..0000000
--- a/data/sounds/effects/wav/NFCInitiated.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/NFCSuccess.wav b/data/sounds/effects/wav/NFCSuccess.wav
deleted file mode 100644
index 39e5da7..0000000
--- a/data/sounds/effects/wav/NFCSuccess.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/Undock.wav b/data/sounds/effects/wav/Undock.wav
deleted file mode 100644
index 3696a24..0000000
--- a/data/sounds/effects/wav/Undock.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/Unlock.wav b/data/sounds/effects/wav/Unlock.wav
deleted file mode 100644
index e1d475e..0000000
--- a/data/sounds/effects/wav/Unlock.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/VideoRecord.wav b/data/sounds/effects/wav/VideoRecord.wav
deleted file mode 100644
index b2ca16a..0000000
--- a/data/sounds/effects/wav/VideoRecord.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/VideoStop.wav b/data/sounds/effects/wav/VideoStop.wav
deleted file mode 100644
index 8ff2f6d..0000000
--- a/data/sounds/effects/wav/VideoStop.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/VideoTransmitBegin.wav b/data/sounds/effects/wav/VideoTransmitBegin.wav
deleted file mode 100644
index 0ed14de..0000000
--- a/data/sounds/effects/wav/VideoTransmitBegin.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/VideoTransmitEnd.wav b/data/sounds/effects/wav/VideoTransmitEnd.wav
deleted file mode 100644
index 3c8523e..0000000
--- a/data/sounds/effects/wav/VideoTransmitEnd.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/effects/wav/VolumeIncremental.wav b/data/sounds/effects/wav/VolumeIncremental.wav
deleted file mode 100644
index 0a64981..0000000
--- a/data/sounds/effects/wav/VolumeIncremental.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Altair.ogg b/data/sounds/notifications/Altair.ogg
deleted file mode 100644
index 660c800..0000000
--- a/data/sounds/notifications/Altair.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Antares.ogg b/data/sounds/notifications/Antares.ogg
deleted file mode 100644
index f4f94d7..0000000
--- a/data/sounds/notifications/Antares.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Betelgeuse.ogg b/data/sounds/notifications/Betelgeuse.ogg
deleted file mode 100644
index 7145a16..0000000
--- a/data/sounds/notifications/Betelgeuse.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Capella.ogg b/data/sounds/notifications/Capella.ogg
deleted file mode 100644
index ae4f3c5..0000000
--- a/data/sounds/notifications/Capella.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/CetiAlpha.ogg b/data/sounds/notifications/CetiAlpha.ogg
deleted file mode 100644
index cd09526..0000000
--- a/data/sounds/notifications/CetiAlpha.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/CetiAlpha.wav b/data/sounds/notifications/CetiAlpha.wav
deleted file mode 100644
index d209645..0000000
--- a/data/sounds/notifications/CetiAlpha.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Cricket.wav b/data/sounds/notifications/Cricket.wav
deleted file mode 100644
index 0a1d1db..0000000
--- a/data/sounds/notifications/Cricket.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Deneb.ogg b/data/sounds/notifications/Deneb.ogg
deleted file mode 100644
index 3b17e28..0000000
--- a/data/sounds/notifications/Deneb.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Doink.wav b/data/sounds/notifications/Doink.wav
deleted file mode 100644
index b0d37c4..0000000
--- a/data/sounds/notifications/Doink.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Drip.wav b/data/sounds/notifications/Drip.wav
deleted file mode 100644
index eeb889e..0000000
--- a/data/sounds/notifications/Drip.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Plastic_Pipe.wav b/data/sounds/notifications/Plastic_Pipe.wav
deleted file mode 100644
index 088e373..0000000
--- a/data/sounds/notifications/Plastic_Pipe.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Polaris.ogg b/data/sounds/notifications/Polaris.ogg
deleted file mode 100644
index d5b991f..0000000
--- a/data/sounds/notifications/Polaris.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Pollux.ogg b/data/sounds/notifications/Pollux.ogg
deleted file mode 100644
index d37c75c..0000000
--- a/data/sounds/notifications/Pollux.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Procyon.ogg b/data/sounds/notifications/Procyon.ogg
deleted file mode 100644
index 93d1557..0000000
--- a/data/sounds/notifications/Procyon.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/SpaceSeed.wav b/data/sounds/notifications/SpaceSeed.wav
deleted file mode 100644
index d209645..0000000
--- a/data/sounds/notifications/SpaceSeed.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/aidos.ogg b/data/sounds/notifications/aidos.ogg
deleted file mode 100755
index d2aec75..0000000
--- a/data/sounds/notifications/aidos.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/arcturus.ogg b/data/sounds/notifications/arcturus.ogg
deleted file mode 100644
index 9d73103..0000000
--- a/data/sounds/notifications/arcturus.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/circios.ogg b/data/sounds/notifications/circios.ogg
deleted file mode 100755
index 68a1871..0000000
--- a/data/sounds/notifications/circios.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/horkos.ogg b/data/sounds/notifications/horkos.ogg
deleted file mode 100755
index 171b3cb..0000000
--- a/data/sounds/notifications/horkos.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/hypnos1.ogg b/data/sounds/notifications/hypnos1.ogg
deleted file mode 100755
index 4a7fc26..0000000
--- a/data/sounds/notifications/hypnos1.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/kratos1.ogg b/data/sounds/notifications/kratos1.ogg
deleted file mode 100755
index 3e1fe64..0000000
--- a/data/sounds/notifications/kratos1.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/kratos2.ogg b/data/sounds/notifications/kratos2.ogg
deleted file mode 100755
index 93d3149e..0000000
--- a/data/sounds/notifications/kratos2.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/moonbeam.wav b/data/sounds/notifications/moonbeam.wav
deleted file mode 100644
index 732ae2c..0000000
--- a/data/sounds/notifications/moonbeam.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/nomos1.ogg b/data/sounds/notifications/nomos1.ogg
deleted file mode 100755
index 5eb719a..0000000
--- a/data/sounds/notifications/nomos1.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/nomos2.ogg b/data/sounds/notifications/nomos2.ogg
deleted file mode 100755
index 544cb4c..0000000
--- a/data/sounds/notifications/nomos2.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/ogg/Acrux.ogg b/data/sounds/notifications/ogg/Acrux.ogg
deleted file mode 100644
index 74ad149..0000000
--- a/data/sounds/notifications/ogg/Acrux.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Aldebaran.ogg b/data/sounds/notifications/ogg/Aldebaran.ogg
index fe30137..fe30137 100644
--- a/data/sounds/notifications/Aldebaran.ogg
+++ b/data/sounds/notifications/ogg/Aldebaran.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Bellatrix.ogg b/data/sounds/notifications/ogg/Bellatrix.ogg
deleted file mode 100644
index 37a1bdc..0000000
--- a/data/sounds/notifications/ogg/Bellatrix.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/Canopus.ogg b/data/sounds/notifications/ogg/Canopus.ogg
index 0d55925..0d55925 100644
--- a/data/sounds/notifications/Canopus.ogg
+++ b/data/sounds/notifications/ogg/Canopus.ogg
Binary files differ
diff --git a/data/sounds/notifications/Castor.ogg b/data/sounds/notifications/ogg/Castor.ogg
index 92de8e7..92de8e7 100644
--- a/data/sounds/notifications/Castor.ogg
+++ b/data/sounds/notifications/ogg/Castor.ogg
Binary files differ
diff --git a/data/sounds/notifications/Electra.ogg b/data/sounds/notifications/ogg/Electra.ogg
index 9335d8d..9335d8d 100644
--- a/data/sounds/notifications/Electra.ogg
+++ b/data/sounds/notifications/ogg/Electra.ogg
Binary files differ
diff --git a/data/sounds/notifications/Fomalhaut.ogg b/data/sounds/notifications/ogg/Fomalhaut.ogg
index 9448c18..9448c18 100644
--- a/data/sounds/notifications/Fomalhaut.ogg
+++ b/data/sounds/notifications/ogg/Fomalhaut.ogg
Binary files differ
diff --git a/data/sounds/notifications/Merope.ogg b/data/sounds/notifications/ogg/Merope.ogg
index fb18c73..fb18c73 100644
--- a/data/sounds/notifications/Merope.ogg
+++ b/data/sounds/notifications/ogg/Merope.ogg
Binary files differ
diff --git a/data/sounds/notifications/regulus.ogg b/data/sounds/notifications/ogg/Regulus.ogg
index 4f28d9e..4f28d9e 100644
--- a/data/sounds/notifications/regulus.ogg
+++ b/data/sounds/notifications/ogg/Regulus.ogg
Binary files differ
diff --git a/data/sounds/notifications/sirius.ogg b/data/sounds/notifications/ogg/Sirius.ogg
index 78c9991..78c9991 100644
--- a/data/sounds/notifications/sirius.ogg
+++ b/data/sounds/notifications/ogg/Sirius.ogg
Binary files differ
diff --git a/data/sounds/notifications/Sirrah.ogg b/data/sounds/notifications/ogg/Sirrah.ogg
index ee79e49..ee79e49 100644
--- a/data/sounds/notifications/Sirrah.ogg
+++ b/data/sounds/notifications/ogg/Sirrah.ogg
Binary files differ
diff --git a/data/sounds/notifications/Beat_Box_Android.ogg b/data/sounds/notifications/old/Beat_Box_Android.ogg
index c5d5747..c5d5747 100644
--- a/data/sounds/notifications/Beat_Box_Android.ogg
+++ b/data/sounds/notifications/old/Beat_Box_Android.ogg
Binary files differ
diff --git a/data/sounds/notifications/Bees_Knees.ogg b/data/sounds/notifications/old/Bees_Knees.ogg
index 1a3cd69..1a3cd69 100644
--- a/data/sounds/notifications/Bees_Knees.ogg
+++ b/data/sounds/notifications/old/Bees_Knees.ogg
Binary files differ
diff --git a/data/sounds/notifications/Cheeper.ogg b/data/sounds/notifications/old/Cheeper.ogg
index 5c59013..5c59013 100644
--- a/data/sounds/notifications/Cheeper.ogg
+++ b/data/sounds/notifications/old/Cheeper.ogg
Binary files differ
diff --git a/data/sounds/notifications/Cricket.ogg b/data/sounds/notifications/old/Cricket.ogg
index 47b3868..47b3868 100644
--- a/data/sounds/notifications/Cricket.ogg
+++ b/data/sounds/notifications/old/Cricket.ogg
Binary files differ
diff --git a/data/sounds/notifications/Doink.ogg b/data/sounds/notifications/old/Doink.ogg
index b8b7181..b8b7181 100644
--- a/data/sounds/notifications/Doink.ogg
+++ b/data/sounds/notifications/old/Doink.ogg
Binary files differ
diff --git a/data/sounds/notifications/Drip.ogg b/data/sounds/notifications/old/Drip.ogg
index 2981758..2981758 100644
--- a/data/sounds/notifications/Drip.ogg
+++ b/data/sounds/notifications/old/Drip.ogg
Binary files differ
diff --git a/data/sounds/F1_MissedCall.ogg b/data/sounds/notifications/old/F1_MissedCall.ogg
index 396d78f..396d78f 100644
--- a/data/sounds/F1_MissedCall.ogg
+++ b/data/sounds/notifications/old/F1_MissedCall.ogg
Binary files differ
diff --git a/data/sounds/F1_NewVoicemail.ogg b/data/sounds/notifications/old/F1_NewVoicemail.ogg
index c56f68b..c56f68b 100644
--- a/data/sounds/F1_NewVoicemail.ogg
+++ b/data/sounds/notifications/old/F1_NewVoicemail.ogg
Binary files differ
diff --git a/data/sounds/F1_New_MMS.ogg b/data/sounds/notifications/old/F1_New_MMS.ogg
index d3cbdfc..d3cbdfc 100644
--- a/data/sounds/F1_New_MMS.ogg
+++ b/data/sounds/notifications/old/F1_New_MMS.ogg
Binary files differ
diff --git a/data/sounds/F1_New_SMS.ogg b/data/sounds/notifications/old/F1_New_SMS.ogg
index 1c6851d..1c6851d 100644
--- a/data/sounds/F1_New_SMS.ogg
+++ b/data/sounds/notifications/old/F1_New_SMS.ogg
Binary files differ
diff --git a/data/sounds/notifications/Heaven.ogg b/data/sounds/notifications/old/Heaven.ogg
index 368c32d..368c32d 100644
--- a/data/sounds/notifications/Heaven.ogg
+++ b/data/sounds/notifications/old/Heaven.ogg
Binary files differ
diff --git a/data/sounds/notifications/IM_Me.ogg b/data/sounds/notifications/old/IM_Me.ogg
index 2d65ec2..2d65ec2 100644
--- a/data/sounds/notifications/IM_Me.ogg
+++ b/data/sounds/notifications/old/IM_Me.ogg
Binary files differ
diff --git a/data/sounds/notifications/moonbeam.ogg b/data/sounds/notifications/old/Moonbeam.ogg
index 59ac985..59ac985 100644
--- a/data/sounds/notifications/moonbeam.ogg
+++ b/data/sounds/notifications/old/Moonbeam.ogg
Binary files differ
diff --git a/data/sounds/notifications/pixiedust.ogg b/data/sounds/notifications/old/Pixiedust.ogg
index 4ed7f52..4ed7f52 100644
--- a/data/sounds/notifications/pixiedust.ogg
+++ b/data/sounds/notifications/old/Pixiedust.ogg
Binary files differ
diff --git a/data/sounds/notifications/pizzicato.ogg b/data/sounds/notifications/old/Pizzicato.ogg
index 0a4a328..0a4a328 100644
--- a/data/sounds/notifications/pizzicato.ogg
+++ b/data/sounds/notifications/old/Pizzicato.ogg
Binary files differ
diff --git a/data/sounds/notifications/Plastic_Pipe.ogg b/data/sounds/notifications/old/Plastic_Pipe.ogg
index 16b06c8..16b06c8 100644
--- a/data/sounds/notifications/Plastic_Pipe.ogg
+++ b/data/sounds/notifications/old/Plastic_Pipe.ogg
Binary files differ
diff --git a/data/sounds/notifications/ShortCircuit.ogg b/data/sounds/notifications/old/ShortCircuit.ogg
index 80be87e..80be87e 100644
--- a/data/sounds/notifications/ShortCircuit.ogg
+++ b/data/sounds/notifications/old/ShortCircuit.ogg
Binary files differ
diff --git a/data/sounds/notifications/SpaceSeed.ogg b/data/sounds/notifications/old/SpaceSeed.ogg
index e69024d..e69024d 100644
--- a/data/sounds/notifications/SpaceSeed.ogg
+++ b/data/sounds/notifications/old/SpaceSeed.ogg
Binary files differ
diff --git a/data/sounds/notifications/Star_Struck.ogg b/data/sounds/notifications/old/Star_Struck.ogg
index d9e6167..d9e6167 100644
--- a/data/sounds/notifications/Star_Struck.ogg
+++ b/data/sounds/notifications/old/Star_Struck.ogg
Binary files differ
diff --git a/data/sounds/notifications/TaDa.ogg b/data/sounds/notifications/old/TaDa.ogg
index c3dc025..c3dc025 100644
--- a/data/sounds/notifications/TaDa.ogg
+++ b/data/sounds/notifications/old/TaDa.ogg
Binary files differ
diff --git a/data/sounds/notifications/Tinkerbell.ogg b/data/sounds/notifications/old/Tinkerbell.ogg
index 434e96b..434e96b 100644
--- a/data/sounds/notifications/Tinkerbell.ogg
+++ b/data/sounds/notifications/old/Tinkerbell.ogg
Binary files differ
diff --git a/data/sounds/notifications/tweeters.ogg b/data/sounds/notifications/old/Tweeters.ogg
index ecc4c5a..ecc4c5a 100644
--- a/data/sounds/notifications/tweeters.ogg
+++ b/data/sounds/notifications/old/Tweeters.ogg
Binary files differ
diff --git a/data/sounds/notifications/ouranos.ogg b/data/sounds/notifications/ouranos.ogg
deleted file mode 100755
index d0efc3a..0000000
--- a/data/sounds/notifications/ouranos.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/phantasos.ogg b/data/sounds/notifications/phantasos.ogg
deleted file mode 100755
index ea19882..0000000
--- a/data/sounds/notifications/phantasos.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/pixiedust.wav b/data/sounds/notifications/pixiedust.wav
deleted file mode 100644
index 890e855..0000000
--- a/data/sounds/notifications/pixiedust.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/pizzicato.wav b/data/sounds/notifications/pizzicato.wav
deleted file mode 100644
index d0f0cef..0000000
--- a/data/sounds/notifications/pizzicato.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/poros.ogg b/data/sounds/notifications/poros.ogg
deleted file mode 100755
index 0a50a12..0000000
--- a/data/sounds/notifications/poros.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/thrasos1.ogg b/data/sounds/notifications/thrasos1.ogg
deleted file mode 100755
index 9b7e621..0000000
--- a/data/sounds/notifications/thrasos1.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/tweeters.wav b/data/sounds/notifications/tweeters.wav
deleted file mode 100644
index b633945..0000000
--- a/data/sounds/notifications/tweeters.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/vega.ogg b/data/sounds/notifications/vega.ogg
deleted file mode 100644
index e596e60..0000000
--- a/data/sounds/notifications/vega.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Altair.wav b/data/sounds/notifications/wav/Altair.wav
deleted file mode 100644
index 0fb9788..0000000
--- a/data/sounds/notifications/wav/Altair.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Antares.wav b/data/sounds/notifications/wav/Antares.wav
deleted file mode 100644
index 7c2dd23..0000000
--- a/data/sounds/notifications/wav/Antares.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Betelgeuse.wav b/data/sounds/notifications/wav/Betelgeuse.wav
deleted file mode 100644
index 9ad799f..0000000
--- a/data/sounds/notifications/wav/Betelgeuse.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Deneb.wav b/data/sounds/notifications/wav/Deneb.wav
deleted file mode 100644
index ffe7c31..0000000
--- a/data/sounds/notifications/wav/Deneb.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Hojus.wav b/data/sounds/notifications/wav/Hojus.wav
deleted file mode 100644
index a16f943..0000000
--- a/data/sounds/notifications/wav/Hojus.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Lalande.wav b/data/sounds/notifications/wav/Lalande.wav
deleted file mode 100644
index 14c9fec..0000000
--- a/data/sounds/notifications/wav/Lalande.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Mira.wav b/data/sounds/notifications/wav/Mira.wav
deleted file mode 100644
index 71be516..0000000
--- a/data/sounds/notifications/wav/Mira.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Proxima.wav b/data/sounds/notifications/wav/Proxima.wav
deleted file mode 100644
index 109bfdd..0000000
--- a/data/sounds/notifications/wav/Proxima.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Upsilon.wav b/data/sounds/notifications/wav/Upsilon.wav
deleted file mode 100644
index ffc959b..0000000
--- a/data/sounds/notifications/wav/Upsilon.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ring3.ogg b/data/sounds/ring3.ogg
deleted file mode 100644
index a0793d9..0000000
--- a/data/sounds/ring3.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringer.ogg b/data/sounds/ringer.ogg
deleted file mode 100644
index 75a01f3..0000000
--- a/data/sounds/ringer.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ANDROMEDA.ogg b/data/sounds/ringtones/ANDROMEDA.ogg
deleted file mode 100644
index 8f6bd3e..0000000
--- a/data/sounds/ringtones/ANDROMEDA.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Aquila.ogg b/data/sounds/ringtones/Aquila.ogg
deleted file mode 100644
index b391be9..0000000
--- a/data/sounds/ringtones/Aquila.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ArgoNavis.ogg b/data/sounds/ringtones/ArgoNavis.ogg
deleted file mode 100644
index b4202ac..0000000
--- a/data/sounds/ringtones/ArgoNavis.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/BOOTES.ogg b/data/sounds/ringtones/BOOTES.ogg
deleted file mode 100644
index 0716a4f..0000000
--- a/data/sounds/ringtones/BOOTES.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/CANISMAJOR.ogg b/data/sounds/ringtones/CANISMAJOR.ogg
deleted file mode 100644
index 177d3de..0000000
--- a/data/sounds/ringtones/CANISMAJOR.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/CASSIOPEIA.ogg b/data/sounds/ringtones/CASSIOPEIA.ogg
deleted file mode 100644
index c4a7948..0000000
--- a/data/sounds/ringtones/CASSIOPEIA.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Carina.ogg b/data/sounds/ringtones/Carina.ogg
deleted file mode 100644
index aeb9b36..0000000
--- a/data/sounds/ringtones/Carina.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Carina.wav b/data/sounds/ringtones/Carina.wav
deleted file mode 100755
index ecaeb58..0000000
--- a/data/sounds/ringtones/Carina.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Centaurus.ogg b/data/sounds/ringtones/Centaurus.ogg
deleted file mode 100644
index 404bdbc..0000000
--- a/data/sounds/ringtones/Centaurus.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Cygnus.ogg b/data/sounds/ringtones/Cygnus.ogg
deleted file mode 100644
index b2e1e65..0000000
--- a/data/sounds/ringtones/Cygnus.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Draco.ogg b/data/sounds/ringtones/Draco.ogg
deleted file mode 100644
index 88d5a04..0000000
--- a/data/sounds/ringtones/Draco.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Eridani.ogg b/data/sounds/ringtones/Eridani.ogg
deleted file mode 100644
index b665a29..0000000
--- a/data/sounds/ringtones/Eridani.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/FreeFlight.ogg b/data/sounds/ringtones/FreeFlight.ogg
deleted file mode 100644
index 76dfabe..0000000
--- a/data/sounds/ringtones/FreeFlight.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/FreeFlight.wav b/data/sounds/ringtones/FreeFlight.wav
deleted file mode 100644
index a4e14aa..0000000
--- a/data/sounds/ringtones/FreeFlight.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Lyra.ogg b/data/sounds/ringtones/Lyra.ogg
deleted file mode 100644
index 696f278..0000000
--- a/data/sounds/ringtones/Lyra.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Machina.ogg b/data/sounds/ringtones/Machina.ogg
deleted file mode 100644
index ac16f7e..0000000
--- a/data/sounds/ringtones/Machina.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Orion.ogg b/data/sounds/ringtones/Orion.ogg
deleted file mode 100644
index 807f107..0000000
--- a/data/sounds/ringtones/Orion.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/PERSEUS.ogg b/data/sounds/ringtones/PERSEUS.ogg
deleted file mode 100644
index ad06021..0000000
--- a/data/sounds/ringtones/PERSEUS.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Pegasus.ogg b/data/sounds/ringtones/Pegasus.ogg
deleted file mode 100644
index 66c4970..0000000
--- a/data/sounds/ringtones/Pegasus.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Pyxis.ogg b/data/sounds/ringtones/Pyxis.ogg
deleted file mode 100644
index 2d3adce..0000000
--- a/data/sounds/ringtones/Pyxis.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Rigel.ogg b/data/sounds/ringtones/Rigel.ogg
deleted file mode 100644
index af2c176..0000000
--- a/data/sounds/ringtones/Rigel.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Scarabaeus.ogg b/data/sounds/ringtones/Scarabaeus.ogg
deleted file mode 100644
index e70fc69..0000000
--- a/data/sounds/ringtones/Scarabaeus.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Sceptrum.ogg b/data/sounds/ringtones/Sceptrum.ogg
deleted file mode 100644
index fc50aef..0000000
--- a/data/sounds/ringtones/Sceptrum.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Solarium.ogg b/data/sounds/ringtones/Solarium.ogg
deleted file mode 100644
index d27f141..0000000
--- a/data/sounds/ringtones/Solarium.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Testudo.ogg b/data/sounds/ringtones/Testudo.ogg
deleted file mode 100644
index 0ca8d6b..0000000
--- a/data/sounds/ringtones/Testudo.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/URSAMINOR.ogg b/data/sounds/ringtones/URSAMINOR.ogg
deleted file mode 100644
index c0010e82..0000000
--- a/data/sounds/ringtones/URSAMINOR.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/Vespa.ogg b/data/sounds/ringtones/Vespa.ogg
deleted file mode 100644
index 4423bbb..0000000
--- a/data/sounds/ringtones/Vespa.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/hydra.ogg b/data/sounds/ringtones/hydra.ogg
deleted file mode 100644
index edde14f..0000000
--- a/data/sounds/ringtones/hydra.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/Ring_Classic_01.ogg b/data/sounds/ringtones/old/Ring_Classic_01.ogg
index b5e6077..b5e6077 100644
--- a/data/sounds/Ring_Classic_01.ogg
+++ b/data/sounds/ringtones/old/Ring_Classic_01.ogg
Binary files differ
diff --git a/data/sounds/Ring_Classic_02.ogg b/data/sounds/ringtones/old/Ring_Classic_02.ogg
index aeb2d5b..aeb2d5b 100644
--- a/data/sounds/Ring_Classic_02.ogg
+++ b/data/sounds/ringtones/old/Ring_Classic_02.ogg
Binary files differ
diff --git a/data/sounds/Ring_Classic_03.ogg b/data/sounds/ringtones/old/Ring_Classic_03.ogg
index 2b14eb4..2b14eb4 100644
--- a/data/sounds/Ring_Classic_03.ogg
+++ b/data/sounds/ringtones/old/Ring_Classic_03.ogg
Binary files differ
diff --git a/data/sounds/Ring_Classic_04.ogg b/data/sounds/ringtones/old/Ring_Classic_04.ogg
index 7474ac5..7474ac5 100644
--- a/data/sounds/Ring_Classic_04.ogg
+++ b/data/sounds/ringtones/old/Ring_Classic_04.ogg
Binary files differ
diff --git a/data/sounds/Ring_Classic_05.ogg b/data/sounds/ringtones/old/Ring_Classic_05.ogg
index b9ef5b1..b9ef5b1 100644
--- a/data/sounds/Ring_Classic_05.ogg
+++ b/data/sounds/ringtones/old/Ring_Classic_05.ogg
Binary files differ
diff --git a/data/sounds/Ring_Digital_01.ogg b/data/sounds/ringtones/old/Ring_Digital_01.ogg
index 39d2bb8..39d2bb8 100644
--- a/data/sounds/Ring_Digital_01.ogg
+++ b/data/sounds/ringtones/old/Ring_Digital_01.ogg
Binary files differ
diff --git a/data/sounds/Ring_Digital_02.ogg b/data/sounds/ringtones/old/Ring_Digital_02.ogg
index f823739..f823739 100644
--- a/data/sounds/Ring_Digital_02.ogg
+++ b/data/sounds/ringtones/old/Ring_Digital_02.ogg
Binary files differ
diff --git a/data/sounds/Ring_Digital_03.ogg b/data/sounds/ringtones/old/Ring_Digital_03.ogg
index 2b70ee8..2b70ee8 100644
--- a/data/sounds/Ring_Digital_03.ogg
+++ b/data/sounds/ringtones/old/Ring_Digital_03.ogg
Binary files differ
diff --git a/data/sounds/Ring_Digital_04.ogg b/data/sounds/ringtones/old/Ring_Digital_04.ogg
index d2ca486..d2ca486 100644
--- a/data/sounds/Ring_Digital_04.ogg
+++ b/data/sounds/ringtones/old/Ring_Digital_04.ogg
Binary files differ
diff --git a/data/sounds/Ring_Digital_05.ogg b/data/sounds/ringtones/old/Ring_Digital_05.ogg
index efde497..efde497 100644
--- a/data/sounds/Ring_Digital_05.ogg
+++ b/data/sounds/ringtones/old/Ring_Digital_05.ogg
Binary files differ
diff --git a/data/sounds/Ring_Synth_01.ogg b/data/sounds/ringtones/old/Ring_Synth_01.ogg
index ec2e628..ec2e628 100644
--- a/data/sounds/Ring_Synth_01.ogg
+++ b/data/sounds/ringtones/old/Ring_Synth_01.ogg
Binary files differ
diff --git a/data/sounds/Ring_Synth_02.ogg b/data/sounds/ringtones/old/Ring_Synth_02.ogg
index 4fc1920..4fc1920 100644
--- a/data/sounds/Ring_Synth_02.ogg
+++ b/data/sounds/ringtones/old/Ring_Synth_02.ogg
Binary files differ
diff --git a/data/sounds/Ring_Synth_03.ogg b/data/sounds/ringtones/old/Ring_Synth_03.ogg
index bb45ecb..bb45ecb 100644
--- a/data/sounds/Ring_Synth_03.ogg
+++ b/data/sounds/ringtones/old/Ring_Synth_03.ogg
Binary files differ
diff --git a/data/sounds/Ring_Synth_04.ogg b/data/sounds/ringtones/old/Ring_Synth_04.ogg
index ec2d9ac..ec2d9ac 100644
--- a/data/sounds/Ring_Synth_04.ogg
+++ b/data/sounds/ringtones/old/Ring_Synth_04.ogg
Binary files differ
diff --git a/data/sounds/Ring_Synth_05.ogg b/data/sounds/ringtones/old/Ring_Synth_05.ogg
index 674434e..674434e 100644
--- a/data/sounds/Ring_Synth_05.ogg
+++ b/data/sounds/ringtones/old/Ring_Synth_05.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ringtone18.ogg b/data/sounds/ringtones/ringtone18.ogg
deleted file mode 100644
index 00cd28f..0000000
--- a/data/sounds/ringtones/ringtone18.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone19.ogg b/data/sounds/ringtones/ringtone19.ogg
deleted file mode 100644
index 02acaa7..0000000
--- a/data/sounds/ringtones/ringtone19.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone20.ogg b/data/sounds/ringtones/ringtone20.ogg
deleted file mode 100644
index e6d1051..0000000
--- a/data/sounds/ringtones/ringtone20.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone21.ogg b/data/sounds/ringtones/ringtone21.ogg
deleted file mode 100644
index f8ef541..0000000
--- a/data/sounds/ringtones/ringtone21.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone22.ogg b/data/sounds/ringtones/ringtone22.ogg
deleted file mode 100644
index cd349f5..0000000
--- a/data/sounds/ringtones/ringtone22.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone23.ogg b/data/sounds/ringtones/ringtone23.ogg
deleted file mode 100644
index 3b4f000..0000000
--- a/data/sounds/ringtones/ringtone23.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone24.ogg b/data/sounds/ringtones/ringtone24.ogg
deleted file mode 100644
index e1c5c3b..0000000
--- a/data/sounds/ringtones/ringtone24.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone25.ogg b/data/sounds/ringtones/ringtone25.ogg
deleted file mode 100644
index 0f66463..0000000
--- a/data/sounds/ringtones/ringtone25.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone26.ogg b/data/sounds/ringtones/ringtone26.ogg
deleted file mode 100644
index 8cd4648..0000000
--- a/data/sounds/ringtones/ringtone26.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone27.ogg b/data/sounds/ringtones/ringtone27.ogg
deleted file mode 100644
index 9671d6e..0000000
--- a/data/sounds/ringtones/ringtone27.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone28.ogg b/data/sounds/ringtones/ringtone28.ogg
deleted file mode 100644
index 6139667..0000000
--- a/data/sounds/ringtones/ringtone28.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone29.ogg b/data/sounds/ringtones/ringtone29.ogg
deleted file mode 100644
index 042c82a..0000000
--- a/data/sounds/ringtones/ringtone29.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone30.ogg b/data/sounds/ringtones/ringtone30.ogg
deleted file mode 100644
index eec8ebc..0000000
--- a/data/sounds/ringtones/ringtone30.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone31.ogg b/data/sounds/ringtones/ringtone31.ogg
deleted file mode 100644
index 0140a80..0000000
--- a/data/sounds/ringtones/ringtone31.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone32.ogg b/data/sounds/ringtones/ringtone32.ogg
deleted file mode 100644
index 4e12f5a..0000000
--- a/data/sounds/ringtones/ringtone32.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone33.ogg b/data/sounds/ringtones/ringtone33.ogg
deleted file mode 100644
index 1342066..0000000
--- a/data/sounds/ringtones/ringtone33.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone34.ogg b/data/sounds/ringtones/ringtone34.ogg
deleted file mode 100644
index a16737b..0000000
--- a/data/sounds/ringtones/ringtone34.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone35.ogg b/data/sounds/ringtones/ringtone35.ogg
deleted file mode 100644
index 3407857..0000000
--- a/data/sounds/ringtones/ringtone35.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone36.ogg b/data/sounds/ringtones/ringtone36.ogg
deleted file mode 100644
index bbd5263..0000000
--- a/data/sounds/ringtones/ringtone36.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone37.ogg b/data/sounds/ringtones/ringtone37.ogg
deleted file mode 100644
index ae7b57e..0000000
--- a/data/sounds/ringtones/ringtone37.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/ringtone38.ogg b/data/sounds/ringtones/ringtone38.ogg
deleted file mode 100644
index fae20cd..0000000
--- a/data/sounds/ringtones/ringtone38.ogg
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/wav/Carina.wav b/data/sounds/ringtones/wav/Carina.wav
deleted file mode 100644
index ecaeb58..0000000
--- a/data/sounds/ringtones/wav/Carina.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/wav/Cassiopeia.wav b/data/sounds/ringtones/wav/Cassiopeia.wav
deleted file mode 100644
index 5c5c6e0..0000000
--- a/data/sounds/ringtones/wav/Cassiopeia.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/wav/Lyra.wav b/data/sounds/ringtones/wav/Lyra.wav
deleted file mode 100644
index 2943cf5..0000000
--- a/data/sounds/ringtones/wav/Lyra.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/wav/Sceptrum.wav b/data/sounds/ringtones/wav/Sceptrum.wav
deleted file mode 100644
index 3694373..0000000
--- a/data/sounds/ringtones/wav/Sceptrum.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/wav/Solarium.wav b/data/sounds/ringtones/wav/Solarium.wav
deleted file mode 100644
index 93f1e01..0000000
--- a/data/sounds/ringtones/wav/Solarium.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/wav/UrsaMinor.wav b/data/sounds/ringtones/wav/UrsaMinor.wav
deleted file mode 100644
index 5e16c94..0000000
--- a/data/sounds/ringtones/wav/UrsaMinor.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/ringtones/wav/Vespa.wav b/data/sounds/ringtones/wav/Vespa.wav
deleted file mode 100644
index 7d696f8..0000000
--- a/data/sounds/ringtones/wav/Vespa.wav
+++ /dev/null
Binary files differ
diff --git a/fmradio/include/android_fmradio.h b/fmradio/include/android_fmradio.h
new file mode 100644
index 0000000..18518b6
--- /dev/null
+++ b/fmradio/include/android_fmradio.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: johan.xj.palmaeus@stericsson.com for ST-Ericsson
+ */
+
+/*
+ * Internal stuff for android_fmradio(_Receiver/_Transmitter).cpp
+ */
+
+#ifndef ANDROID_FMRADIO_H
+#define ANDROID_FMRADIO_H
+
+#include "jni.h"
+#include "fmradio.h"
+
+enum FmRadioState_t {
+ FMRADIO_STATE_IDLE,
+ FMRADIO_STATE_STARTING,
+ FMRADIO_STATE_STARTED,
+ FMRADIO_STATE_PAUSED,
+ FMRADIO_STATE_SCANNING,
+ FMRADIO_STATE_EXTRA_COMMAND,
+ /* sum up */
+ FMRADIO_NUMBER_OF_STATES
+};
+
+enum FmRadioCommand_t {
+ FMRADIO_EVENT_START,
+ FMRADIO_EVENT_START_ASYNC,
+ FMRADIO_EVENT_PAUSE,
+ FMRADIO_EVENT_RESUME,
+ FMRADIO_EVENT_RESET,
+ FMRADIO_EVENT_GET_FREQUENCY,
+ FMRADIO_EVENT_SET_FREQUENCY,
+ FMRADIO_EVENT_SET_PARAMETER,
+ FMRADIO_EVENT_STOP_SCAN,
+ FMRADIO_EVENT_EXTRA_COMMAND,
+ /* RX Only */
+ FMRADIO_EVENT_GET_PARAMETER,
+ FMRADIO_EVENT_GET_SIGNAL_STRENGTH,
+ FMRADIO_EVENT_SCAN,
+ FMRADIO_EVENT_FULL_SCAN,
+ /* TX Only */
+ FMRADIO_EVENT_BLOCK_SCAN,
+ /* sum up */
+ FMRADIO_NUMBER_OF_EVENTS
+};
+
+enum RadioMode_t {
+ FMRADIO_RX,
+ FMRADIO_TX
+};
+
+typedef bool ValidEventsForStates_t[FMRADIO_NUMBER_OF_EVENTS]
+ [FMRADIO_NUMBER_OF_STATES];
+
+struct FmRadioCallbacks_t {
+ void (*onStateChanged) (int, int);
+ void (*onError) (void);
+ void (*onStarted) (void);
+ void (*onScan) (int, int, int, bool); /* RX only */
+ void (*onFullScan) (int, int *, int *, bool); /* RX only */
+ void (*onBlockScan) (int, int *, int *, bool); /* TX only */
+ void (*onForcedReset) (enum fmradio_reset_reason_t reason);
+ void (*onSendExtraCommand) (char*, struct fmradio_extra_command_ret_item_t *);
+};
+
+struct bundle_descriptor_offsets_t {
+ jclass mClass;
+ jmethodID mConstructor;
+ jmethodID mGetInt;
+ jmethodID mGetIntArray;
+ jmethodID mGetShort;
+ jmethodID mGetShortArray;
+ jmethodID mGetString;
+ jmethodID mContainsKey;
+ jmethodID mSize;
+ jmethodID mKeySet;
+ jmethodID mPutInt;
+ jmethodID mPutShort;
+ jmethodID mPutIntArray;
+ jmethodID mPutShortArray;
+ jmethodID mPutString;
+};
+
+struct FmSession_t {
+ // vendor specific data, we do not know about this type
+ void *vendorData_p;
+ void *fmLibrary_p;
+ bool isRegistered;
+ enum FmRadioState_t state;
+ struct fmradio_vendor_methods_t *vendorMethods_p;
+ const ValidEventsForStates_t *validEventsForStates_p;
+ const struct FmRadioCallbacks_t *callbacks_p;
+ JavaVM *jvm_p;
+ jobject jobj;
+ struct FmSession_t *partnerSession_p;
+ struct bundle_descriptor_offsets_t *bundleOffsets_p;
+ enum FmRadioState_t oldState; /* used when scanning */
+ bool lastScanAborted; /* used when scanning */
+ bool pendingPause; /* used when scanning & asyncStarting */
+ bool ongoingReset; /* used during reset while waiting */
+ pthread_mutex_t *dataMutex_p; /* data access to this struct */
+ pthread_cond_t sync_cond;
+ struct ThreadCtrl_t *signalStrengthThreadCtrl_p; /* RX Only */
+};
+
+#define FMRADIO_SET_STATE(_session_p,_newState) {int _oldState = (_session_p)->state; (_session_p)->state = _newState;(_session_p)->callbacks_p->onStateChanged(_oldState, _newState);}
+
+/* exceptions */
+
+#define THROW_ILLEGAL_ARGUMENT(_session_p) \
+ androidFmRadioThrowException(_session_p,\
+ "java/lang/IllegalArgumentException",\
+ "Illegal argument", __FILE__, __LINE__,\
+ __FUNCTION__)
+#define THROW_UNSUPPORTED_OPERATION(_session_p) \
+ androidFmRadioThrowException(_session_p,\
+ "java/lang/UnsupportedOperationException",\
+ "Unsupported operation", __FILE__, __LINE__,\
+ __FUNCTION__)
+#define THROW_INVALID_STATE(_session_p) \
+ androidFmRadioThrowException(_session_p,\
+ "java/lang/IllegalStateException",\
+ "State is invalid", __FILE__, __LINE__,\
+ __FUNCTION__)
+#define THROW_IO_ERROR(_session_p) \
+ androidFmRadioThrowException(_session_p,\
+ "java/io/IOException",\
+ "IO Exception", __FILE__, __LINE__,\
+ __FUNCTION__)
+
+
+#define FM_LIBRARY_NAME_MAX_LENGTH 128
+
+#define THREAD_WAIT_TIMEOUT_S 2
+
+#define SIGNAL_STRENGTH_MAX 1000
+#define SIGNAL_STRENGTH_UNKNOWN -1
+
+extern pthread_mutex_t rx_tx_common_mutex;
+
+jobject extraCommandRetList2Bundle(JNIEnv * env_p, struct bundle_descriptor_offsets_t
+ *bundleOffsets_p,
+ struct fmradio_extra_command_ret_item_t *itemList);
+
+void freeExtraCommandRetList(struct extra_command_ret_item_t *itemList);
+
+void androidFmRadioTempResumeIfPaused(struct FmSession_t *session_p);
+
+void androidFmRadioPauseIfTempResumed(struct FmSession_t *session_p);
+
+bool androidFmRadioIsValidEventForState(struct FmSession_t *session_p,
+ enum FmRadioCommand_t event);
+
+void androidFmRadioThrowException(struct FmSession_t *session_p,
+ const char *exception,
+ const char *message, const char *file,
+ int line, const char *function);
+
+bool androidFmRadioLoadFmLibrary(struct FmSession_t *session_p,
+ enum RadioMode_t mode);
+
+void androidFmRadioUnLoadFmLibrary(struct FmSession_t *session_p);
+
+int
+androidFmRadioStart(struct FmSession_t *session_p, enum RadioMode_t mode,
+ const struct fmradio_vendor_callbacks_t *callbacks,
+ bool async, int lowFreq, int highFreq, int defaultFreq,
+ int grid);
+
+int androidFmRadioPause(struct FmSession_t *session_p);
+
+int androidFmRadioResume(struct FmSession_t *session_p);
+
+int androidFmRadioReset(struct FmSession_t *session_p);
+
+void androidFmRadioSetFrequency(struct FmSession_t *session_p,
+ int frequency);
+
+int androidFmRadioGetFrequency(struct FmSession_t *session_p);
+
+void androidFmRadioStopScan(struct FmSession_t *session_p);
+
+void
+androidFmRadioSendExtraCommand(struct FmSession_t *session_p, JNIEnv * env,
+ jstring command, jobjectArray parameter);
+
+#endif
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmBand.aidl b/fmradio/java/com/stericsson/hardware/fm/FmBand.aidl
new file mode 100644
index 0000000..76def36
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmBand.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+parcelable FmBand;
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmBand.java b/fmradio/java/com/stericsson/hardware/fm/FmBand.java
new file mode 100644
index 0000000..f1002f3
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmBand.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Bjorn Pileryd (bjorn.pileryd@sonyericsson.com)
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Describes the properties of the FM frequency band. The frequency band range
+ * and the channel offset vary in different regions. The unit for all
+ * frequencies in this class is kHz.
+ */
+public class FmBand implements Parcelable {
+
+ /**
+ * Default band for US 87.9MHz - 107.9MHz, 200kHz channel offset.
+ */
+ public static final int BAND_US = 0;
+
+ /**
+ * Default band for EU 87.5MHz - 108MHz, 100kHz channel offset.
+ */
+ public static final int BAND_EU = 1;
+
+ /**
+ * Default band for Japan 76MHz - 90MHz, 100kHz channel offset.
+ */
+ public static final int BAND_JAPAN = 2;
+
+ /**
+ * Default band for China 70MHz - 108MHz, 50kHz channel offset.
+ */
+ public static final int BAND_CHINA = 3;
+
+ /**
+ * Default band for EU 87.5MHz - 108MHz, 50kHz channel offset.
+ */
+ public static final int BAND_EU_50K_OFFSET = 4;
+
+ /**
+ * Unknown frequency.
+ */
+ public static final int FM_FREQUENCY_UNKNOWN = -1;
+
+ /**
+ * The lowest frequency of the band.
+ */
+ private int mMinFrequency;
+
+ /**
+ * The highest frequency of the band.
+ */
+ private int mMaxFrequency;
+
+ /**
+ * The default frequency of the band.
+ */
+ private int mDefaultFrequency;
+
+ /**
+ * The offset between the channels in the band.
+ */
+ private int mChannelOffset;
+
+ /**
+ * Creates a band representation.
+ *
+ * @param minFrequency
+ * the lowest frequency of the band in kHz
+ * @param maxFrequency
+ * the highest frequency of the band in kHz
+ * @param channelOffset
+ * the offset between the channels in the band in kHz
+ * @param defaultFrequency
+ * the default frequency that the hardware will tune to at
+ * startup
+ * @throws IllegalArgumentException
+ * if the minFrequency is equal or higher then maxFrequency
+ * @throws IllegalArgumentException
+ * if the defaultFrequency is not within the limits of
+ * minFrequency and maxFrequency
+ * @throws IllegalArgumentException
+ * if the minFrequency or maxFrequency is not a multiplier of channelOffset
+ */
+ public FmBand(int minFrequency, int maxFrequency, int channelOffset, int defaultFrequency) {
+ if (minFrequency >= maxFrequency) {
+ throw new IllegalArgumentException(
+ "Minimum frequency can not be equal or higher than maximum frequency");
+ }
+ if (defaultFrequency < minFrequency) {
+ throw new IllegalArgumentException(
+ "Default frequency can not be less than minFrequency");
+ }
+ if (defaultFrequency > maxFrequency) {
+ throw new IllegalArgumentException(
+ "Default frequency can not be higher than maxFrequency");
+ }
+ if ((maxFrequency - minFrequency) % channelOffset != 0
+ || (defaultFrequency - minFrequency) % channelOffset != 0) {
+ throw new IllegalArgumentException(
+ "Frequency has invalid offset");
+ }
+ this.mMinFrequency = minFrequency;
+ this.mMaxFrequency = maxFrequency;
+ this.mDefaultFrequency = defaultFrequency;
+ this.mChannelOffset = channelOffset;
+ }
+
+ /**
+ * Creates a standard band representation. The default frequency will be the
+ * lowest frequency for the specified band.
+ *
+ * @param band
+ * one of {@link #BAND_US}, {@link #BAND_EU}, {@link #BAND_JAPAN}
+ * , {@link #BAND_CHINA}, {@link #BAND_EU_50K_OFFSET}
+ * @throws IllegalArgumentException
+ * if the band is not one of {@link #BAND_US}, {@link #BAND_EU},
+ * {@link #BAND_JAPAN}, {@link #BAND_CHINA}, {@link #BAND_EU_50K_OFFSET}
+ */
+ public FmBand(int band) {
+ switch (band) {
+ case BAND_US:
+ this.mMinFrequency = 87900;
+ this.mMaxFrequency = 107900;
+ this.mDefaultFrequency = 87900;
+ this.mChannelOffset = 200;
+ break;
+ case BAND_EU:
+ this.mMinFrequency = 87500;
+ this.mMaxFrequency = 108000;
+ this.mDefaultFrequency = 87500;
+ this.mChannelOffset = 100;
+ break;
+ case BAND_JAPAN:
+ this.mMinFrequency = 76000;
+ this.mMaxFrequency = 90000;
+ this.mDefaultFrequency = 76000;
+ this.mChannelOffset = 100;
+ break;
+ case BAND_CHINA:
+ this.mMinFrequency = 70000;
+ this.mMaxFrequency = 108000;
+ this.mDefaultFrequency = 70000;
+ this.mChannelOffset = 50;
+ break;
+ case BAND_EU_50K_OFFSET:
+ this.mMinFrequency = 87500;
+ this.mMaxFrequency = 108000;
+ this.mDefaultFrequency = 87500;
+ this.mChannelOffset = 50;
+ break;
+ default:
+ throw new IllegalArgumentException("Wrong band identifier");
+ }
+ }
+
+ /**
+ * Checks if a frequency is valid to the band. To be valid it must be within
+ * the frequency range and on a frequency with correct channel offset.
+ *
+ * @param frequency
+ * the frequency to validate
+ * @return true if the frequency is valid for this band
+ */
+ public boolean isFrequencyValid(int frequency) {
+ if (frequency < mMinFrequency || frequency > mMaxFrequency) {
+ return false;
+ }
+ if ((frequency - mMinFrequency) % mChannelOffset != 0) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return the lowest frequency of the band.
+ *
+ * @return the lowest frequency of the band in kHz
+ */
+ public int getMinFrequency() {
+ return mMinFrequency;
+ }
+
+ /**
+ * Returns the highest frequency of the band.
+ *
+ * @return the highest frequency of the band in kHz
+ */
+ public int getMaxFrequency() {
+ return mMaxFrequency;
+ }
+
+ /**
+ * Returns the default frequency of the band that the hardware will tune to
+ * at startup.
+ *
+ * @return the default frequency of the band in kHz
+ */
+ public int getDefaultFrequency() {
+ return mDefaultFrequency;
+ }
+
+ /**
+ * Returns the offset between the channels in the band.
+ *
+ * @return the offset between the channels in the band in kHz
+ */
+ public int getChannelOffset() {
+ return mChannelOffset;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mMinFrequency);
+ dest.writeInt(mMaxFrequency);
+ dest.writeInt(mChannelOffset);
+ dest.writeInt(mDefaultFrequency);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<FmBand> CREATOR = new Creator<FmBand>() {
+ public FmBand createFromParcel(Parcel in) {
+ int minfreq = in.readInt();
+ int maxfreq = in.readInt();
+ int offset = in.readInt();
+ int defaultFreq = in.readInt();
+ FmBand band = new FmBand(minfreq, maxfreq, offset, defaultFreq);
+ return band;
+ }
+
+ public FmBand[] newArray(int size) {
+ return new FmBand[size];
+ }
+ };
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmReceiver.java b/fmradio/java/com/stericsson/hardware/fm/FmReceiver.java
new file mode 100644
index 0000000..1055429
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmReceiver.java
@@ -0,0 +1,1327 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Bjorn Pileryd (bjorn.pileryd@sonyericsson.com)
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import java.io.IOException;
+
+/**
+ * The FmReceiver controls reception of FM radio. This API enables an
+ * application to tune/scan for channels, receive RDS data, etc. The unit for
+ * all frequencies in this class is kHz. Note that this API only controls the
+ * reception of FM radio, to play FM radio the MediaPlayer interfaces should be
+ * used, see code example below the state diagram.
+ * <p>
+ * Get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(String)
+ * Context.getSystemService("fm_receiver")}.
+ * </p>
+ * <a name="StateDiagram"></a> <h3>State Diagram</h3>
+ * <p>
+ * The state machine is designed to take into account that some hardware may
+ * need time to prepare, and that it is likely to consume more power when paused
+ * and started than it does in the idle state. The hardware implementation of
+ * this interface should do the time consuming preparation procedures in the
+ * starting state. The switching between paused and started states should be
+ * fast to give a good user experience.
+ * </p>
+ * <p>
+ * <img src="../../../../images/FmReceiver_states.gif"
+ * alt="FmReceiver State diagram" border="0" />
+ * </p>
+ * <table border="1">
+ * <tr>
+ * <th>Method Name</th>
+ * <th>Valid States</th>
+ * <th>Invalid States</th>
+ * <th>Comments</th>
+ * </tr>
+ * <tr>
+ * <td>{@link #startAsync(FmBand)}</td>
+ * <td>{idle}</td>
+ * <td>{starting, paused, started, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the starting state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #start(FmBand)}</td>
+ * <td>{idle}</td>
+ * <td>{starting, paused, started, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the started state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #resume()}</td>
+ * <td>{paused, started}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the started state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #pause()}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the paused state. Calling this method in an invalid state throws an
+ * IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #reset()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>Successful invocation of this method transfers the object to the idle
+ * state, the object is like being just created.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #getState()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #isApiSupported(Context)}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #isRDSDataSupported()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #isTunedToValidChannel()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #setThreshold(int)}</td>
+ * <td>{started, paused, scanning}</td>
+ * <td>{idle, starting}</td>
+ * <td>Calling this method in an invalid state throws an IllegalStateException.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>{@link #getThreshold()}</td>
+ * <td>{started, paused, scanning}</td>
+ * <td>{idle, starting}</td>
+ * <td>Calling this method in an invalid state throws an IllegalStateException.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>{@link #getFrequency()}</td>
+ * <td>{paused, started}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state does not change the
+ * object state. Calling this method in an invalid state throws an
+ * IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #getSignalStrength()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #isPlayingInStereo()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #setForceMono(boolean)}</td>
+ * <td>{started, paused, scanning}</td>
+ * <td>{idle, starting}</td>
+ * <td>Calling this method in an invalid state throws an IllegalStateException.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>{@link #setAutomaticAFSwitching(boolean)}</td>
+ * <td>{started, paused, scanning}</td>
+ * <td>{idle, starting}</td>
+ * <td>Calling this method in an invalid state throws an IllegalStateException.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>{@link #setAutomaticTASwitching(boolean)}</td>
+ * <td>{started, paused, scanning}</td>
+ * <td>{idle, starting}</td>
+ * <td>Calling this method in an invalid state throws an IllegalStateException.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>{@link #setFrequency(int)}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state does not change the
+ * object state. Calling this method in an invalid state throws an
+ * IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #startFullScan()}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the scanning state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #scanUp()}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the scanning state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #scanDown()}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the scanning state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #stopScan()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>Successful invocation of this method in a valid state tries to stop
+ * performing a scan operation. The hardware might continue the scan for an
+ * unspecified amount of time after this method is called. Once the scan has
+ * stopped, it will be notified via {@link OnScanListener}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #sendExtraCommand(String, String[])}</td>
+ * <td>vendor specific</td>
+ * <td>vendor specific</td>
+ * <td>vendor specific</td>
+ * </tr>
+ * </table>
+ * <a name="Examples"></a> <h3>Example code</h3>
+ * <pre>
+ * // start receiving FM radio
+ * FmReceiver fmr = (FmReceiver) getSystemService("fm_receiver");
+ * fmr.start(new FmBand(FmBand.BAND_EU));
+ *
+ * // prepare and start playback
+ * MediaPlayer mp = new MediaPlayer();
+ * mp.setDataSource(&quot;fmradio://rx&quot;);
+ * mp.prepare();
+ * mp.start();
+ * </pre>
+ * <a name="FMHandling"></a> <h3>FM receiving/transmission handling</h3>
+ * <p>
+ * In this API, FM radio cannot be received and transmitted at the same time,
+ * therefore the state machine is designed to prevent incorrect usage. The
+ * FmReceiver and FmTransmitter has a separate state machine and only one can be
+ * <i>active</i> (state other than idle).
+ * <ul>
+ * <li>If start is called on FmReceiver and the FmTransmitter is <i>active</i>,
+ * the FmTransmitter MUST release resources and change state to idle.</li>
+ * <li>The FmTransmitter will in that case be notified by
+ * {@link com.stericsson.hardware.fm.FmTransmitter.OnForcedResetListener#onForcedReset(int)}.</li>
+ * </ul>
+ * </p>
+ * <a name="RDSHandling"></a> <h3>Receiving/transmitting RDS data</h3>
+ * <p>
+ * RDS data can be received by setting the
+ * {@link #addOnRDSDataFoundListener(OnRDSDataFoundListener)}. When RDS data is
+ * available the data can be extracted from the Bundle object in
+ * {@link OnRDSDataFoundListener#onRDSDataFound(Bundle, int)} according to the
+ * table below. This table can also be used when transmitting RDS data with the
+ * FmTransmitter.
+ * </p>
+ * <table border="1">
+ * <tr>
+ * <th>RDS description</th>
+ * <th>key name</th>
+ * <th>value type</th>
+ * <th>value description</th>
+ * </tr>
+ * <tr>
+ * <td>Program Identification code</td>
+ * <td>PI</td>
+ * <td>short</td>
+ * <td>N/A</td>
+ * </tr>
+ * <tr>
+ * <td>Traffic Program Identification code</td>
+ * <td>TP</td>
+ * <td>short</td>
+ * <td>1 bit</td>
+ * </tr>
+ * <tr>
+ * <td>Program Type code</td>
+ * <td>PTY</td>
+ * <td>short</td>
+ * <td>5 bits</td>
+ * </tr>
+ * <tr>
+ * <td>Traffic Announcement code</td>
+ * <td>TA</td>
+ * <td>short</td>
+ * <td>1 bit</td>
+ * </tr>
+ * <tr>
+ * <td>Music/Speech switch code</td>
+ * <td>M/S</td>
+ * <td>short</td>
+ * <td>1 bit</td>
+ * </tr>
+ * <tr>
+ * <td>Alternative Frequency</td>
+ * <td>AF</td>
+ * <td>int[]</td>
+ * <td>kHz</td>
+ * </tr>
+ * <tr>
+ * <td>Program service name</td>
+ * <td>PSN</td>
+ * <td>string</td>
+ * <td>8 chars</td>
+ * </tr>
+ * <tr>
+ * <td>Radio text</td>
+ * <td>RT</td>
+ * <td>string</td>
+ * <td>64 chars</td>
+ * </tr>
+ * <tr>
+ * <td>Clock-time and date</td>
+ * <td>CT</td>
+ * <td>string</td>
+ * <td>Yr:mo:dy:hr:min</td>
+ * </tr>
+ * <tr>
+ * <td>Program Type name</td>
+ * <td>PTYN</td>
+ * <td>string</td>
+ * <td>8 chars</td>
+ * </tr>
+ * <tr>
+ * <td>Traffic Message Channel</td>
+ * <td>TMC</td>
+ * <td>short[]</td>
+ * <td>X:Y:Z -> 5+16+16 bits</td>
+ * </tr>
+ * <tr>
+ * <td>TA Frequency</td>
+ * <td>TAF</td>
+ * <td>int</td>
+ * <td>kHz</td>
+ * </tr>
+ * </table>
+ * <p>
+ * The RDS specification can be found <a
+ * href="http://www.rds.org.uk/rds98/pdf/IEC%2062106-E_no%20print.pdf">here</a>
+ * </p>
+ * <a name="ErrorHandling"></a> <h3>Error handling</h3>
+ * <p>
+ * In general, it is up to the application that uses this API to keep track of
+ * events that could affect the FM radio user experience. The hardware
+ * implementation side of this API should only take actions when it is really
+ * necessary, e.g. if the hardware is forced to pause or reset, and notify the
+ * application by using the {@link OnForcedPauseListener},
+ * {@link OnForcedResetListener} or {@link OnErrorListener}.
+ * </p>
+ */
+public abstract class FmReceiver {
+
+ /**
+ * The FmReceiver had to be shut down due to a non-critical error, meaning
+ * that it is OK to attempt a restart immediately after this. For example,
+ * if the hardware was shut down in order to save power after being in the
+ * paused state for too long.
+ */
+ public static final int RESET_NON_CRITICAL = 0;
+
+ /**
+ * The FmReceiver had to be shut down due to a critical error. The FM
+ * hardware it not guaranteed to work as expected after receiving this
+ * error.
+ */
+ public static final int RESET_CRITICAL = 1;
+
+ /**
+ * The FmTransmitter was activated and therefore the FmReceiver must be put
+ * in idle.
+ *
+ * @see FmTransmitter#startAsync(FmBand)
+ */
+ public static final int RESET_TX_IN_USE = 2;
+
+ /**
+ * The radio is not allowed to be used, typically when flight mode is
+ * enabled.
+ */
+ public static final int RESET_RADIO_FORBIDDEN = 3;
+
+ /**
+ * Indicates that the FmReceiver is in an idle state. No resources are
+ * allocated and power consumption is kept to a minimum.
+ */
+ public static final int STATE_IDLE = 0;
+
+ /**
+ * Indicates that the FmReceiver is allocating resources and preparing to
+ * receive FM radio.
+ */
+ public static final int STATE_STARTING = 1;
+
+ /**
+ * Indicates that the FmReceiver is receiving FM radio. Note that the
+ * FmReceiver is considered to be started even if it is receiving noise or
+ * gets a signal with not good enough quality to consider a valid channel.
+ */
+ public static final int STATE_STARTED = 2;
+
+ /**
+ * Indicates that the FmReceiver has allocated resources and is ready to
+ * instantly receive FM radio.
+ */
+ public static final int STATE_PAUSED = 3;
+
+ /**
+ * Indicates that the FmReceiver is scanning. FM radio will not be received
+ * in this state.
+ */
+ public static final int STATE_SCANNING = 4;
+
+ /**
+ * Unknown signal strength.
+ */
+ public static final int SIGNAL_STRENGTH_UNKNOWN = -1;
+
+ /**
+ * The frequency switch occurred as a stronger alternate frequency was
+ * found.
+ */
+ public static final int SWITCH_AF = 0;
+
+ /**
+ * The frequency switch occurred as there is a traffic announcement
+ * in progress.
+ */
+ public static final int SWITCH_TA = 1;
+
+ /**
+ * The frequency switch occurred at the cessation of a traffic
+ * announcement.
+ */
+ public static final int SWITCH_TA_END = 2;
+
+ /**
+ * Scan direction down towards lower frequencies.
+ */
+ public static final int SCAN_DOWN = 0;
+
+ /**
+ * Scan direction up towards higher frequencies.
+ */
+ public static final int SCAN_UP = 1;
+
+ /**
+ * Returns true if the FM receiver API is supported by the system.
+ */
+ public static boolean isApiSupported(Context context) {
+ return context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_RADIO_FM_RECEIVER);
+ }
+
+ /**
+ * Starts reception of the FM hardware. This is an asynchronous method since
+ * different hardware can have varying startup times. When the reception is
+ * started a callback to {@link OnStartedListener#onStarted()} is made.
+ * <p>
+ * When calling this method, an FmBand parameter must be passed that
+ * describes the properties of the band that the FmReceiver should prepare
+ * for. If the band is null, invalid or not supported, an exception will be
+ * thrown.
+ * </p>
+ * <p>
+ * If the FmTransmitter is active it will be forced to reset. See
+ * {@link FmTransmitter#RESET_RX_IN_USE}.
+ * </p>
+ *
+ * @param band
+ * the band to use
+ * @throws IllegalArgumentException
+ * if the band is null
+ * @throws UnsupportedOperationException
+ * if the band is not supported by the hardware
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to start
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ * @see FmBand
+ */
+ public abstract void startAsync(FmBand band) throws IOException;
+
+ /**
+ * Starts reception of the FM hardware. This is a synchronous method and the
+ * method call will block until the hardware is started.
+ * <p>
+ * When calling this method, an FmBand parameter must be passed that
+ * describes the properties of the band that the FmReceiver should prepare
+ * for. If the band is null, invalid or not supported, an exception will be
+ * thrown.
+ * </p>
+ * <p>
+ * If the FmTransmitter is active it will be forced to reset. See
+ * {@link FmTransmitter#RESET_RX_IN_USE}.
+ * </p>
+ *
+ * @param band
+ * the band to use
+ * @throws IllegalArgumentException
+ * if the band is null
+ * @throws UnsupportedOperationException
+ * if the band is not supported by the hardware
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to start
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ * @see FmBand
+ */
+ public abstract void start(FmBand band) throws IOException;
+
+ /**
+ * Resumes FM reception.
+ * <p>
+ * Calling this method when the FmReceiver is in started state has no
+ * affect.
+ * </p>
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to resume
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void resume() throws IOException;
+
+ /**
+ * Pauses FM reception. No FM radio is received as long as the FmReceiver is
+ * paused. Call {@link #resume()} to resume reception. The hardware should
+ * be able to resume reception quickly from the paused state to give a good
+ * user experience.
+ * <p>
+ * Note that the hardware provider may choose to turn off the hardware after
+ * being paused a certain amount of time to save power. This will be
+ * reported in {@link OnForcedResetListener#onForcedReset(int)} with reason
+ * {@link #RESET_NON_CRITICAL} and the FmReceiver will be set to the idle
+ * state.
+ * </p>
+ * <p>
+ * Calling this method when the FmReceiver is in paused state has no affect.
+ * </p>
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to pause
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void pause() throws IOException;
+
+ /**
+ * Resets the FmReceiver to its idle state.
+ *
+ * @throws IOException
+ * if the FM hardware failed to reset
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void reset() throws IOException;
+
+ /**
+ * Returns the state of the FmReceiver.
+ *
+ * @return One of {@link #STATE_IDLE}, {@link #STATE_STARTING},
+ * {@link #STATE_STARTED}, {@link #STATE_PAUSED},
+ * {@link #STATE_SCANNING}
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract int getState();
+
+ /**
+ * Returns true if the hardware/implementation supports RDS data. If true
+ * the {@link OnRDSDataFoundListener} will work. If not it will never report
+ * any data.
+ * <p>
+ * The motivation for having this function is that an application can take
+ * this capability into account when laying out its UI.
+ * </p>
+ *
+ * @return true if RDS data is supported by the FmReceiver, false otherwise
+ *
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract boolean isRDSDataSupported();
+
+ /**
+ * Checks if the tuned frequency is considered to contain a channel.
+ *
+ * @return true if the FmReceiver is tuned to a valid channel
+ *
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract boolean isTunedToValidChannel();
+
+ /**
+ * Sets the threshold for the tuner. The threshold can be 0-1000. A low
+ * threshold indicates that the tuner will find stations with a weak signal
+ * and a high threshold will find stations with a strong signal.
+ * <p>
+ * This is used then calling {@link FmReceiver#scanUp()},
+ * {@link FmReceiver#scanDown()} or {@link FmReceiver#startFullScan()}.
+ * </p>
+ *
+ * @param threshold
+ * a value between 0-1000
+ * @throws IllegalArgumentException
+ * if the value is not between 0-1000
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to set threshold
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void setThreshold(int threshold) throws IOException;
+
+ /**
+ * Returns the threshold for the tuner.
+ *
+ * @return the threshold for the tuner
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to get the threshold
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract int getThreshold() throws IOException;
+
+ /**
+ * Returns the tuned frequency.
+ *
+ * @return the tuned frequency in kHz
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to get the frequency
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract int getFrequency() throws IOException;
+
+ /**
+ * Returns the signal strength of the tuned frequency. The signal strength
+ * is a value from 0 to 1000. A high value indicates a strong signal and a
+ * low value indicates a weak signal.
+ *
+ * @return the signal strength or {@link #SIGNAL_STRENGTH_UNKNOWN}
+ *
+ * @throws IOException
+ * if the FM hardware failed to get the signal strength
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract int getSignalStrength() throws IOException;
+
+ /**
+ * Checks if the tuned frequency is played in stereo. If
+ * {@link #setForceMono(boolean)} is set, this method will always return
+ * false.
+ *
+ * @return true if the tuned frequency is playing in stereo
+ *
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract boolean isPlayingInStereo();
+
+ /**
+ * Force the playback to always be in mono.
+ *
+ * @param forceMono
+ * if true, the hardware will only output mono audio. If false,
+ * stereo is allowed if supported by hardware and signal.
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void setForceMono(boolean forceMono);
+
+ /**
+ * Sets the automatic switching of the FmReceiver in the case of a stronger
+ * transmitter with the same Programme Identification (PI) presence. The
+ * application should register for callbacks using
+ * {@link #addOnAutomaticSwitchListener(OnAutomaticSwitchListener)}
+ * to receive a callback when channels are found. The reason stated in
+ * the callback will be {@link FmReceiver#SWITCH_AF}.
+ *
+ * @param automatic
+ * enable or disable automatic switching
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void setAutomaticAFSwitching(boolean automatic);
+
+ /**
+ * Sets the automatic switching of the program in case of the presence of
+ * traffic announcement in another program. The application should register
+ * for callbacks using {@link #addOnAutomaticSwitchListener(OnAutomaticSwitchListener)}
+ * to receive a callback when channels are found. The reason stated in
+ * the callback will be {@link FmReceiver#SWITCH_TA} when switching to
+ * traffic announcement and {@link FmReceiver#SWITCH_TA_END} when switching
+ * back after the announcement.
+ *
+ * @param automatic
+ * enable or disable automatic switching
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void setAutomaticTASwitching(boolean automatic);
+
+ /**
+ * Sets the frequency. Unlike {@link #scanUp()} and {@link #scanDown()},
+ * this method will directly jump to the specified frequency instead of
+ * trying to find a channel while scanning.
+ * <p>
+ * The frequency must be within the band that the FmReceiver prepared for.
+ * </p>
+ *
+ * @param frequency
+ * the frequency to tune to in kHz
+ * @throws IllegalArgumentException
+ * if the frequency is not supported
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to set frequency
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ * @see FmBand
+ */
+ public abstract void setFrequency(int frequency) throws IOException;
+
+ /**
+ * Starts a full scan. The tuner will scan the entire frequency band for
+ * channels. The application should register for callbacks using
+ * {@link #addOnScanListener(OnScanListener)} to receive a callback when
+ * channels are found.
+ * <p>
+ * If the application wants to stop the full scan, a call to
+ * {@link #stopScan()} should be made.
+ * </p>
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void startFullScan();
+
+ /**
+ * Starts seeking for a channel downwards in the frequency band from the
+ * currently tuned frequency. When a channel with enough signal strength is
+ * found the scanning will stop.
+ * <p>
+ * The seek will always stop if it reaches back to the frequency it started
+ * from, meaning that in the worst case scenario, when no channel can be
+ * found, the seek will run through one full cycle of the frequency band
+ * and stop at the frequency it started from.
+ * </p>
+ * The application should register for callbacks using
+ * {@link #addOnScanListener(OnScanListener)} to receive a callback when the
+ * scan is complete.
+ * <p>
+ * If the application wants to stop the scan, a call to {@link #stopScan()}
+ * should be made.
+ * </p>
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ * @see FmReceiver#scanUp()
+ */
+ public abstract void scanDown();
+
+ /**
+ * Same as {@link #scanDown()} but seeks upwards in the frequency band.
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ * @see FmReceiver#scanDown()
+ */
+ public abstract void scanUp();
+
+ /**
+ * Stops performing a scan operation. The hardware might continue the scan
+ * for an unspecified amount of time after this method is called. Once the
+ * scan has stopped, it will be notified via {@link OnScanListener}.
+ * <p>
+ * Note that this method has no affect if called in other states than the
+ * scanning state.
+ * </p>
+ *
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void stopScan();
+
+ /**
+ * This method can be used to send vendor specific commands. These commands
+ * must not follow any common design for all vendors, and information about
+ * the commands that a vendor implements is out of scope in this API.
+ * <p>
+ * However, one command must be supported by all vendors that implements
+ * vendor specific commands, the <i>vendor_information</i> command. In the
+ * Bundle parameter in
+ * {@link OnExtraCommandListener#onExtraCommand(String, Bundle)} the FM
+ * radio device name and version can be extracted according to the table
+ * below.
+ * </p>
+ * <table border="1">
+ * <tr>
+ * <th>key name</th>
+ * <th>value type</th>
+ * </tr>
+ * <tr>
+ * <td>device_name</td>
+ * <td>string</td>
+ * </tr>
+ * <tr>
+ * <td>device_version</td>
+ * <td>string</td>
+ * </tr>
+ * </table>
+ *
+ * @param command
+ * the command to send
+ * @param extras
+ * extra parameters to the command
+ * @return true if the command was accepted, otherwise false
+ *
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract boolean sendExtraCommand(String command, String[] extras);
+
+ /**
+ * Register a callback to be invoked when the FmReceiver is started.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnStartedListener(OnStartedListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmReceiver is started.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnStartedListener(OnStartedListener listener);
+
+ /**
+ * Register a callback to be invoked during a scan.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnScanListener(OnScanListener listener);
+
+ /**
+ * Unregister a callback to be invoked during a scan.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnScanListener(OnScanListener listener);
+
+ /**
+ * Register a callback to be invoked when RDS data is found. Having a
+ * listener registered for this might cause continuous callbacks, so it is
+ * considered good practice to set this listener to null whenever the
+ * application is not interested in these updates, e.g. when the application
+ * UI is not visible.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnRDSDataFoundListener(OnRDSDataFoundListener listener);
+
+ /**
+ * Unregister a callback to be invoked when RDS data is found.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnRDSDataFoundListener(OnRDSDataFoundListener listener);
+
+ /**
+ * Register a callback to be invoked when an error has happened during an
+ * asynchronous operation.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnErrorListener(OnErrorListener listener);
+
+ /**
+ * Unregister a callback to be invoked when an error has happened during an
+ * asynchronous operation.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnErrorListener(OnErrorListener listener);
+
+ /**
+ * Register a callback to be invoked when the signal strength of the
+ * currently tuned frequency changes. Having a listener registered to this
+ * method may cause frequent callbacks, hence it is good practice to only
+ * have a listener registered for this when necessary.
+ * <p>
+ * Example: If the application uses this information to visualize the signal
+ * strength on the UI, it should unregister the listener whenever the UI is
+ * not visible.
+ * </p>
+ * <p>
+ * The listener will only receive callbacks when the signal strength
+ * changes.
+ * </p>
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnSignalStrengthChangedListener(OnSignalStrengthChangedListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the signal strength of the
+ * currently tuned frequency changes.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnSignalStrengthChangedListener(OnSignalStrengthChangedListener listener);
+
+ /**
+ * Register a callback to be invoked when playback of the tuned frequency
+ * changes between mono and stereo. Having a listener registered to this
+ * method may cause frequent callbacks, hence it is good practice to only
+ * have a listener registered for this when necessary.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnPlayingInStereoListener(OnPlayingInStereoListener listener);
+
+ /**
+ * Unregister a callback to be invoked when playback of the tuned frequency
+ * changes between mono and stereo.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnPlayingInStereoListener(OnPlayingInStereoListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmReceiver is forced to pause
+ * due to external reasons.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnForcedPauseListener(OnForcedPauseListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmReceiver is forced to
+ * pause due to external reasons.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnForcedPauseListener(OnForcedPauseListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmReceiver is forced to reset
+ * due to external reasons.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnForcedResetListener(OnForcedResetListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmReceiver is forced to
+ * reset due to external reasons.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnForcedResetListener(OnForcedResetListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmReceiver changes state.
+ * Having a listener registered to this method may cause frequent callbacks,
+ * hence it is good practice to only have a listener registered for this
+ * when necessary.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnStateChangedListener(OnStateChangedListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmReceiver changes state.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnStateChangedListener(OnStateChangedListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmReceiver want's to invoke a
+ * vendor specific callback.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnExtraCommandListener(OnExtraCommandListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmReceiver want's to invoke
+ * a vendor specific callback.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnExtraCommandListener(OnExtraCommandListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmReceiver has triggered
+ * a changed frequency.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void addOnAutomaticSwitchListener(OnAutomaticSwitchListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmReceiver has triggered
+ * a changed frequency.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_RECEIVER permission is not present
+ */
+ public abstract void removeOnAutomaticSwitchListener(OnAutomaticSwitchListener listener);
+
+ /**
+ * Interface definition of a callback to be invoked when the FmReceiver is
+ * started.
+ */
+ public interface OnStartedListener {
+ /**
+ * Called when the FmReceiver is started. The FmReceiver is now
+ * receiving FM radio.
+ */
+ void onStarted();
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when a scan operation is
+ * complete.
+ */
+ public interface OnScanListener {
+ /**
+ * Called when the full scan is completed.
+ * <p>
+ * If the full scan is aborted with stopScan, this will be indicated
+ * with the aborted argument.
+ * <p>
+ * If an error occurs during a full scan, it will be reported via
+ * {@link OnErrorListener#onError()} and this method callback will not
+ * be invoked.
+ * </p>
+ *
+ * @param frequency
+ * the frequency in kHz where the channel was found
+ * @param signalStrength
+ * the signal strength, 0-1000
+ * @param aborted
+ * true if the full scan was aborted, false otherwise
+ */
+ void onFullScan(int[] frequency, int[] signalStrength, boolean aborted);
+
+ /**
+ * Called when {@link FmReceiver#scanDown()} or
+ * {@link FmReceiver#scanUp()} has successfully completed a scan
+ * operation. Note that failing to find a channel during a scan
+ * operation does not mean that it is an error, and it will still result
+ * in a call to this interface.
+ * <p>
+ * If the scan is aborted with stopScan, this will be indicated with the
+ * aborted argument.
+ * <p>
+ *
+ * @param tunedFrequency
+ * the current frequency in kHz of the tuner after the scan
+ * operation was completed
+ * @param signalStrength
+ * the signal strength, 0-1000
+ * @param scanDirection
+ * direction of scan, SCAN_DOWN or SCAN_UP
+ * @param aborted
+ * true if the scan was aborted, false otherwise
+ */
+ void onScan(int tunedFrequency, int signalStrength, int scanDirection, boolean aborted);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when RDS data has been
+ * found. Note that there is not necessarily a relation between the
+ * frequency that the RDS data is found at and the currently tuned
+ * frequency.
+ */
+ public interface OnRDSDataFoundListener {
+ /**
+ * Called when RDS data has been found or updated.
+ *
+ * @param rdsData
+ * the RDS data that was found
+ * @param frequency
+ * the frequency where the RDS data was found
+ */
+ void onRDSDataFound(Bundle rdsData, int frequency);
+ };
+
+ /**
+ * Interface definition of a callback to be invoked when there has been an
+ * error during an asynchronous operation.
+ */
+ public interface OnErrorListener {
+ /**
+ * Called to indicate an error.
+ */
+ void onError();
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the signal strength
+ * of the currently tuned frequency changes.
+ */
+ public interface OnSignalStrengthChangedListener {
+ /**
+ * Called to indicate that the signal strength has changed.
+ *
+ * @param signalStrength
+ * the signal strength, 0-1000
+ */
+ void onSignalStrengthChanged(int signalStrength);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when playback of the
+ * tuned frequency changes between mono and stereo. This is useful if the
+ * application wants to display some icon that shows if playing in stereo or
+ * not.
+ */
+ public interface OnPlayingInStereoListener {
+ /**
+ * Called when switching between mono and stereo.
+ *
+ * @param inStereo
+ * true if playback is in stereo, false if in mono
+ */
+ void onPlayingInStereo(boolean inStereo);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmReceiver was
+ * forced to pause due to external reasons.
+ */
+ public interface OnForcedPauseListener {
+ /**
+ * Called when an external reason caused the FmReceiver to pause. When
+ * this callback is received, the FmReceiver is still able to resume
+ * reception by calling {@link FmReceiver#resume()}.
+ */
+ void onForcedPause();
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmReceiver was
+ * forced to reset due to external reasons.
+ */
+ public interface OnForcedResetListener {
+ /**
+ * Called when an external reason caused the FmReceiver to reset. The
+ * application that uses the FmReceiver should take action according to
+ * the reason for resetting.
+ *
+ * @param reason
+ * reason why the FmReceiver reset:
+ * <ul>
+ * <li>{@link FmReceiver#RESET_NON_CRITICAL}
+ * <li>{@link FmReceiver#RESET_CRITICAL}
+ * <li>{@link FmReceiver#RESET_TX_IN_USE}
+ * <li>{@link FmReceiver#RESET_RADIO_FORBIDDEN}
+ * </ul>
+ */
+ void onForcedReset(int reason);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmReceiver
+ * changes state.
+ */
+ public interface OnStateChangedListener {
+ /**
+ * Called when the state is changed in the FmReceiver. This is useful if
+ * an application want's to monitor the FmReceiver state.
+ *
+ * @param oldState
+ * the old state of the FmReceiver
+ * @param newState
+ * the new state of the FmReceiver
+ */
+ void onStateChanged(int oldState, int newState);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmReceiver
+ * responds to a vendor specific command.
+ */
+ public interface OnExtraCommandListener {
+ /**
+ * Called when the FmReceiver responds to a vendor specific command.
+ *
+ * @param response
+ * the command the FmReceiver responds to
+ * @param extras
+ * extra parameters to the command
+ */
+ void onExtraCommand(String response, Bundle extras);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmReceiver
+ * changes frequency either due to AF switch or TA event.
+ */
+ public interface OnAutomaticSwitchListener {
+ /**
+ * Called when the FmReceiver changes frequency either due to AF
+ * switch or TA event.
+ *
+ * @param newFrequency
+ * the frequency switched to
+ * @param reason
+ * the reason for the switch:
+ * <ul>
+ * <li>{@link FmReceiver#SWITCH_AF}
+ * <li>{@link FmReceiver#SWITCH_TA}
+ * <li>{@link FmReceiver#SWITCH_TA_END}
+ * </ul>
+ */
+ void onAutomaticSwitch(int newFrequency, int reason);
+ }
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmReceiverImpl.java b/fmradio/java/com/stericsson/hardware/fm/FmReceiverImpl.java
new file mode 100644
index 0000000..da57bc0
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmReceiverImpl.java
@@ -0,0 +1,1126 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Bjorn Pileryd (bjorn.pileryd@sonyericsson.com)
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ * Author: Andreas Gustafsson (andreas.a.gustafsson@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * The implementation of the FmReceiver.
+ *
+ * @hide
+ */
+public class FmReceiverImpl extends FmReceiver {
+
+ private static final String TAG = "FmReceiver";
+
+ private IFmReceiver mService;
+
+ /**
+ * Save the FmBand used to be able to validate frequencies.
+ */
+ private FmBand mBand;
+
+ /**
+ * Map from OnStateChanged to their associated ListenerTransport objects.
+ */
+ private HashMap<OnStateChangedListener, OnStateChangedListenerTransport> mOnStateChanged =
+ new HashMap<OnStateChangedListener, OnStateChangedListenerTransport>();
+
+ /**
+ * Map from OnStarted to their associated ListenerTransport objects.
+ */
+ private HashMap<OnStartedListener, OnStartedListenerTransport> mOnStarted =
+ new HashMap<OnStartedListener, OnStartedListenerTransport>();
+
+ /**
+ * Map from OnError to their associated ListenerTransport objects.
+ */
+ private HashMap<OnErrorListener, OnErrorListenerTransport> mOnError =
+ new HashMap<OnErrorListener, OnErrorListenerTransport>();
+
+ /**
+ * Map from OnScan to their associated ListenerTransport objects.
+ */
+ private HashMap<OnScanListener, OnScanListenerTransport> mOnScan =
+ new HashMap<OnScanListener, OnScanListenerTransport>();
+
+ /**
+ * Map from OnForcedPause to their associated ListenerTransport objects.
+ */
+ private HashMap<OnForcedPauseListener, OnForcedPauseListenerTransport> mOnForcedPause =
+ new HashMap<OnForcedPauseListener, OnForcedPauseListenerTransport>();
+
+ /**
+ * Map from OnForcedReset to their associated ListenerTransport objects.
+ */
+ private HashMap<OnForcedResetListener, OnForcedResetListenerTransport> mOnForcedReset =
+ new HashMap<OnForcedResetListener, OnForcedResetListenerTransport>();
+
+ /**
+ * Map from OnRDSDataFound to their associated ListenerTransport objects.
+ */
+ private HashMap<OnRDSDataFoundListener, OnRDSDataListenerTransport> mOnRDSData =
+ new HashMap<OnRDSDataFoundListener, OnRDSDataListenerTransport>();
+
+ /**
+ * Map from OnSignalStrength to their associated ListenerTransport objects.
+ */
+ private HashMap<OnSignalStrengthChangedListener, OnSignalStrengthListenerTransport> mOnSignalStrength =
+ new HashMap<OnSignalStrengthChangedListener, OnSignalStrengthListenerTransport>();
+
+ /**
+ * Map from OnStereo to their associated ListenerTransport objects.
+ */
+ private HashMap<OnPlayingInStereoListener, OnStereoListenerTransport> mOnStereo =
+ new HashMap<OnPlayingInStereoListener, OnStereoListenerTransport>();
+
+ /**
+ * Map from OnExtraCommand to their associated ListenerTransport objects.
+ */
+ private HashMap<OnExtraCommandListener, OnExtraCommandListenerTransport> mOnExtraCommand =
+ new HashMap<OnExtraCommandListener, OnExtraCommandListenerTransport>();
+
+ /**
+ * Map from OnAutomaticSwitch to their associated ListenerTransport objects.
+ */
+ private HashMap<OnAutomaticSwitchListener, OnAutomaticSwitchListenerTransport> mOnAutomaticSwitch =
+ new HashMap<OnAutomaticSwitchListener, OnAutomaticSwitchListenerTransport>();
+
+ private static class OnStateChangedListenerTransport extends IOnStateChangedListener.Stub {
+ private static final int TYPE_ON_STATE_CHANGED = 1;
+
+ private OnStateChangedListener mListener;
+ private final Handler mListenerHandler;
+
+ OnStateChangedListenerTransport(OnStateChangedListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+
+ public void onStateChanged(int oldState, int newState) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_STATE_CHANGED;
+ Bundle b = new Bundle();
+ b.putInt("oldState", oldState);
+ b.putInt("newState", newState);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_STATE_CHANGED:
+ Bundle b = (Bundle) msg.obj;
+ int oldState = b.getInt("oldState");
+ int newState = b.getInt("newState");
+ mListener.onStateChanged(oldState, newState);
+ break;
+ }
+ }
+ }
+
+ private static class OnStartedListenerTransport extends IOnStartedListener.Stub {
+ private static final int TYPE_ON_STARTED = 1;
+
+ private OnStartedListener mListener;
+ private final Handler mListenerHandler;
+
+ OnStartedListenerTransport(OnStartedListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onStarted() {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_STARTED;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_STARTED:
+ mListener.onStarted();
+ break;
+ }
+ }
+ }
+
+ private static class OnErrorListenerTransport extends IOnErrorListener.Stub {
+ private static final int TYPE_ON_ERROR = 1;
+
+ private OnErrorListener mListener;
+ private final Handler mListenerHandler;
+
+ OnErrorListenerTransport(OnErrorListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onError() {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_ERROR;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_ERROR:
+ mListener.onError();
+ break;
+ }
+ }
+ }
+
+ private static class OnScanListenerTransport extends IOnScanListener.Stub {
+ private static final int TYPE_ON_SCAN = 1;
+ private static final int TYPE_ON_FULLSCAN = 2;
+
+ private OnScanListener mListener;
+ private final Handler mListenerHandler;
+
+ OnScanListenerTransport(OnScanListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onScan(int tunedFrequency, int signalStrength,
+ int scanDirection, boolean aborted) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_SCAN;
+ Bundle b = new Bundle();
+ b.putInt("tunedFrequency", tunedFrequency);
+ b.putInt("signalStrength", signalStrength);
+ b.putInt("scanDirection", scanDirection);
+ b.putBoolean("aborted", aborted);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ public void onFullScan(int[] frequency, int[] signalStrength, boolean aborted) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_FULLSCAN;
+ Bundle b = new Bundle();
+ b.putIntArray("frequency", frequency);
+ b.putIntArray("signalStrength", signalStrength);
+ b.putBoolean("aborted", aborted);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ Bundle b;
+ boolean aborted;
+
+ switch (msg.what) {
+ case TYPE_ON_SCAN:
+ b = (Bundle) msg.obj;
+ int tunedFrequency = b.getInt("tunedFrequency");
+ int signalStrength = b.getInt("signalStrength");
+ int scanDirection = b.getInt("scanDirection");
+ aborted = b.getBoolean("aborted");
+ mListener.onScan(tunedFrequency, signalStrength, scanDirection, aborted);
+ break;
+ case TYPE_ON_FULLSCAN:
+ b = (Bundle) msg.obj;
+ int[] frequency = b.getIntArray("frequency");
+ int[] signalStrengths = b.getIntArray("signalStrength");
+ aborted = b.getBoolean("aborted");
+ mListener.onFullScan(frequency, signalStrengths, aborted);
+ break;
+ }
+ }
+ }
+
+ private static class OnForcedPauseListenerTransport extends IOnForcedPauseListener.Stub {
+ private static final int TYPE_ON_FORCEDPAUSE = 1;
+
+ private OnForcedPauseListener mListener;
+ private final Handler mListenerHandler;
+
+ OnForcedPauseListenerTransport(OnForcedPauseListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onForcedPause() {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_FORCEDPAUSE;
+ Bundle b = new Bundle();
+ // Need more here? Or remove?
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_FORCEDPAUSE:
+ Bundle b = (Bundle) msg.obj;
+ mListener.onForcedPause();
+ break;
+ }
+ }
+ }
+
+ private static class OnForcedResetListenerTransport extends IOnForcedResetListener.Stub {
+ private static final int TYPE_ON_FORCEDRESET = 1;
+
+ private OnForcedResetListener mListener;
+ private final Handler mListenerHandler;
+
+ OnForcedResetListenerTransport(OnForcedResetListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onForcedReset(int reason) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_FORCEDRESET;
+ Bundle b = new Bundle();
+ b.putInt("reason", reason);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_FORCEDRESET:
+ Bundle b = (Bundle) msg.obj;
+ int reason = b.getInt("reason");
+ mListener.onForcedReset(reason);
+ break;
+ }
+ }
+ }
+
+ private static class OnRDSDataListenerTransport extends IOnRDSDataFoundListener.Stub {
+ private static final int TYPE_ON_RDS_DATA = 1;
+
+ private OnRDSDataFoundListener mListener;
+ private final Handler mListenerHandler;
+
+ OnRDSDataListenerTransport(OnRDSDataFoundListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onRDSDataFound(Bundle rdsData, int frequency) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_RDS_DATA;
+ Bundle b = new Bundle();
+ if (rdsData != null) {
+ b.putBundle("rdsData", rdsData);
+ }
+ b.putInt("frequency", frequency);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ Bundle b;
+
+ switch (msg.what) {
+ case TYPE_ON_RDS_DATA:
+ b = (Bundle) msg.obj;
+ int frequency = b.getInt("frequency");
+ Bundle rdsData = b.getBundle("rdsData");
+ mListener.onRDSDataFound(rdsData, frequency);
+ break;
+ }
+ }
+ }
+
+ private static class OnSignalStrengthListenerTransport extends IOnSignalStrengthListener.Stub {
+ private static final int TYPE_ON_SIGNAL_STRENGTH_CHANGED = 1;
+
+ private OnSignalStrengthChangedListener mListener;
+ private final Handler mListenerHandler;
+
+ OnSignalStrengthListenerTransport(OnSignalStrengthChangedListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onSignalStrengthChanged(int signalStrength) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_SIGNAL_STRENGTH_CHANGED;
+ Bundle b = new Bundle();
+ b.putInt("signalStrength", signalStrength);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ Bundle b;
+ boolean aborted;
+
+ switch (msg.what) {
+ case TYPE_ON_SIGNAL_STRENGTH_CHANGED:
+ b = (Bundle) msg.obj;
+ int signalStrength = b.getInt("signalStrength");
+ mListener.onSignalStrengthChanged(signalStrength);
+ break;
+ }
+ }
+ }
+
+ private static class OnStereoListenerTransport extends IOnStereoListener.Stub {
+ private static final int TYPE_ON_STEREO = 1;
+
+ private OnPlayingInStereoListener mListener;
+ private final Handler mListenerHandler;
+
+ OnStereoListenerTransport(OnPlayingInStereoListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onPlayingInStereo(boolean inStereo) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_STEREO;
+ Bundle b = new Bundle();
+ b.putBoolean("inStereo", inStereo);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ Bundle b;
+ boolean aborted;
+
+ switch (msg.what) {
+ case TYPE_ON_STEREO:
+ b = (Bundle) msg.obj;
+ boolean inStereo = b.getBoolean("inStereo");
+ mListener.onPlayingInStereo(inStereo);
+ break;
+ }
+ }
+ }
+
+ private static class OnExtraCommandListenerTransport extends IOnExtraCommandListener.Stub {
+ private static final int TYPE_ON_EXTRA_COMMAND = 1;
+
+ private OnExtraCommandListener mListener;
+ private final Handler mListenerHandler;
+
+ OnExtraCommandListenerTransport(OnExtraCommandListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onExtraCommand(String response, Bundle extras) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_EXTRA_COMMAND;
+ Bundle b = new Bundle();
+ b.putString("response", response);
+ b.putBundle("extras", extras);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ Bundle b;
+ boolean aborted;
+
+ switch (msg.what) {
+ case TYPE_ON_EXTRA_COMMAND:
+ b = (Bundle) msg.obj;
+ String response = b.getString("response");
+ Bundle extras = b.getBundle("extras");
+ mListener.onExtraCommand(response, extras);
+ break;
+ }
+ }
+ }
+
+ private static class OnAutomaticSwitchListenerTransport extends IOnAutomaticSwitchListener.Stub {
+ private static final int TYPE_ON_AUTOMATIC_SWITCH = 1;
+
+ private OnAutomaticSwitchListener mListener;
+ private final Handler mListenerHandler;
+
+ OnAutomaticSwitchListenerTransport(OnAutomaticSwitchListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onAutomaticSwitch(int newFrequency, int reason) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_AUTOMATIC_SWITCH;
+ Bundle b = new Bundle();
+ b.putInt("newFrequency", newFrequency);
+ b.putInt("reason", reason);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ Bundle b;
+ boolean aborted;
+
+ switch (msg.what) {
+ case TYPE_ON_AUTOMATIC_SWITCH:
+ b = (Bundle) msg.obj;
+ int newFrequency = b.getInt("newFrequency");
+ int reason = b.getInt("reason");
+ mListener.onAutomaticSwitch(newFrequency, reason);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Creates a new FmReceiver instance. Applications will almost always want
+ * to use {@link android.content.Context#getSystemService
+ * Context.getSystemService()} to retrieve the standard
+ * {@link android.content.Context "fm_receiver"}.
+ *
+ * @param service
+ * the Binder interface
+ * @hide - hide this because it takes in a parameter of type IFmReceiver,
+ * which is a system private class.
+ */
+ public FmReceiverImpl(IFmReceiver service) {
+ mService = service;
+ }
+
+ @Override
+ public void startAsync(FmBand band) throws IOException {
+ if (band == null) {
+ throw new IllegalArgumentException("Band cannot be null");
+ }
+ try {
+ mService.startAsync(band);
+ mBand = band;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "startAsync: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void start(FmBand band) throws IOException {
+ if (band == null) {
+ throw new IllegalArgumentException("Band cannot be null");
+ }
+ try {
+ mService.start(band);
+ mBand = band;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "start: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void resume() throws IOException {
+ try {
+ mService.resume();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "resume: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void pause() throws IOException {
+ try {
+ mService.pause();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "pause: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void reset() throws IOException {
+ try {
+ mService.reset();
+ mBand = null;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "reset: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public int getState() {
+ try {
+ return mService.getState();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getState: RemoteException", ex);
+ return STATE_IDLE;
+ }
+ }
+
+ @Override
+ public boolean isRDSDataSupported() {
+ try {
+ return mService.isRDSDataSupported();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "isRDSDataSupported: RemoteException", ex);
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isTunedToValidChannel() {
+ try {
+ return mService.isTunedToValidChannel();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "isTunedToValidChannel: RemoteException", ex);
+ return false;
+ }
+ }
+
+ @Override
+ public void setThreshold(int threshold) throws IOException {
+ if (threshold < 0 || threshold > 1000) {
+ throw new IllegalArgumentException("threshold not within limits");
+ }
+ try {
+ mService.setThreshold(threshold);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "setThreshold: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public int getThreshold() throws IOException {
+ try {
+ return mService.getThreshold();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getThreshold: RemoteException", ex);
+ return 0;
+ }
+ }
+
+ @Override
+ public int getFrequency() throws IOException {
+ try {
+ return mService.getFrequency();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getFrequency: RemoteException", ex);
+ return FmBand.FM_FREQUENCY_UNKNOWN;
+ }
+ }
+
+ @Override
+ public int getSignalStrength() throws IOException {
+ try {
+ return mService.getSignalStrength();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getSignalStrength: RemoteException", ex);
+ return SIGNAL_STRENGTH_UNKNOWN;
+ }
+ }
+
+ @Override
+ public boolean isPlayingInStereo() {
+ try {
+ return mService.isPlayingInStereo();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "isPlayingInStereo: RemoteException", ex);
+ return false;
+ }
+ }
+
+ @Override
+ public void setForceMono(boolean forceMono) {
+ try {
+ mService.setForceMono(forceMono);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "setForceMono: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void setAutomaticAFSwitching(boolean automatic) {
+ try {
+ mService.setAutomaticAFSwitching(automatic);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "setAutomaticAFSwitching: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void setAutomaticTASwitching(boolean automatic) {
+ try {
+ mService.setAutomaticTASwitching(automatic);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "setAutomaticTASwitching: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void setFrequency(int frequency) throws IOException {
+ if (mBand != null && !mBand.isFrequencyValid(frequency)) {
+ throw new IllegalArgumentException("Frequency is not valid in this band.");
+ }
+
+ try {
+ mService.setFrequency(frequency);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "setFrequency: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void startFullScan() {
+ try {
+ mService.startFullScan();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "startFullScan: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void scanDown() {
+ try {
+ mService.scanDown();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "scanDown: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void scanUp() {
+ try {
+ mService.scanUp();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "scanUp: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void stopScan() {
+ try {
+ mService.stopScan();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "stopScan: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public boolean sendExtraCommand(String command, String[] extras) {
+ try {
+ return mService.sendExtraCommand(command, extras);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "sendExtraCommand: RemoteException", ex);
+ return false;
+ }
+ }
+
+ @Override
+ public void addOnStartedListener(OnStartedListener listener) {
+ if (mOnStarted.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnStarted) {
+ OnStartedListenerTransport transport = new OnStartedListenerTransport(listener);
+ mService.addOnStartedListener(transport);
+ mOnStarted.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnStartedListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnStartedListener(OnStartedListener listener) {
+ try {
+ OnStartedListenerTransport transport = mOnStarted.remove(listener);
+ if (transport != null) {
+ mService.removeOnStartedListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnStartedListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnScanListener(OnScanListener listener) {
+ if (mOnScan.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnScan) {
+ OnScanListenerTransport transport = new OnScanListenerTransport(listener);
+ mService.addOnScanListener(transport);
+ mOnScan.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnScanListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnScanListener(OnScanListener listener) {
+ try {
+ OnScanListenerTransport transport = mOnScan.remove(listener);
+ if (transport != null) {
+ mService.removeOnScanListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnScanListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnRDSDataFoundListener(OnRDSDataFoundListener listener) {
+ if (mOnRDSData.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnRDSData) {
+ OnRDSDataListenerTransport transport = new OnRDSDataListenerTransport(listener);
+ mService.addOnRDSDataFoundListener(transport);
+ mOnRDSData.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnRDSDataFoundListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnRDSDataFoundListener(OnRDSDataFoundListener listener) {
+ try {
+ OnRDSDataListenerTransport transport = mOnRDSData.remove(listener);
+ if (transport != null) {
+ mService.removeOnRDSDataFoundListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnRDSDataFoundListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnErrorListener(OnErrorListener listener) {
+ if (mOnError.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnError) {
+ OnErrorListenerTransport transport = new OnErrorListenerTransport(listener);
+ mService.addOnErrorListener(transport);
+ mOnError.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnErrorListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnErrorListener(OnErrorListener listener) {
+ try {
+ OnErrorListenerTransport transport = mOnError.remove(listener);
+ if (transport != null) {
+ mService.removeOnErrorListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnErrorListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnSignalStrengthChangedListener(OnSignalStrengthChangedListener listener) {
+ if (mOnSignalStrength.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnSignalStrength) {
+ OnSignalStrengthListenerTransport transport = new OnSignalStrengthListenerTransport(
+ listener);
+ mService.addOnSignalStrengthChangedListener(transport);
+ mOnSignalStrength.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnSignalStrengthChangedListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnSignalStrengthChangedListener(OnSignalStrengthChangedListener listener) {
+ try {
+ OnSignalStrengthListenerTransport transport = mOnSignalStrength.remove(listener);
+ if (transport != null) {
+ mService.removeOnSignalStrengthChangedListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnSignalStrengthChangedListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnPlayingInStereoListener(OnPlayingInStereoListener listener) {
+ if (mOnStereo.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnStereo) {
+ OnStereoListenerTransport transport = new OnStereoListenerTransport(listener);
+ mService.addOnPlayingInStereoListener(transport);
+ mOnStereo.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnPlayingInStereoListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnPlayingInStereoListener(OnPlayingInStereoListener listener) {
+ try {
+ OnStereoListenerTransport transport = mOnStereo.remove(listener);
+ if (transport != null) {
+ mService.removeOnPlayingInStereoListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnPlayingInStereoListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnForcedPauseListener(OnForcedPauseListener listener) {
+ if (mOnForcedPause.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnForcedPause) {
+ OnForcedPauseListenerTransport transport = new OnForcedPauseListenerTransport(
+ listener);
+ mService.addOnForcedPauseListener(transport);
+ mOnForcedPause.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnForcedPauseListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnForcedPauseListener(OnForcedPauseListener listener) {
+ try {
+ OnForcedPauseListenerTransport transport = mOnForcedPause.remove(listener);
+ if (transport != null) {
+ mService.removeOnForcedPauseListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnForcedPauseListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnForcedResetListener(OnForcedResetListener listener) {
+ if (mOnForcedReset.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnForcedReset) {
+ OnForcedResetListenerTransport transport = new OnForcedResetListenerTransport(
+ listener);
+ mService.addOnForcedResetListener(transport);
+ mOnForcedReset.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnForcedResetListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnForcedResetListener(OnForcedResetListener listener) {
+ try {
+ OnForcedResetListenerTransport transport = mOnForcedReset.remove(listener);
+ if (transport != null) {
+ mService.removeOnForcedResetListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnForcedResetListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnStateChangedListener(OnStateChangedListener listener) {
+ if (mOnStateChanged.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnStateChanged) {
+ OnStateChangedListenerTransport transport = new OnStateChangedListenerTransport(
+ listener);
+ mService.addOnStateChangedListener(transport);
+ mOnStateChanged.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnStateChangedListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnStateChangedListener(OnStateChangedListener listener) {
+ try {
+ OnStateChangedListenerTransport transport = mOnStateChanged.remove(listener);
+ if (transport != null) {
+ mService.removeOnStateChangedListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnStateChangedListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnExtraCommandListener(OnExtraCommandListener listener) {
+ if (mOnExtraCommand.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnExtraCommand) {
+ OnExtraCommandListenerTransport transport = new OnExtraCommandListenerTransport(
+ listener);
+ mService.addOnExtraCommandListener(transport);
+ mOnExtraCommand.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnExtraCommandListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnExtraCommandListener(OnExtraCommandListener listener) {
+ try {
+ OnExtraCommandListenerTransport transport = mOnExtraCommand.remove(listener);
+ if (transport != null) {
+ mService.removeOnExtraCommandListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnExtraCommandListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnAutomaticSwitchListener(OnAutomaticSwitchListener listener) {
+ if (mOnAutomaticSwitch.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnAutomaticSwitch) {
+ OnAutomaticSwitchListenerTransport transport = new OnAutomaticSwitchListenerTransport(listener);
+ mService.addOnAutomaticSwitchListener(transport);
+ mOnAutomaticSwitch.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnAutomaticSwitchListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnAutomaticSwitchListener(OnAutomaticSwitchListener listener) {
+ try {
+ OnAutomaticSwitchListenerTransport transport = mOnAutomaticSwitch.remove(listener);
+ if (transport != null) {
+ mService.removeOnAutomaticSwitchListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnAutomaticSwitchListener: DeadObjectException", ex);
+ }
+ }
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmReceiverService.java b/fmradio/java/com/stericsson/hardware/fm/FmReceiverService.java
new file mode 100644
index 0000000..b002cb1
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmReceiverService.java
@@ -0,0 +1,1347 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * The implementation of the FM receiver service.
+ *
+ * @hide
+ */
+public class FmReceiverService extends IFmReceiver.Stub {
+
+ private static final String TAG = "FmReceiverService";
+
+ private Context mContext;
+
+ private final HashMap<Object, OnStateChangedReceiver> mOnStateChangedReceivers =
+ new HashMap<Object, OnStateChangedReceiver>();
+
+ private final HashMap<Object, OnStartedReceiver> mOnStartedReceivers =
+ new HashMap<Object, OnStartedReceiver>();
+
+ private final HashMap<Object, OnErrorReceiver> mOnErrorReceivers =
+ new HashMap<Object, OnErrorReceiver>();
+
+ private final HashMap<Object, OnScanReceiver> mOnScanReceivers =
+ new HashMap<Object, OnScanReceiver>();
+
+ private final HashMap<Object, OnForcedPauseReceiver> mOnForcedPauseReceivers =
+ new HashMap<Object, OnForcedPauseReceiver>();
+
+ private final HashMap<Object, OnForcedResetReceiver> mOnForcedResetReceivers =
+ new HashMap<Object, OnForcedResetReceiver>();
+
+ private final HashMap<Object, OnRDSDataReceiver> mOnRDSDataReceivers =
+ new HashMap<Object, OnRDSDataReceiver>();
+
+ private final HashMap<Object, OnSignalStrengthReceiver> mOnSignalStrengthReceivers =
+ new HashMap<Object, OnSignalStrengthReceiver>();
+
+ private final HashMap<Object, OnStereoReceiver> mOnStereoReceivers =
+ new HashMap<Object, OnStereoReceiver>();
+
+ private final HashMap<Object, OnExtraCommandReceiver> mOnExtraCommandReceivers =
+ new HashMap<Object, OnExtraCommandReceiver>();
+
+ private final HashMap<Object, OnAutomaticSwitchReceiver> mOnAutomaticSwitchReceivers =
+ new HashMap<Object, OnAutomaticSwitchReceiver>();
+
+ private final class OnStateChangedReceiver implements IBinder.DeathRecipient {
+ final IOnStateChangedListener mListener;
+
+ final Object mKey;
+
+ OnStateChangedReceiver(IOnStateChangedListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnStateChangedListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnStateChanged(int oldState, int newState) {
+ try {
+ synchronized (this) {
+ mListener.onStateChanged(oldState, newState);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnStateChanged: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnStateChangedReceivers) {
+ mOnStateChangedReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnStartedReceiver implements IBinder.DeathRecipient {
+ final IOnStartedListener mListener;
+
+ final Object mKey;
+
+ OnStartedReceiver(IOnStartedListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnStartedListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnStarted() {
+ try {
+ synchronized (this) {
+ mListener.onStarted();
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnStarted: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnStartedReceivers) {
+ mOnStartedReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnErrorReceiver implements IBinder.DeathRecipient {
+ final IOnErrorListener mListener;
+
+ final Object mKey;
+
+ OnErrorReceiver(IOnErrorListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnErrorListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnError() {
+ try {
+ synchronized (this) {
+ mListener.onError();
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnError: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnErrorReceivers) {
+ mOnErrorReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnScanReceiver implements IBinder.DeathRecipient {
+ final IOnScanListener mListener;
+
+ final Object mKey;
+
+ OnScanReceiver(IOnScanListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnScanListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnScan(int tunedFrequency, int signalLevel, int scanDirection, boolean aborted) {
+ try {
+ synchronized (this) {
+ mListener.onScan(tunedFrequency, signalLevel, scanDirection, aborted);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnScan: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public boolean callOnFullScan(int[] frequency, int[] signalLevel, boolean aborted) {
+ try {
+ synchronized (this) {
+ mListener.onFullScan(frequency, signalLevel, aborted);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnFullScan: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnScanReceivers) {
+ mOnScanReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnForcedPauseReceiver implements IBinder.DeathRecipient {
+ final IOnForcedPauseListener mListener;
+
+ final Object mKey;
+
+ OnForcedPauseReceiver(IOnForcedPauseListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnForcedPauseListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnForcedPause() {
+ try {
+ synchronized (this) {
+ mListener.onForcedPause();
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnForcedPause: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnForcedPauseReceivers) {
+ mOnForcedPauseReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnForcedResetReceiver implements IBinder.DeathRecipient {
+ final IOnForcedResetListener mListener;
+
+ final Object mKey;
+
+ OnForcedResetReceiver(IOnForcedResetListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnForcedResetListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnForcedReset(int reason) {
+ try {
+ synchronized (this) {
+ mListener.onForcedReset(reason);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnForcedReset: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnForcedResetReceivers) {
+ mOnForcedResetReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnRDSDataReceiver implements IBinder.DeathRecipient {
+ final IOnRDSDataFoundListener mListener;
+
+ final Object mKey;
+
+ OnRDSDataReceiver(IOnRDSDataFoundListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnRDSDataFoundListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnRDSDataFound(Bundle bundle, int frequency) {
+ try {
+ synchronized (this) {
+ mListener.onRDSDataFound(bundle, frequency);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnRDSDataFound: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnRDSDataReceivers) {
+ mOnRDSDataReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnSignalStrengthReceiver implements IBinder.DeathRecipient {
+ final IOnSignalStrengthListener mListener;
+
+ final Object mKey;
+
+ OnSignalStrengthReceiver(IOnSignalStrengthListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnSignalStrengthListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnSignalStrengthChanged(int signalStrength) {
+ try {
+ synchronized (this) {
+ mListener.onSignalStrengthChanged(signalStrength);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnSignalStrengthChanged: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnSignalStrengthReceivers) {
+ mOnSignalStrengthReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnStereoReceiver implements IBinder.DeathRecipient {
+ final IOnStereoListener mListener;
+
+ final Object mKey;
+
+ OnStereoReceiver(IOnStereoListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnStereoListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnPlayingInStereo(boolean inStereo) {
+ try {
+ synchronized (this) {
+ mListener.onPlayingInStereo(inStereo);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnPlayingInStereo: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnStereoReceivers) {
+ mOnStereoReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnExtraCommandReceiver implements IBinder.DeathRecipient {
+ final IOnExtraCommandListener mListener;
+
+ final Object mKey;
+
+ OnExtraCommandReceiver(IOnExtraCommandListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnExtraCommandListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnExtraCommand(String response, Bundle extras) {
+ try {
+ synchronized (this) {
+ mListener.onExtraCommand(response, extras);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnExtraCommand: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnExtraCommandReceivers) {
+ mOnExtraCommandReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnAutomaticSwitchReceiver implements IBinder.DeathRecipient {
+ final IOnAutomaticSwitchListener mListener;
+
+ final Object mKey;
+
+ OnAutomaticSwitchReceiver(IOnAutomaticSwitchListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnAutomaticSwitchListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnAutomaticSwitch(int newFrequency, int reason) {
+ try {
+ synchronized (this) {
+ mListener.onAutomaticSwitch(newFrequency, reason);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnAutomaticSwitch: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnAutomaticSwitchReceivers) {
+ mOnAutomaticSwitchReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
+ Log.d(TAG, "onReceive:ACTION_AIRPLANE_MODE_CHANGED");
+
+ // check that airplane mode is off
+ if (!isAirplaneModeOn()) {
+ return;
+ }
+
+ // power down hardware
+ if (_fm_receiver_reset() > FmReceiver.STATE_IDLE) {
+ notifyOnForcedReset(FmReceiver.RESET_RADIO_FORBIDDEN);
+ }
+ }
+ }
+
+ };
+
+ /* Returns true if airplane mode is currently on */
+ private boolean isAirplaneModeOn() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ }
+
+ public FmReceiverService(Context context) {
+ Log.i(TAG, "FmReceiverService created");
+ mContext = context;
+
+ // Register for airplane mode
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ filter.addAction(Intent.ACTION_DOCK_EVENT);
+
+ mContext.registerReceiver(mReceiver, filter);
+
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ }
+
+ public void start(FmBand band) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_start(band.getMinFrequency(), band.getMaxFrequency(), band
+ .getDefaultFrequency(), band.getChannelOffset());
+
+ if (mOnRDSDataReceivers.size() > 0) {
+ Log.d(TAG, "Started with RDS receiver(s), switching on RDS");
+ _fm_receiver_setRDS(true);
+ }
+ }
+
+ public void startAsync(FmBand band) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_startAsync(band.getMinFrequency(), band.getMaxFrequency(), band
+ .getDefaultFrequency(), band.getChannelOffset());
+ }
+
+ public void reset() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_reset();
+ }
+
+ public void pause() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_pause();
+ }
+
+ public void resume() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_resume();
+ }
+
+ public int getState() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_getState();
+ }
+
+ public void setFrequency(int frequency) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_setFrequency(frequency);
+ }
+
+ public int getFrequency() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_getFrequency();
+ }
+
+ public void scanUp() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_scanUp();
+ }
+
+ public void scanDown() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_scanDown();
+ }
+
+ public void startFullScan() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_startFullScan();
+ }
+
+ public void stopScan() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_stopScan();
+ }
+
+ public boolean isRDSDataSupported() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_isRDSDataSupported();
+ }
+
+ public boolean isTunedToValidChannel() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_isTunedToValidChannel();
+ }
+
+ public void setThreshold(int threshold) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_setThreshold(threshold);
+ }
+
+ public int getThreshold() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_getThreshold();
+ }
+
+ public int getSignalStrength() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_getSignalStrength();
+ }
+
+ public boolean isPlayingInStereo() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_isPlayingInStereo();
+ }
+
+ public void setForceMono(boolean forceMono) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_setForceMono(forceMono);
+ }
+
+ public void setAutomaticAFSwitching(boolean automatic) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_setAutomaticAFSwitching(automatic);
+ }
+
+ public void setAutomaticTASwitching(boolean automatic) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ _fm_receiver_setAutomaticTASwitching(automatic);
+ }
+
+ public boolean sendExtraCommand(String command, String[] extras) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ return _fm_receiver_sendExtraCommand(command, extras);
+ }
+
+ public void addOnStateChangedListener(IOnStateChangedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStateChangedReceiver receiver = mOnStateChangedReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnStateChangedReceiver(listener);
+ mOnStateChangedReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnStateChangedListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnStateChangedListener(IOnStateChangedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStateChangedReceiver receiver = mOnStateChangedReceivers.get(binder);
+ if (receiver != null) {
+ mOnStateChangedReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnStateChangedListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnStartedListener(IOnStartedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStartedReceiver receiver = mOnStartedReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnStartedReceiver(listener);
+ mOnStartedReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnStartedListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnStartedListener(IOnStartedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStartedReceiver receiver = mOnStartedReceivers.get(binder);
+ if (receiver != null) {
+ mOnStartedReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnStartedListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnErrorListener(IOnErrorListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnErrorReceiver receiver = mOnErrorReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnErrorReceiver(listener);
+ mOnErrorReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnErrorListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnErrorListener(IOnErrorListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnErrorReceiver receiver = mOnErrorReceivers.get(binder);
+ if (receiver != null) {
+ mOnErrorReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnErrorListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnScanListener(IOnScanListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnScanReceiver receiver = mOnScanReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnScanReceiver(listener);
+ mOnScanReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnScanListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnScanListener(IOnScanListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnScanReceiver receiver = mOnScanReceivers.get(binder);
+ if (receiver != null) {
+ mOnScanReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnScanListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnForcedPauseListener(IOnForcedPauseListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedPauseReceiver receiver = mOnForcedPauseReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnForcedPauseReceiver(listener);
+ mOnForcedPauseReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnForcedPauseListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnForcedPauseListener(IOnForcedPauseListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedPauseReceiver receiver = mOnForcedPauseReceivers.get(binder);
+ if (receiver != null) {
+ mOnForcedPauseReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnForcedPauseListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnForcedResetListener(IOnForcedResetListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedResetReceiver receiver = mOnForcedResetReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnForcedResetReceiver(listener);
+ mOnForcedResetReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnForcedResetListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnForcedResetListener(IOnForcedResetListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedResetReceiver receiver = mOnForcedResetReceivers.get(binder);
+ if (receiver != null) {
+ mOnForcedResetReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnForcedResetListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnRDSDataFoundListener(IOnRDSDataFoundListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnRDSDataReceiver receiver = mOnRDSDataReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnRDSDataReceiver(listener);
+ mOnRDSDataReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnRDSDataFoundListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ if ((getState() >= FmReceiver.STATE_STARTED) &&
+ (mOnRDSDataReceivers.size() == 1)) {
+ Log.d(TAG, "First RDS receiver added, switching on RDS");
+ _fm_receiver_setRDS(true);
+ }
+ }
+ }
+
+ public void removeOnRDSDataFoundListener(IOnRDSDataFoundListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnRDSDataReceiver receiver = mOnRDSDataReceivers.get(binder);
+ if (receiver != null) {
+ mOnRDSDataReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnRDSDataFoundListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ if ((getState() >= FmReceiver.STATE_STARTED) &&
+ mOnRDSDataReceivers.isEmpty()) {
+ Log.d(TAG, "Last RDS receiver removed, switching off RDS");
+ _fm_receiver_setRDS(false);
+ }
+ }
+ }
+
+ public void addOnSignalStrengthChangedListener(IOnSignalStrengthListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnSignalStrengthReceiver receiver = mOnSignalStrengthReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnSignalStrengthReceiver(listener);
+ mOnSignalStrengthReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnSignalStrengthChangedListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnSignalStrengthChangedListener(IOnSignalStrengthListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnSignalStrengthReceiver receiver = mOnSignalStrengthReceivers.get(binder);
+ if (receiver != null) {
+ mOnSignalStrengthReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnSignalStrengthChangedListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnPlayingInStereoListener(IOnStereoListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStereoReceiver receiver = mOnStereoReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnStereoReceiver(listener);
+ mOnStereoReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnPlayingInStereoListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnPlayingInStereoListener(IOnStereoListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStereoReceiver receiver = mOnStereoReceivers.get(binder);
+ if (receiver != null) {
+ mOnStereoReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnPlayingInStereoListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnExtraCommandListener(IOnExtraCommandListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnExtraCommandReceiver receiver = mOnExtraCommandReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnExtraCommandReceiver(listener);
+ mOnExtraCommandReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnExtraCommandListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnExtraCommandListener(IOnExtraCommandListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnExtraCommandReceiver receiver = mOnExtraCommandReceivers.get(binder);
+ if (receiver != null) {
+ mOnExtraCommandReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnExtraCommandListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnAutomaticSwitchListener(IOnAutomaticSwitchListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnAutomaticSwitchReceiver receiver = mOnAutomaticSwitchReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnAutomaticSwitchReceiver(listener);
+ mOnAutomaticSwitchReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnAutomaticSwitchListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnAutomaticSwitchListener(IOnAutomaticSwitchListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_RECEIVER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_RECEIVER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnAutomaticSwitchReceiver receiver = mOnAutomaticSwitchReceivers.get(binder);
+ if (receiver != null) {
+ mOnAutomaticSwitchReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnAutomaticSwitchListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ private void notifyOnStateChanged(int oldState, int newState) {
+ synchronized (mOnStateChangedReceivers) {
+ Collection c = mOnStateChangedReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnStateChangedReceiver m = (OnStateChangedReceiver) iterator.next();
+ m.callOnStateChanged(oldState, newState);
+ }
+ }
+ }
+
+ private void notifyOnStarted() {
+ synchronized (mOnStartedReceivers) {
+ Collection c = mOnStartedReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnStartedReceiver m = (OnStartedReceiver) iterator.next();
+ m.callOnStarted();
+ }
+
+ if (mOnRDSDataReceivers.size() > 0) {
+ Log.d(TAG, "Started event with RDS receiver(s), switching on RDS");
+ _fm_receiver_setRDS(true);
+ }
+ }
+ }
+
+ private void notifyOnScan(int frequency, int signalLevel, int scanDirection, boolean aborted) {
+ synchronized (mOnScanReceivers) {
+ Collection c = mOnScanReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnScanReceiver m = (OnScanReceiver) iterator.next();
+ m.callOnScan(frequency, signalLevel, scanDirection, aborted);
+ }
+ }
+ }
+
+ private void notifyOnFullScan(int[] frequency, int[] signalLevel, boolean aborted) {
+ synchronized (mOnScanReceivers) {
+ Collection c = mOnScanReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnScanReceiver m = (OnScanReceiver) iterator.next();
+ m.callOnFullScan(frequency, signalLevel, aborted);
+ }
+ }
+ }
+
+ private void notifyOnForcedPause() {
+ synchronized (mOnForcedPauseReceivers) {
+ Collection c = mOnForcedPauseReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnForcedPauseReceiver m = (OnForcedPauseReceiver) iterator.next();
+ m.callOnForcedPause();
+ }
+ }
+ }
+
+ private void notifyOnForcedReset(int reason) {
+ synchronized (mOnForcedResetReceivers) {
+ Collection c = mOnForcedResetReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnForcedResetReceiver m = (OnForcedResetReceiver) iterator.next();
+ m.callOnForcedReset(reason);
+ }
+ }
+ }
+
+ private void notifyOnError() {
+ synchronized (mOnErrorReceivers) {
+ Collection c = mOnErrorReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnErrorReceiver m = (OnErrorReceiver) iterator.next();
+ m.callOnError();
+ }
+ }
+ }
+
+ private void notifyOnRDSDataFound(Bundle bundle, int frequency) {
+ synchronized (mOnRDSDataReceivers) {
+ Collection c = mOnRDSDataReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnRDSDataReceiver m = (OnRDSDataReceiver) iterator.next();
+ m.callOnRDSDataFound(bundle, frequency);
+ }
+ }
+ }
+
+ private void notifyOnSignalStrengthChanged(int signalStrength) {
+ synchronized (mOnSignalStrengthReceivers) {
+ Collection c = mOnSignalStrengthReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnSignalStrengthReceiver m = (OnSignalStrengthReceiver) iterator.next();
+ m.callOnSignalStrengthChanged(signalStrength);
+ }
+ }
+ }
+
+ private void notifyOnPlayingInStereo(boolean inStereo) {
+ synchronized (mOnStereoReceivers) {
+ Collection c = mOnStereoReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnStereoReceiver m = (OnStereoReceiver) iterator.next();
+ m.callOnPlayingInStereo(inStereo);
+ }
+ }
+ }
+
+ private void notifyOnExtraCommand(String response, Bundle extras) {
+ synchronized (mOnExtraCommandReceivers) {
+ Collection c = mOnExtraCommandReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnExtraCommandReceiver m = (OnExtraCommandReceiver) iterator.next();
+ m.callOnExtraCommand(response, extras);
+ }
+ }
+ }
+
+ private void notifyOnAutomaticSwitching(int newFrequency, int reason) {
+ synchronized (mOnAutomaticSwitchReceivers) {
+ Collection c = mOnAutomaticSwitchReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnAutomaticSwitchReceiver m = (OnAutomaticSwitchReceiver) iterator.next();
+ m.callOnAutomaticSwitch(newFrequency, reason);
+ }
+ }
+ }
+
+ static
+ {
+ System.loadLibrary("analogradiobroadcasting");
+ }
+
+ private native void _fm_receiver_start(int minFreq, int maxFreq, int defaultFreq, int offset);
+
+ private native void _fm_receiver_startAsync(int minFreq, int maxFreq, int defaultFreq,
+ int offset);
+
+ private native int _fm_receiver_reset();
+
+ private native void _fm_receiver_pause();
+
+ private native void _fm_receiver_resume();
+
+ private native int _fm_receiver_getState();
+
+ private native void _fm_receiver_setFrequency(int frequency);
+
+ private native int _fm_receiver_getFrequency();
+
+ private native void _fm_receiver_scanUp();
+
+ private native void _fm_receiver_scanDown();
+
+ private native void _fm_receiver_startFullScan();
+
+ private native void _fm_receiver_stopScan();
+
+ private native boolean _fm_receiver_isRDSDataSupported();
+
+ private native boolean _fm_receiver_isTunedToValidChannel();
+
+ private native void _fm_receiver_setThreshold(int threshold);
+
+ private native int _fm_receiver_getThreshold();
+
+ private native int _fm_receiver_getSignalStrength();
+
+ private native boolean _fm_receiver_isPlayingInStereo();
+
+ private native void _fm_receiver_setForceMono(boolean forceMono);
+
+ private native void _fm_receiver_setAutomaticAFSwitching(boolean automatic);
+
+ private native void _fm_receiver_setAutomaticTASwitching(boolean automatic);
+
+ private native void _fm_receiver_setRDS(boolean receiveRDS);
+
+ private native boolean _fm_receiver_sendExtraCommand(String command, String[] extras);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmTransmitter.java b/fmradio/java/com/stericsson/hardware/fm/FmTransmitter.java
new file mode 100644
index 0000000..9581651
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmTransmitter.java
@@ -0,0 +1,807 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Bjorn Pileryd (bjorn.pileryd@sonyericsson.com)
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import java.io.IOException;
+
+/**
+ * The FmTransmitter controls the output of FM radio from the device. When
+ * started, the transmitter will transmit audio via FM signals. The unit for all
+ * frequencies in this class is kHz. Note that this API only controls the output
+ * of FM radio, to select the audio stream the MediaPlayer interface should be
+ * used, see code example below the state diagram.
+ * <p>
+ * The output frequency can be changed at any time using
+ * {@link #setFrequency(int)}. The transmitter also supports transmission of RDS
+ * data, see {@link #setRdsData(Bundle)}.
+ * </p>
+ * <p>
+ * Get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(String)
+ * Context.getSystemService("fm_transmitter")}.
+ * </p>
+ * <a name="StateDiagram"></a> <h3>State Diagram</h3>
+ * <p>
+ * The state machine is designed to take into account that some hardware may
+ * need time to prepare, and that it is likely to consume more power when paused
+ * and started than it does in the idle state. The hardware implementation of
+ * this interface should do the time consuming preparation procedures in the
+ * starting state. The switching between paused and started states should be
+ * fast to give a good user experience.
+ * </p>
+ * <p>
+ * <img src="../../../../images/FmTransmitter_states.gif"
+ * alt="FmTransmitter State diagram" border="0" />
+ * </p>
+ * <table border="1">
+ * <tr>
+ * <th>Method Name</th>
+ * <th>Valid States</th>
+ * <th>Invalid States</th>
+ * <th>Comments</th>
+ * </tr>
+ * <tr>
+ * <td>{@link #startAsync(FmBand)}</td>
+ * <td>{idle}</td>
+ * <td>{starting, started, paused, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the starting state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #start(FmBand)}</td>
+ * <td>{idle}</td>
+ * <td>{starting, started, paused, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the started state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #resume()}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the started state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #pause()}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the paused state. Calling this method in an invalid state throws an
+ * IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #reset()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>Successful invocation of this method transfers the object to the idle
+ * state, the object is like being just created.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #getState()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #isApiSupported(Context)}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #setFrequency(int)}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state does not change the
+ * object state. Calling this method in an invalid state throws an
+ * IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #getFrequency()}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state does not change the
+ * object state. Calling this method in an invalid state throws an
+ * IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #setRdsData(Bundle)}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state does not change the
+ * object state. Calling this method in an invalid state throws an
+ * IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #isBlockScanSupported()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #startBlockScan(int, int)}</td>
+ * <td>{started, paused}</td>
+ * <td>{idle, starting, scanning}</td>
+ * <td>Successful invocation of this method in a valid state transfers the
+ * object to the scanning state. Calling this method in an invalid state throws
+ * an IllegalStateException.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #stopScan()}</td>
+ * <td>any</td>
+ * <td>{}</td>
+ * <td>Successful invocation of this method in a valid state tries to stop
+ * performing a scan operation. The hardware might continue the scan for an
+ * unspecified amount of time after this method is called. Once the scan has
+ * stopped, it will be notified via {@link OnScanListener}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #sendExtraCommand(String, String[])}</td>
+ * <td>vendor specific</td>
+ * <td>vendor specific</td>
+ * <td>vendor specific</td>
+ * </tr>
+ * </table>
+ * <a name="Examples"></a> <h3>Example code</h3>
+ * <pre>
+ * // prepare and start the FM transmitter
+ * FmTransmitter fmt = (FmTransmitter) getSystemService("fm_transmitter");
+ * fmt.start(new FmBand(FmBand.BAND_EU));
+ *
+ * // prepare and start playback
+ * MediaPlayer mp = new MediaPlayer();
+ * mp.setDataSource(PATH_TO_FILE);
+ * mp.prepare();
+ * mp.start();
+ * </pre>
+ * <a name="FMHandling"></a> <h3>FM receiving/transmission handling</h3>
+ * <p>
+ * In this API, FM radio cannot be received and transmitted at the same time,
+ * therefore the state machine is designed to prevent incorrect usage. The
+ * FmReceiver and FmTransmitter has a separate state machine and only one can be
+ * <i>active</i> (state other than idle).
+ * <ul>
+ * <li>If start is called on FmTransmitter and the FmReceiver is <i>active</i>,
+ * the FmReceiver MUST release resources and change state to idle.</li>
+ * <li>The FmReceiver will in that case be notified by
+ * {@link com.stericsson.hardware.fm.FmReceiver.OnForcedResetListener#onForcedReset(int)}.</li>
+ * </ul>
+ * </p>
+ * <a name="ErrorHandling"></a> <h3>Error handling</h3>
+ * <p>
+ * In general, it is up to the application that uses this API to keep track of
+ * events that could affect the FM radio user experience. The hardware
+ * implementation side of this API should only take actions when it is really
+ * necessary, e.g. if the hardware is forced to pause or reset, and notify the
+ * application by using the {@link OnForcedPauseListener},
+ * {@link OnForcedResetListener} or {@link OnErrorListener}.
+ * </p>
+ */
+public abstract class FmTransmitter {
+
+ /**
+ * The FmTransmitter had to be shut down due to a non-critical error,
+ * meaning that it is OK to attempt a restart immediately after this. An
+ * example is when the hardware was shut down in order to save power after
+ * being in the paused state for too long.
+ */
+ public static final int RESET_NON_CRITICAL = 0;
+
+ /**
+ * The FmTransmitter had to be shut down due to a critical error. The FM
+ * hardware it not guaranteed to work as expected after receiving this
+ * error.
+ */
+ public static final int RESET_CRITICAL = 1;
+
+ /**
+ * The FmReceiver was activated and therefore the FmTransmitter must be put
+ * in idle.
+ *
+ * @see FmReceiver#startAsync(FmBand)
+ */
+ public static final int RESET_RX_IN_USE = 2;
+
+ /**
+ * The radio is not allowed to be used, typically when flight mode is
+ * enabled.
+ */
+ public static final int RESET_RADIO_FORBIDDEN = 3;
+
+ /**
+ * Indicates that the FmTransmitter is in an idle state. No resources are
+ * allocated and power consumption is kept to a minimum.
+ */
+ public static final int STATE_IDLE = 0;
+
+ /**
+ * Indicates that the FmTransmitter is allocating resources and preparing to
+ * transmit FM radio.
+ */
+ public static final int STATE_STARTING = 1;
+
+ /**
+ * Indicates that the FmTransmitter is transmitting FM radio.
+ */
+ public static final int STATE_STARTED = 2;
+
+ /**
+ * Indicates that the FmTransmitter has allocated resources and is ready to
+ * instantly transmit FM radio.
+ */
+ public static final int STATE_PAUSED = 3;
+
+ /**
+ * Indicates that the FmTransmitter is scanning. FM radio will not be
+ * transmitted in this state.
+ */
+ public static final int STATE_SCANNING = 4;
+
+ /**
+ * Returns true if the FM transmitter API is supported by the system.
+ */
+ public static boolean isApiSupported(Context context) {
+ return context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_RADIO_FM_TRANSMITTER);
+ }
+
+ /**
+ * Starts reception of the FM hardware. This is an asynchronous method since
+ * different hardware can have varying startup times. When the reception is
+ * started a callback to {@link OnStartedListener#onStarted()} is made.
+ * <p>
+ * When calling this method, an FmBand parameter must be passed that
+ * describes the properties of the band that the FmTransmitter should
+ * prepare for. If the band is null, invalid or not supported, an exception
+ * will be thrown.
+ * </p>
+ * <p>
+ * If the FmReceiver is active it will be forced to reset. See
+ * {@link FmReceiver#RESET_TX_IN_USE}.
+ * </p>
+ *
+ * @param band
+ * the band to use
+ * @throws IllegalArgumentException
+ * if the band is null
+ * @throws UnsupportedOperationException
+ * if the band is not supported by the hardware
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to start
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ * @see FmBand
+ */
+ public abstract void startAsync(FmBand band) throws IOException;
+
+ /**
+ * Starts reception of the FM hardware. This is a synchronous method and the
+ * method call will block until the hardware is started.
+ * <p>
+ * When calling this method, an FmBand parameter must be passed that
+ * describes the properties of the band that the FmTransmitter should
+ * prepare for. If the band is null, invalid or not supported, an exception
+ * will be thrown.
+ * </p>
+ * <p>
+ * If the FmReceiver is active it will be forced to reset. See
+ * {@link FmReceiver#RESET_TX_IN_USE}.
+ * </p>
+ *
+ * @param band
+ * the band to use
+ * @throws IllegalArgumentException
+ * if the band is null
+ * @throws UnsupportedOperationException
+ * if the band is not supported by the hardware
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to start
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ * @see FmBand
+ */
+ public abstract void start(FmBand band) throws IOException;
+
+ /**
+ * Resumes FM transmission.
+ * <p>
+ * Calling this method when the FmTransmitter is in started state has no
+ * affect.
+ * </p>
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to resume
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void resume() throws IOException;
+
+ /**
+ * Pauses FM transmission. No signals are sent when the FmTransmitter is
+ * paused. Call {@link #resume()} to resume transmission. The hardware
+ * should be able to start transmission quickly from the paused state to
+ * give a good user experience.
+ * <p>
+ * Note that the hardware provider may choose to turn off the hardware after
+ * being paused a certain amount of time to save power. This will be
+ * reported in {@link OnForcedResetListener#onForcedReset(int)} with reason
+ * {@link #RESET_NON_CRITICAL} and the FmTransmitter will be set to the idle
+ * state.
+ * </p>
+ * <p>
+ * Calling this method when the FmTransmitter is in paused state has no
+ * affect.
+ * </p>
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to pause
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void pause() throws IOException;
+
+ /**
+ * Resets the FmTransmitter to its idle state.
+ *
+ * @throws IOException
+ * if the FM hardware failed to reset
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void reset() throws IOException;
+
+ /**
+ * Returns the state of the FmTransmitter.
+ *
+ * @return One of {@link #STATE_IDLE}, {@link #STATE_STARTING},
+ * {@link #STATE_STARTED}, {@link #STATE_PAUSED},
+ * {@link #STATE_SCANNING}
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract int getState();
+
+ /**
+ * Sets the output frequency. The frequency must be within the band that the
+ * FmTransmitter prepared for.
+ *
+ * @param frequency
+ * the output frequency to use in kHz
+ * @throws IllegalArgumentException
+ * if the frequency is not supported
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to set frequency
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void setFrequency(int frequency) throws IOException;
+
+ /**
+ * Returns the output frequency.
+ *
+ * @return the output frequency in kHz
+ *
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws IOException
+ * if the FM hardware failed to get the frequency
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract int getFrequency() throws IOException;
+
+ /**
+ * Sets the RDS data to transmit. See RDS table in FmReceiver for data that
+ * can be set.
+ *
+ * @param rdsData
+ * the RDS data to transmit, set to null to disable RDS
+ * transmission
+ * @throws IllegalArgumentException
+ * if the rdsData parameter has invalid syntax
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void setRdsData(Bundle rdsData);
+
+ /**
+ * Returns true if the hardware/implementation supports block scan. If true
+ * the {@link FmTransmitter#startBlockScan(int, int)} will work.
+ * <p>
+ * The motivation for having this function is that an application can take
+ * this capability into account when laying out its UI.
+ * </p>
+ *
+ * @return true if block scan is supported by the FmTransmitter, false
+ * otherwise
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract boolean isBlockScanSupported();
+
+ /**
+ * Starts a block scan. The tuner will scan the frequency band between
+ * startFrequency and endFrequency for unused frequencies. The application
+ * should register for callbacks using
+ * {@link #addOnScanListener(OnScanListener)} to receive a callback when
+ * frequencies are found.
+ * <p>
+ * If the application wants to stop the block scan, a call to
+ * {@link #stopScan()} should be made.
+ * </p>
+ *
+ * @param startFrequency
+ * the frequency to start the block scan
+ * @param endFrequency
+ * the frequency to end the block scan
+ * @throws IllegalArgumentException
+ * if the startFrequency or endFrequency it not within the
+ * currently used FmBand
+ * @throws UnsupportedOperationException
+ * if the hardware/implementation does not supports block scan
+ * @throws IllegalStateException
+ * if it is called in an invalid state
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void startBlockScan(int startFrequency, int endFrequency);
+
+ /**
+ * Stops performing a scan operation. The hardware might continue the scan
+ * for an unspecified amount of time after this method is called. Once the
+ * scan has stopped, it will be notified via {@link OnScanListener}.
+ * <p>
+ * Note that this method has no affect if called in other states than the
+ * scanning state.
+ * </p>
+ *
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void stopScan();
+
+ /**
+ * This method can be used to send vendor specific commands. These commands
+ * must not follow any common design for all vendors, and information about
+ * the commands that a vendor implements is out of scope in this API.
+ * <p>
+ * However, one command must be supported by all vendors that implements
+ * vendor specific commands, the <i>vendor_information</i> command. In the
+ * Bundle parameter in
+ * {@link OnExtraCommandListener#onExtraCommand(String, Bundle)} the FM
+ * radio device name and version can be extracted according to the table
+ * below.
+ * </p>
+ * <table border="1">
+ * <tr>
+ * <th>key name</th>
+ * <th>value type</th>
+ * </tr>
+ * <tr>
+ * <td>device_name</td>
+ * <td>string</td>
+ * </tr>
+ * <tr>
+ * <td>device_version</td>
+ * <td>string</td>
+ * </tr>
+ * </table>
+ *
+ * @param command
+ * the command to send
+ * @param extras
+ * extra parameters to the command
+ * @return true if the command was accepted, otherwise false
+ *
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract boolean sendExtraCommand(String command, String[] extras);
+
+ /**
+ * Register a callback to be invoked when the FmTransmitter is started.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void addOnStartedListener(OnStartedListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmTransmitter is started.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void removeOnStartedListener(OnStartedListener listener);
+
+ /**
+ * Register a callback to be invoked during a scan.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void addOnScanListener(OnScanListener listener);
+
+ /**
+ * Unregister a callback to be invoked during a scan.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void removeOnScanListener(OnScanListener listener);
+
+ /**
+ * Register a callback to be invoked when an error has happened during an
+ * asynchronous operation.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void addOnErrorListener(OnErrorListener listener);
+
+ /**
+ * Unregister a callback to be invoked when an error has happened during an
+ * asynchronous operation.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void removeOnErrorListener(OnErrorListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmTransmitter is forced to
+ * pause due to external reasons.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void addOnForcedPauseListener(OnForcedPauseListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmTransmitter is forced to
+ * pause due to external reasons.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void removeOnForcedPauseListener(OnForcedPauseListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmTransmitter is forced to
+ * reset due to external reasons.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void addOnForcedResetListener(OnForcedResetListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmTransmitter is forced to
+ * reset due to external reasons.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void removeOnForcedResetListener(OnForcedResetListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmTransmitter changes state.
+ * Having a listener registered to this method may cause frequent callbacks,
+ * hence it is good practice to only have a listener registered for this
+ * when necessary.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void addOnStateChangedListener(OnStateChangedListener listener);
+
+ /**
+ * Unregister a callback to be invoked when the FmTransmitter changes state.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void removeOnStateChangedListener(OnStateChangedListener listener);
+
+ /**
+ * Register a callback to be invoked when the FmTransmitter want's to invoke
+ * a vendor specific callback.
+ *
+ * @param listener
+ * the callback that will be run
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void addOnExtraCommandListener(OnExtraCommandListener listener);
+ /**
+ * Unregister a callback to be invoked when the FmTransmitter want's to
+ * invoke a vendor specific callback.
+ *
+ * @param listener
+ * the callback to remove
+ * @throws SecurityException
+ * if the FM_RADIO_TRANSMITTER permission is not present
+ */
+ public abstract void removeOnExtraCommandListener(OnExtraCommandListener listener);
+
+ /**
+ * Interface definition of a callback to be invoked when the FmTransmitter
+ * is started.
+ */
+ public interface OnStartedListener {
+ /**
+ * Called when the FmTransmitter is started. The FmTransmitter is now
+ * transmitting FM radio.
+ */
+ void onStarted();
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when a scan operation is
+ * complete.
+ */
+ public interface OnScanListener {
+ /**
+ * Called when the block scan is completed.
+ * <p>
+ * If the block scan is aborted with stopScan, this will be indicated
+ * with the aborted argument.
+ * <p>
+ * If an error occurs during a block scan, it will be reported via
+ * {@link OnErrorListener#onError()} and this method callback will not
+ * be invoked.
+ * </p>
+ *
+ * @param frequency
+ * the frequency in kHz where the channel was found
+ * @param signalStrength
+ * the signal strength, 0-1000
+ * @param aborted
+ * true if the block scan was aborted, false otherwise
+ */
+ void onBlockScan(int[] frequency, int[] signalStrength, boolean aborted);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when there has been an
+ * error during an asynchronous operation.
+ */
+ public interface OnErrorListener {
+ /**
+ * Called to indicate an error.
+ */
+ void onError();
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmTransmitter
+ * was forced to pause due to external reasons.
+ */
+ public interface OnForcedPauseListener {
+ /**
+ * Called when an external reason caused the FmTransmitter to pause.
+ * When this callback is received, the FmTransmitter is still able to
+ * resume transmission by calling {@link FmTransmitter#resume()}.
+ */
+ void onForcedPause();
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmTransmitter
+ * was forced to reset due to external reasons.
+ */
+ public interface OnForcedResetListener {
+ /**
+ * Called when an external reason caused the FmTransmitter to reset. The
+ * application that uses the FmTransmitter should take action according
+ * to the reason for resetting.
+ *
+ * @param reason
+ * reason why the FmTransmitter reset:
+ * <ul>
+ * <li>{@link FmTransmitter#RESET_NON_CRITICAL}
+ * <li>{@link FmTransmitter#RESET_CRITICAL}
+ * <li>{@link FmTransmitter#RESET_RX_IN_USE}
+ * <li>{@link FmTransmitter#RESET_RADIO_FORBIDDEN}
+ * </ul>
+ */
+ void onForcedReset(int reason);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmTransmitter
+ * changes state.
+ */
+ public interface OnStateChangedListener {
+ /**
+ * Called when the state is changed in the FmTransmitter. This is useful
+ * if an application want's to monitor the FmTransmitter state.
+ *
+ * @param oldState
+ * the old state of the FmTransmitter
+ * @param newState
+ * the new state of the FmTransmitter
+ */
+ void onStateChanged(int oldState, int newState);
+ }
+
+ /**
+ * Interface definition of a callback to be invoked when the FmTransmitter
+ * responds to a vendor specific command.
+ */
+ public interface OnExtraCommandListener {
+ /**
+ * Called when the FmTransmitter responds to a vendor specific command.
+ *
+ * @param response
+ * the command the FmTransmitter responds to
+ * @param extras
+ * extra parameters to the command
+ */
+ void onExtraCommand(String response, Bundle extras);
+ }
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmTransmitterImpl.java b/fmradio/java/com/stericsson/hardware/fm/FmTransmitterImpl.java
new file mode 100644
index 0000000..0dbb005
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmTransmitterImpl.java
@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Bjorn Pileryd (bjorn.pileryd@sonyericsson.com)
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ * Author: Andreas Gustafsson (andreas.a.gustafsson@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * The implementation of the FmReceiver.
+ *
+ * @hide
+ */
+public class FmTransmitterImpl extends FmTransmitter {
+
+ private static final String TAG = "FmTransmitter";
+
+ private IFmTransmitter mService;
+
+ /**
+ * Save the FmBand used to be able to validate frequencies.
+ */
+ private FmBand mBand;
+
+ /**
+ * Map from OnStateChanged to their associated ListenerTransport objects.
+ */
+ private HashMap<OnStateChangedListener, OnStateChangedListenerTransport> mOnStateChanged =
+ new HashMap<OnStateChangedListener, OnStateChangedListenerTransport>();
+
+ /**
+ * Map from OnStarted to their associated ListenerTransport objects.
+ */
+ private HashMap<OnStartedListener, OnStartedListenerTransport> mOnStarted =
+ new HashMap<OnStartedListener, OnStartedListenerTransport>();
+
+ /**
+ * Map from OnError to their associated ListenerTransport objects.
+ */
+ private HashMap<OnErrorListener, OnErrorListenerTransport> mOnError =
+ new HashMap<OnErrorListener, OnErrorListenerTransport>();
+
+ /**
+ * Map from OnBlockScan to their associated ListenerTransport objects.
+ */
+ private HashMap<OnScanListener, OnBlockScanListenerTransport> mOnBlockScan =
+ new HashMap<OnScanListener, OnBlockScanListenerTransport>();
+
+ /**
+ * Map from OnForcedPause to their associated ListenerTransport objects.
+ */
+ private HashMap<OnForcedPauseListener, OnForcedPauseListenerTransport> mOnForcedPause =
+ new HashMap<OnForcedPauseListener, OnForcedPauseListenerTransport>();
+
+ /**
+ * Map from OnForcedReset to their associated ListenerTransport objects.
+ */
+ private HashMap<OnForcedResetListener, OnForcedResetListenerTransport> mOnForcedReset =
+ new HashMap<OnForcedResetListener, OnForcedResetListenerTransport>();
+
+ /**
+ * Map from OnExtraCommand to their associated ListenerTransport objects.
+ */
+ private HashMap<OnExtraCommandListener, OnExtraCommandListenerTransport> mOnExtraCommand =
+ new HashMap<OnExtraCommandListener, OnExtraCommandListenerTransport>();
+
+ private static class OnStateChangedListenerTransport extends IOnStateChangedListener.Stub {
+ private static final int TYPE_ON_STATE_CHANGED = 1;
+
+ private OnStateChangedListener mListener;
+ private final Handler mListenerHandler;
+
+ OnStateChangedListenerTransport(OnStateChangedListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onStateChanged(int oldState, int newState) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_STATE_CHANGED;
+ Bundle b = new Bundle();
+ b.putInt("oldState", oldState);
+ b.putInt("newState", newState);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_STATE_CHANGED:
+ Bundle b = (Bundle) msg.obj;
+ int oldState = b.getInt("oldState");
+ int newState = b.getInt("newState");
+ mListener.onStateChanged(oldState, newState);
+ break;
+ }
+ }
+ }
+
+ private static class OnStartedListenerTransport extends IOnStartedListener.Stub {
+ private static final int TYPE_ON_STARTED = 1;
+
+ private OnStartedListener mListener;
+ private final Handler mListenerHandler;
+
+ OnStartedListenerTransport(OnStartedListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onStarted() {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_STARTED;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_STARTED:
+ mListener.onStarted();
+ break;
+ }
+ }
+ }
+
+ private static class OnErrorListenerTransport extends IOnErrorListener.Stub {
+ private static final int TYPE_ON_ERROR = 1;
+
+ private OnErrorListener mListener;
+ private final Handler mListenerHandler;
+
+ OnErrorListenerTransport(OnErrorListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onError() {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_ERROR;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_ERROR:
+ mListener.onError();
+ break;
+ }
+ }
+ }
+
+ private static class OnBlockScanListenerTransport extends IOnBlockScanListener.Stub {
+ private static final int TYPE_ON_BLOCKSCAN = 1;
+
+ private OnScanListener mListener;
+ private final Handler mListenerHandler;
+
+ OnBlockScanListenerTransport(OnScanListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onBlockScan(int[] frequency, int[] signalStrength, boolean aborted) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_BLOCKSCAN;
+ Bundle b = new Bundle();
+ b.putIntArray("frequency", frequency);
+ b.putIntArray("signalStrength", signalStrength);
+ b.putBoolean("aborted", aborted);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+
+ switch (msg.what) {
+ case TYPE_ON_BLOCKSCAN:
+ Bundle b = (Bundle) msg.obj;
+ int[] frequency = b.getIntArray("frequency");
+ int[] signalStrengths = b.getIntArray("signalStrength");
+ boolean aborted = b.getBoolean("aborted");
+ mListener.onBlockScan(frequency, signalStrengths, aborted);
+ break;
+ }
+ }
+ }
+
+ private static class OnForcedPauseListenerTransport extends IOnForcedPauseListener.Stub {
+ private static final int TYPE_ON_FORCEDPAUSE = 1;
+
+ private OnForcedPauseListener mListener;
+ private final Handler mListenerHandler;
+
+ OnForcedPauseListenerTransport(OnForcedPauseListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onForcedPause() {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_FORCEDPAUSE;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_FORCEDPAUSE:
+ mListener.onForcedPause();
+ break;
+ }
+ }
+ }
+
+ private static class OnForcedResetListenerTransport extends IOnForcedResetListener.Stub {
+ private static final int TYPE_ON_FORCEDRESET = 1;
+
+ private OnForcedResetListener mListener;
+ private final Handler mListenerHandler;
+
+ OnForcedResetListenerTransport(OnForcedResetListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onForcedReset(int reason) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_FORCEDRESET;
+ Bundle b = new Bundle();
+ b.putInt("reason", reason);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ switch (msg.what) {
+ case TYPE_ON_FORCEDRESET:
+ Bundle b = (Bundle) msg.obj;
+ int reason = b.getInt("reason");
+ mListener.onForcedReset(reason);
+ break;
+ }
+ }
+ }
+
+ private static class OnExtraCommandListenerTransport extends IOnExtraCommandListener.Stub {
+ private static final int TYPE_ON_EXTRA_COMMAND = 1;
+
+ private OnExtraCommandListener mListener;
+ private final Handler mListenerHandler;
+
+ OnExtraCommandListenerTransport(OnExtraCommandListener listener) {
+ mListener = listener;
+
+ mListenerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ _handleMessage(msg);
+ }
+ };
+ }
+
+ public void onExtraCommand(String response, Bundle extras) {
+ Message msg = Message.obtain();
+ msg.what = TYPE_ON_EXTRA_COMMAND;
+ Bundle b = new Bundle();
+ b.putString("response", response);
+ b.putBundle("extras", extras);
+ msg.obj = b;
+ mListenerHandler.sendMessage(msg);
+ }
+
+ private void _handleMessage(Message msg) {
+ Bundle b;
+ boolean aborted;
+
+ switch (msg.what) {
+ case TYPE_ON_EXTRA_COMMAND:
+ b = (Bundle) msg.obj;
+ String response = b.getString("response");
+ Bundle extras = b.getBundle("extras");
+ mListener.onExtraCommand(response, extras);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Creates a new FmTransmitter instance. Applications will almost always
+ * want to use {@link android.content.Context#getSystemService
+ * Context.getSystemService()} to retrieve the standard
+ * {@link android.content.Context "fm_transmitter"}.
+ *
+ * @param service
+ * the Binder interface
+ * @hide - hide this because it takes in a parameter of type IFmReceiver,
+ * which is a system private class.
+ */
+ public FmTransmitterImpl(IFmTransmitter service) {
+ mService = service;
+ }
+
+ @Override
+ public void startAsync(FmBand band) throws IOException {
+ if (band == null) {
+ throw new IllegalArgumentException("Band cannot be null");
+ }
+ try {
+ mService.startAsync(band);
+ mBand = band;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "startAsync: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void start(FmBand band) throws IOException {
+ if (band == null) {
+ throw new IllegalArgumentException("Band cannot be null");
+ }
+ try {
+ mService.start(band);
+ mBand = band;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "start: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void resume() throws IOException {
+ try {
+ mService.resume();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "resume: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void pause() throws IOException {
+ try {
+ mService.pause();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "pause: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void reset() throws IOException {
+ try {
+ mService.reset();
+ mBand = null;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "reset: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public int getState() {
+ try {
+ return mService.getState();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getState: RemoteException", ex);
+ return STATE_IDLE;
+ }
+ }
+
+ @Override
+ public void setFrequency(int frequency) throws IOException {
+ if (mBand != null && !mBand.isFrequencyValid(frequency)) {
+ throw new IllegalArgumentException(
+ "Frequency is not valid in this band.");
+ }
+ try {
+ mService.setFrequency(frequency);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "setFrequency: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public int getFrequency() throws IOException {
+ try {
+ return mService.getFrequency();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getFrequency: RemoteException", ex);
+ return FmBand.FM_FREQUENCY_UNKNOWN;
+ }
+ }
+
+ @Override
+ public void setRdsData(Bundle rdsData) {
+ try {
+ mService.setRdsData(rdsData);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "setRdsData: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public boolean isBlockScanSupported() {
+ try {
+ return mService.isBlockScanSupported();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "isBlockScanSupported: RemoteException", ex);
+ return false;
+ }
+ }
+
+ @Override
+ public void startBlockScan(int startFrequency, int endFrequency) {
+ try {
+ mService.startBlockScan(startFrequency, endFrequency);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "startBlockScan: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void stopScan() {
+ try {
+ mService.stopScan();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "stopScan: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public boolean sendExtraCommand(String command, String[] extras) {
+ try {
+ return mService.sendExtraCommand(command, extras);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "sendExtraCommand: RemoteException", ex);
+ return false;
+ }
+ }
+
+ @Override
+ public void addOnStartedListener(OnStartedListener listener) {
+ if (mOnStarted.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnStarted) {
+ OnStartedListenerTransport transport = new OnStartedListenerTransport(listener);
+ mService.addOnStartedListener(transport);
+ mOnStarted.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnStartedListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnStartedListener(OnStartedListener listener) {
+ try {
+ OnStartedListenerTransport transport = mOnStarted.remove(listener);
+ if (transport != null) {
+ mService.removeOnStartedListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnStartedListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnScanListener(OnScanListener listener) {
+ if (mOnBlockScan.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnBlockScan) {
+ OnBlockScanListenerTransport transport = new OnBlockScanListenerTransport(listener);
+ mService.addOnBlockScanListener(transport);
+ mOnBlockScan.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnScanListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnScanListener(OnScanListener listener) {
+ try {
+ OnBlockScanListenerTransport transport = mOnBlockScan.remove(listener);
+ if (transport != null) {
+ mService.removeOnBlockScanListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnScanListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnErrorListener(OnErrorListener listener) {
+ if (mOnError.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnError) {
+ OnErrorListenerTransport transport = new OnErrorListenerTransport(listener);
+ mService.addOnErrorListener(transport);
+ mOnError.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnErrorListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnErrorListener(OnErrorListener listener) {
+ try {
+ OnErrorListenerTransport transport = mOnError.remove(listener);
+ if (transport != null) {
+ mService.removeOnErrorListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnErrorListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnForcedPauseListener(OnForcedPauseListener listener) {
+ if (mOnForcedPause.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnForcedPause) {
+ OnForcedPauseListenerTransport transport = new OnForcedPauseListenerTransport(
+ listener);
+ mService.addOnForcedPauseListener(transport);
+ mOnForcedPause.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnForcedPauseListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnForcedPauseListener(OnForcedPauseListener listener) {
+ try {
+ OnForcedPauseListenerTransport transport = mOnForcedPause.remove(listener);
+ if (transport != null) {
+ mService.removeOnForcedPauseListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnForcedPauseListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnForcedResetListener(OnForcedResetListener listener) {
+ if (mOnForcedReset.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnForcedReset) {
+ OnForcedResetListenerTransport transport = new OnForcedResetListenerTransport(
+ listener);
+ mService.addOnForcedResetListener(transport);
+ mOnForcedReset.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnForcedResetListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnForcedResetListener(OnForcedResetListener listener) {
+ try {
+ OnForcedResetListenerTransport transport = mOnForcedReset.remove(listener);
+ if (transport != null) {
+ mService.removeOnForcedResetListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnForcedResetListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnStateChangedListener(OnStateChangedListener listener) {
+ if (mOnStateChanged.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnStateChanged) {
+ OnStateChangedListenerTransport transport = new OnStateChangedListenerTransport(
+ listener);
+ mService.addOnStateChangedListener(transport);
+ mOnStateChanged.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnStateChangedListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnStateChangedListener(OnStateChangedListener listener) {
+ try {
+ OnStateChangedListenerTransport transport = mOnStateChanged.remove(listener);
+ if (transport != null) {
+ mService.removeOnStateChangedListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnStateChangedListener: DeadObjectException", ex);
+ }
+ }
+
+ @Override
+ public void addOnExtraCommandListener(OnExtraCommandListener listener) {
+ if (mOnExtraCommand.get(listener) != null) {
+ // listener is already registered
+ return;
+ }
+ try {
+ synchronized (mOnExtraCommand) {
+ OnExtraCommandListenerTransport transport = new OnExtraCommandListenerTransport(
+ listener);
+ mService.addOnExtraCommandListener(transport);
+ mOnExtraCommand.put(listener, transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "addOnExtraCommandListener: RemoteException", ex);
+ }
+ }
+
+ @Override
+ public void removeOnExtraCommandListener(OnExtraCommandListener listener) {
+ try {
+ OnExtraCommandListenerTransport transport = mOnExtraCommand.remove(listener);
+ if (transport != null) {
+ mService.removeOnExtraCommandListener(transport);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "removeOnExtraCommandListener: DeadObjectException", ex);
+ }
+ }
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/FmTransmitterService.java b/fmradio/java/com/stericsson/hardware/fm/FmTransmitterService.java
new file mode 100644
index 0000000..8434ebc
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/FmTransmitterService.java
@@ -0,0 +1,846 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * The implementation of the FM transmitter service.
+ *
+ * @hide
+ */
+
+public class FmTransmitterService extends IFmTransmitter.Stub {
+
+ private static final String TAG = "FmTransmitterService";
+
+ private Context mContext;
+
+ private final HashMap<Object, OnStateChangedReceiver> mOnStateChangedReceivers =
+ new HashMap<Object, OnStateChangedReceiver>();
+
+ private final HashMap<Object, OnStartedReceiver> mOnStartedReceivers =
+ new HashMap<Object, OnStartedReceiver>();
+
+ private final HashMap<Object, OnErrorReceiver> mOnErrorReceivers =
+ new HashMap<Object, OnErrorReceiver>();
+
+ private final HashMap<Object, OnBlockScanReceiver> mOnBlockScanReceivers =
+ new HashMap<Object, OnBlockScanReceiver>();
+
+ private final HashMap<Object, OnForcedPauseReceiver> mOnForcedPauseReceivers =
+ new HashMap<Object, OnForcedPauseReceiver>();
+
+ private final HashMap<Object, OnForcedResetReceiver> mOnForcedResetReceivers =
+ new HashMap<Object, OnForcedResetReceiver>();
+
+ private final HashMap<Object, OnExtraCommandReceiver> mOnExtraCommandReceivers =
+ new HashMap<Object, OnExtraCommandReceiver>();
+
+ private final class OnStateChangedReceiver implements IBinder.DeathRecipient {
+ final IOnStateChangedListener mListener;
+ final Object mKey;
+
+ OnStateChangedReceiver(IOnStateChangedListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnStateChangedListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnStateChanged(int oldState, int newState) {
+ try {
+ synchronized (this) {
+ mListener.onStateChanged(oldState, newState);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnStateChanged: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM transmitter listener died");
+
+ synchronized (mOnStateChangedReceivers) {
+ mOnStateChangedReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnStartedReceiver implements IBinder.DeathRecipient {
+ final IOnStartedListener mListener;
+ final Object mKey;
+
+ OnStartedReceiver(IOnStartedListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnStartedListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnStarted() {
+ try {
+ synchronized (this) {
+ mListener.onStarted();
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnStarted: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM transmitter listener died");
+
+ synchronized (mOnStartedReceivers) {
+ mOnStartedReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnErrorReceiver implements IBinder.DeathRecipient {
+ final IOnErrorListener mListener;
+ final Object mKey;
+
+ OnErrorReceiver(IOnErrorListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnErrorListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnError() {
+ try {
+ synchronized (this) {
+ mListener.onError();
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnError: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM transmitter listener died");
+
+ synchronized (mOnErrorReceivers) {
+ mOnErrorReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnBlockScanReceiver implements IBinder.DeathRecipient {
+ final IOnBlockScanListener mListener;
+
+ final Object mKey;
+
+ OnBlockScanReceiver(IOnBlockScanListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnBlockScanListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnBlockScan(int[] frequency, int[] signalLevel, boolean aborted) {
+ try {
+ synchronized (this) {
+ mListener.onBlockScan(frequency, signalLevel, aborted);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnBlockScan: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnBlockScanReceivers) {
+ mOnBlockScanReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnForcedPauseReceiver implements IBinder.DeathRecipient {
+ final IOnForcedPauseListener mListener;
+ final Object mKey;
+
+ OnForcedPauseReceiver(IOnForcedPauseListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnForcedPauseListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnForcedPause() {
+ try {
+ synchronized (this) {
+ mListener.onForcedPause();
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnForcedPause: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM transmitter listener died");
+
+ synchronized (mOnForcedPauseReceivers) {
+ mOnForcedPauseReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnForcedResetReceiver implements IBinder.DeathRecipient {
+ final IOnForcedResetListener mListener;
+ final Object mKey;
+
+ OnForcedResetReceiver(IOnForcedResetListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnForcedResetListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnForcedReset(int reason) {
+ try {
+ synchronized (this) {
+ mListener.onForcedReset(reason);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnForcedReset: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM transmitter listener died");
+
+ synchronized (mOnForcedResetReceivers) {
+ mOnForcedResetReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final class OnExtraCommandReceiver implements IBinder.DeathRecipient {
+ final IOnExtraCommandListener mListener;
+
+ final Object mKey;
+
+ OnExtraCommandReceiver(IOnExtraCommandListener listener) {
+ mListener = listener;
+ mKey = listener.asBinder();
+ }
+
+ public IOnExtraCommandListener getListener() {
+ return mListener;
+ }
+
+ public boolean callOnExtraCommand(String response, Bundle extras) {
+ try {
+ synchronized (this) {
+ mListener.onExtraCommand(response, extras);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "callOnExtraCommand: RemoteException", ex);
+ return false;
+ }
+ return true;
+ }
+
+ public void binderDied() {
+ Log.d(TAG, "FM receiver listener died");
+
+ synchronized (mOnExtraCommandReceivers) {
+ mOnExtraCommandReceivers.remove(this.mKey);
+ }
+ if (mListener != null) {
+ mListener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
+ Log.d(TAG, "onReceive:ACTION_AIRPLANE_MODE_CHANGED");
+
+ // check that airplane mode is off
+ if (!isAirplaneModeOn()) {
+ return;
+ }
+
+ // power down hardware
+ if (_fm_transmitter_reset() > FmTransmitter.STATE_IDLE) {
+ notifyOnForcedReset(FmTransmitter.RESET_RADIO_FORBIDDEN);
+ }
+ }
+ }
+
+ };
+
+ /* Returns true if airplane mode is currently on */
+ private boolean isAirplaneModeOn() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ }
+
+ public FmTransmitterService(Context context) {
+ Log.i(TAG, "FmTransmitterService created");
+ mContext = context;
+
+ // Register for airplane mode
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ filter.addAction(Intent.ACTION_DOCK_EVENT);
+
+ mContext.registerReceiver(mReceiver, filter);
+
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ }
+
+ public void start(FmBand band) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_start(band.getMinFrequency(), band.getMaxFrequency(), band
+ .getDefaultFrequency(), band.getChannelOffset());
+ }
+
+ public void startAsync(FmBand band) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_startAsync(band.getMinFrequency(), band.getMaxFrequency(), band
+ .getDefaultFrequency(), band.getChannelOffset());
+ }
+
+ public void reset() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_reset();
+ }
+
+ public void pause() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_pause();
+ }
+
+ public void resume() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_resume();
+ }
+
+ public int getState() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ return _fm_transmitter_getState();
+ }
+
+ public void setFrequency(int frequency) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_setFrequency(frequency);
+ }
+
+ public int getFrequency() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ return _fm_transmitter_getFrequency();
+ }
+
+ public boolean isBlockScanSupported() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ return _fm_transmitter_isBlockScanSupported();
+ }
+
+ public void startBlockScan(int startFrequency, int endFrequency) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_startBlockScan(startFrequency, endFrequency);
+ }
+
+ public void stopScan() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_stopScan();
+ }
+
+ public void setRdsData(Bundle rdsData) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ _fm_transmitter_setRdsData(rdsData);
+ }
+
+ public boolean sendExtraCommand(String command, String[] extras) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ return _fm_transmitter_sendExtraCommand(command, extras);
+ }
+
+ public void addOnStateChangedListener(IOnStateChangedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStateChangedReceiver receiver = mOnStateChangedReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnStateChangedReceiver(listener);
+ mOnStateChangedReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnStateChangedListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnStateChangedListener(IOnStateChangedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStateChangedReceiver receiver = mOnStateChangedReceivers.get(binder);
+ if (receiver != null) {
+ mOnStateChangedReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnStateChangedListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnStartedListener(IOnStartedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStartedReceiver receiver = mOnStartedReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnStartedReceiver(listener);
+ mOnStartedReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnStartedListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnStartedListener(IOnStartedListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnStartedReceiver receiver = mOnStartedReceivers.get(binder);
+ if (receiver != null) {
+ mOnStartedReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnStartedListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnErrorListener(IOnErrorListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnErrorReceiver receiver = mOnErrorReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnErrorReceiver(listener);
+ mOnErrorReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnErrorListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnErrorListener(IOnErrorListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnErrorReceiver receiver = mOnErrorReceivers.get(binder);
+ if (receiver != null) {
+ mOnErrorReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnErrorListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnBlockScanListener(IOnBlockScanListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnBlockScanReceiver receiver = mOnBlockScanReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnBlockScanReceiver(listener);
+ mOnBlockScanReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnBlockScanListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnBlockScanListener(IOnBlockScanListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnBlockScanReceiver receiver = mOnBlockScanReceivers.get(binder);
+ if (receiver != null) {
+ mOnBlockScanReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnBlockScanListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnForcedPauseListener(IOnForcedPauseListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedPauseReceiver receiver = mOnForcedPauseReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnForcedPauseReceiver(listener);
+ mOnForcedPauseReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnForcedPauseListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnForcedPauseListener(IOnForcedPauseListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedPauseReceiver receiver = mOnForcedPauseReceivers.get(binder);
+ if (receiver != null) {
+ mOnForcedPauseReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnForcedPauseListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnForcedResetListener(IOnForcedResetListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedResetReceiver receiver = mOnForcedResetReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnForcedResetReceiver(listener);
+ mOnForcedResetReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnForcedResetListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnForcedResetListener(IOnForcedResetListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnForcedResetReceiver receiver = mOnForcedResetReceivers.get(binder);
+ if (receiver != null) {
+ mOnForcedResetReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnForcedResetListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ public void addOnExtraCommandListener(IOnExtraCommandListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnExtraCommandReceiver receiver = mOnExtraCommandReceivers.get(binder);
+ if (receiver == null) {
+ receiver = new OnExtraCommandReceiver(listener);
+ mOnExtraCommandReceivers.put(binder, receiver);
+ Log.d(TAG, "addOnExtraCommandListener(), new receiver added");
+ try {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "linkToDeath failed:", ex);
+ }
+ }
+ }
+
+ public void removeOnExtraCommandListener(IOnExtraCommandListener listener) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FM_RADIO_TRANSMITTER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires FM_RADIO_TRANSMITTER permission");
+ }
+
+ IBinder binder = listener.asBinder();
+ OnExtraCommandReceiver receiver = mOnExtraCommandReceivers.get(binder);
+ if (receiver != null) {
+ mOnExtraCommandReceivers.remove(receiver.mKey);
+ Log.d(TAG, "removeOnExtraCommandListener(), receiver removed");
+ receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ }
+ }
+
+ private void notifyOnStateChanged(int oldState, int newState) {
+ synchronized (mOnStateChangedReceivers) {
+ Collection c = mOnStateChangedReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnStateChangedReceiver m = (OnStateChangedReceiver) iterator.next();
+ m.callOnStateChanged(oldState, newState);
+ }
+ }
+ }
+
+ private void notifyOnStarted() {
+ synchronized (mOnStartedReceivers) {
+ Collection c = mOnStartedReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnStartedReceiver m = (OnStartedReceiver) iterator.next();
+ m.callOnStarted();
+ }
+ }
+ }
+
+ private void notifyOnError() {
+ synchronized (mOnErrorReceivers) {
+ Collection c = mOnErrorReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnErrorReceiver m = (OnErrorReceiver) iterator.next();
+ m.callOnError();
+ }
+ }
+ }
+
+ private void notifyOnBlockScan(int[] frequency, int[] signalLevel, boolean aborted) {
+ synchronized (mOnBlockScanReceivers) {
+ Collection c = mOnBlockScanReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnBlockScanReceiver m = (OnBlockScanReceiver) iterator.next();
+ m.callOnBlockScan(frequency, signalLevel, aborted);
+ }
+ }
+ }
+
+ private void notifyOnForcedPause() {
+ synchronized (mOnForcedPauseReceivers) {
+ Collection c = mOnForcedPauseReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnForcedPauseReceiver m = (OnForcedPauseReceiver) iterator.next();
+ m.callOnForcedPause();
+ }
+ }
+ }
+
+ private void notifyOnForcedReset(int reason) {
+ synchronized (mOnForcedResetReceivers) {
+ Collection c = mOnForcedResetReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnForcedResetReceiver m = (OnForcedResetReceiver) iterator.next();
+ m.callOnForcedReset(reason);
+ }
+ }
+ }
+
+ private void notifyOnExtraCommand(String response, Bundle extras) {
+ synchronized (mOnExtraCommandReceivers) {
+ Collection c = mOnExtraCommandReceivers.values();
+ Iterator iterator = c.iterator();
+ while (iterator.hasNext()) {
+ OnExtraCommandReceiver m = (OnExtraCommandReceiver) iterator.next();
+ m.callOnExtraCommand(response, extras);
+ }
+ }
+ }
+
+ private native void _fm_transmitter_start(int minFreq, int maxFreq, int defaultFreq, int offset);
+
+ private native void _fm_transmitter_startAsync(int minFreq, int maxFreq, int defaultFreq,
+ int offset);
+
+ private native int _fm_transmitter_reset();
+
+ private native void _fm_transmitter_pause();
+
+ private native void _fm_transmitter_resume();
+
+ private native int _fm_transmitter_getState();
+
+ private native void _fm_transmitter_setFrequency(int frequency);
+
+ private native int _fm_transmitter_getFrequency();
+
+ private native boolean _fm_transmitter_isBlockScanSupported();
+
+ private native void _fm_transmitter_startBlockScan(int startFrequency, int endFrequency);
+
+ private native void _fm_transmitter_stopScan();
+
+ private native void _fm_transmitter_setRdsData(Bundle rdsData);
+
+ private native boolean _fm_transmitter_sendExtraCommand(String command, String[] extras);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IFmReceiver.aidl b/fmradio/java/com/stericsson/hardware/fm/IFmReceiver.aidl
new file mode 100644
index 0000000..edf168e
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IFmReceiver.aidl
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import com.stericsson.hardware.fm.FmBand;
+import com.stericsson.hardware.fm.IOnStateChangedListener;
+import com.stericsson.hardware.fm.IOnStartedListener;
+import com.stericsson.hardware.fm.IOnErrorListener;
+import com.stericsson.hardware.fm.IOnScanListener;
+import com.stericsson.hardware.fm.IOnForcedPauseListener;
+import com.stericsson.hardware.fm.IOnForcedResetListener;
+import com.stericsson.hardware.fm.IOnRDSDataFoundListener;
+import com.stericsson.hardware.fm.IOnSignalStrengthListener;
+import com.stericsson.hardware.fm.IOnStereoListener;
+import com.stericsson.hardware.fm.IOnExtraCommandListener;
+import com.stericsson.hardware.fm.IOnAutomaticSwitchListener;
+
+/**
+ * {@hide}
+ */
+interface IFmReceiver
+{
+ void start(in FmBand band);
+ void startAsync(in FmBand band);
+ void reset();
+ void pause();
+ void resume();
+ int getState();
+ int getFrequency();
+ void setFrequency(int frequency);
+ void scanUp();
+ void scanDown();
+ void startFullScan();
+ void stopScan();
+ boolean isRDSDataSupported();
+ boolean isTunedToValidChannel();
+ void setThreshold(int threshold);
+ int getThreshold();
+ int getSignalStrength();
+ boolean isPlayingInStereo();
+ void setForceMono(boolean forceMono);
+ void setAutomaticAFSwitching(boolean automatic);
+ void setAutomaticTASwitching(boolean automatic);
+ boolean sendExtraCommand(String command, in String[] extras);
+ void addOnStateChangedListener(in IOnStateChangedListener listener);
+ void removeOnStateChangedListener(in IOnStateChangedListener listener);
+ void addOnStartedListener(in IOnStartedListener listener);
+ void removeOnStartedListener(in IOnStartedListener listener);
+ void addOnErrorListener(in IOnErrorListener listener);
+ void removeOnErrorListener(in IOnErrorListener listener);
+ void addOnScanListener(in IOnScanListener listener);
+ void removeOnScanListener(in IOnScanListener listener);
+ void addOnForcedPauseListener(in IOnForcedPauseListener listener);
+ void removeOnForcedPauseListener(in IOnForcedPauseListener listener);
+ void addOnForcedResetListener(in IOnForcedResetListener listener);
+ void removeOnForcedResetListener(in IOnForcedResetListener listener);
+ void addOnRDSDataFoundListener(in IOnRDSDataFoundListener listener);
+ void removeOnRDSDataFoundListener(in IOnRDSDataFoundListener listener);
+ void addOnSignalStrengthChangedListener(in IOnSignalStrengthListener listener);
+ void removeOnSignalStrengthChangedListener(in IOnSignalStrengthListener listener);
+ void addOnPlayingInStereoListener(in IOnStereoListener listener);
+ void removeOnPlayingInStereoListener(in IOnStereoListener listener);
+ void addOnExtraCommandListener(in IOnExtraCommandListener listener);
+ void removeOnExtraCommandListener(in IOnExtraCommandListener listener);
+ void addOnAutomaticSwitchListener(in IOnAutomaticSwitchListener listener);
+ void removeOnAutomaticSwitchListener(in IOnAutomaticSwitchListener listener);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IFmTransmitter.aidl b/fmradio/java/com/stericsson/hardware/fm/IFmTransmitter.aidl
new file mode 100644
index 0000000..6ca0cee
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IFmTransmitter.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import com.stericsson.hardware.fm.FmBand;
+import com.stericsson.hardware.fm.IOnStateChangedListener;
+import com.stericsson.hardware.fm.IOnStartedListener;
+import com.stericsson.hardware.fm.IOnErrorListener;
+import com.stericsson.hardware.fm.IOnBlockScanListener;
+import com.stericsson.hardware.fm.IOnForcedPauseListener;
+import com.stericsson.hardware.fm.IOnForcedResetListener;
+import com.stericsson.hardware.fm.IOnExtraCommandListener;
+import android.os.Bundle;
+
+/**
+ * {@hide}
+ */
+interface IFmTransmitter
+{
+ void start(in FmBand band);
+ void startAsync(in FmBand band);
+ void reset();
+ void pause();
+ void resume();
+ int getState();
+ int getFrequency();
+ void setFrequency(int frequency);
+ boolean isBlockScanSupported();
+ void startBlockScan(int startFrequency, int endFrequency);
+ void stopScan();
+ void setRdsData(in Bundle rdsData);
+ boolean sendExtraCommand(String command, in String[] extras);
+ void addOnStateChangedListener(in IOnStateChangedListener listener);
+ void removeOnStateChangedListener(in IOnStateChangedListener listener);
+ void addOnStartedListener(in IOnStartedListener listener);
+ void removeOnStartedListener(in IOnStartedListener listener);
+ void addOnErrorListener(in IOnErrorListener listener);
+ void removeOnErrorListener(in IOnErrorListener listener);
+ void addOnBlockScanListener(in IOnBlockScanListener listener);
+ void removeOnBlockScanListener(in IOnBlockScanListener listener);
+ void addOnForcedPauseListener(in IOnForcedPauseListener listener);
+ void removeOnForcedPauseListener(in IOnForcedPauseListener listener);
+ void addOnForcedResetListener(in IOnForcedResetListener listener);
+ void removeOnForcedResetListener(in IOnForcedResetListener listener);
+ void addOnExtraCommandListener(in IOnExtraCommandListener listener);
+ void removeOnExtraCommandListener(in IOnExtraCommandListener listener);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnAutomaticSwitchListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnAutomaticSwitchListener.aidl
new file mode 100644
index 0000000..8bf88ad
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnAutomaticSwitchListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Johan Palmaeus (johan.xj.palmaeus@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnAutomaticSwitchListener
+{
+ void onAutomaticSwitch(int newFrequency, int reason);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnBlockScanListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnBlockScanListener.aidl
new file mode 100644
index 0000000..ec39dea
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnBlockScanListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnBlockScanListener
+{
+ void onBlockScan(in int[] frequency, in int[] signalLevel, boolean aborted);
+} \ No newline at end of file
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnErrorListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnErrorListener.aidl
new file mode 100644
index 0000000..558600b
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnErrorListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnErrorListener
+{
+ void onError();
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnExtraCommandListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnExtraCommandListener.aidl
new file mode 100644
index 0000000..7647832
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnExtraCommandListener.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.os.Bundle;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnExtraCommandListener
+{
+ void onExtraCommand(String response, in Bundle extras);
+} \ No newline at end of file
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnForcedPauseListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnForcedPauseListener.aidl
new file mode 100644
index 0000000..bb8d876
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnForcedPauseListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnForcedPauseListener
+{
+ void onForcedPause();
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnForcedResetListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnForcedResetListener.aidl
new file mode 100644
index 0000000..4514501
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnForcedResetListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnForcedResetListener
+{
+ void onForcedReset(int reason);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnRDSDataFoundListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnRDSDataFoundListener.aidl
new file mode 100644
index 0000000..31b4801
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnRDSDataFoundListener.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+import android.os.Bundle;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnRDSDataFoundListener
+{
+ void onRDSDataFound(in Bundle options, int frequency);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnScanListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnScanListener.aidl
new file mode 100644
index 0000000..9996c1a
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnScanListener.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnScanListener
+{
+ void onScan(int tunedFrequency, int signalLevel, int scanDirection, boolean aborted);
+ void onFullScan(in int[] frequency, in int[] signalLevel, boolean aborted);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnSignalStrengthListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnSignalStrengthListener.aidl
new file mode 100644
index 0000000..431952b
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnSignalStrengthListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnSignalStrengthListener
+{
+ void onSignalStrengthChanged(int signalStrength);
+} \ No newline at end of file
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnStartedListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnStartedListener.aidl
new file mode 100644
index 0000000..b15ef09
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnStartedListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnStartedListener
+{
+ void onStarted();
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnStateChangedListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnStateChangedListener.aidl
new file mode 100644
index 0000000..3a63564
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnStateChangedListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnStateChangedListener
+{
+ void onStateChanged(int oldState, int newState);
+}
diff --git a/fmradio/java/com/stericsson/hardware/fm/IOnStereoListener.aidl b/fmradio/java/com/stericsson/hardware/fm/IOnStereoListener.aidl
new file mode 100644
index 0000000..ff2c977
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/IOnStereoListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Markus Grape (markus.grape@stericsson.com) for ST-Ericsson
+ */
+
+package com.stericsson.hardware.fm;
+
+/**
+ * {@hide}
+ */
+oneway interface IOnStereoListener
+{
+ void onPlayingInStereo(boolean inStereo);
+} \ No newline at end of file
diff --git a/fmradio/java/com/stericsson/hardware/fm/package.html b/fmradio/java/com/stericsson/hardware/fm/package.html
new file mode 100644
index 0000000..13c4a07
--- /dev/null
+++ b/fmradio/java/com/stericsson/hardware/fm/package.html
@@ -0,0 +1,13 @@
+<HTML>
+<BODY>
+Provides classes to receive and transmit FM Radio.
+<p>
+<lu>
+<li>FM Radio can be received by using the FmReceiver to control the reception and the MediaPlayer
+to play the FM Radio stream.</li>
+<li>FM Radio can be transmitted by using the FmTransmitter to control the output and the MediaPlayer
+to select the audio stream that will be transmitted.</li>
+</lu>
+</p>
+</BODY>
+</HTML>
diff --git a/fmradio/jni/Android.mk b/fmradio/jni/Android.mk
new file mode 100644
index 0000000..1b2643d
--- /dev/null
+++ b/fmradio/jni/Android.mk
@@ -0,0 +1,41 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ android_fmradio.cpp \
+ android_fmradio_Receiver.cpp \
+ android_fmradio_Transmitter.cpp
+
+LOCAL_C_INCLUDES += \
+ $(JNI_H_INCLUDE)\
+ $(TOP)/frameworks/base/fmradio/include \
+ $(TOP)/hardware/libhardware/include/hardware
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libhardware \
+ libhardware_legacy \
+ libnativehelper \
+ libsystem_server \
+ libutils \
+ libdl \
+ libui \
+ libmedia \
+
+ifeq ($(TARGET_SIMULATOR),true)
+ifeq ($(TARGET_OS),linux)
+ifeq ($(TARGET_ARCH),x86)
+LOCAL_LDLIBS += -lpthread -ldl -lrt
+endif
+endif
+endif
+
+ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
+ LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
+endif
+
+LOCAL_MODULE:= libanalogradiobroadcasting
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/fmradio/jni/android_fmradio.cpp b/fmradio/jni/android_fmradio.cpp
new file mode 100755
index 0000000..5dd9f72
--- /dev/null
+++ b/fmradio/jni/android_fmradio.cpp
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: johan.xj.palmaeus@stericsson.com for ST-Ericsson
+ */
+
+/*
+ * Native part of the generic TX-RX common FmRadio inteface
+ */
+
+
+#define ALOG_TAG "FmServiceNative"
+
+// #define ALOG_NDEBUG 1
+
+#include <dlfcn.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <utils/Log.h>
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "android_fmradio.h"
+
+#ifndef LIBRARY_PATH
+#define LIBRARY_PATH "/system/lib/"
+#endif
+
+#ifndef LIBRARY_PREFIX
+#define LIBRARY_PREFIX "libfmradio."
+#endif
+
+#ifndef LIBRARY_SUFFIX
+#define LIBRARY_SUFFIX ".so"
+#endif
+
+#ifndef LIBRARY_SUFFIX_RX
+#define LIBRARY_SUFFIX_RX "_rx.so"
+#endif
+
+#ifndef LIBRARY_SUFFIX_TX
+#define LIBRARY_SUFFIX_TX "_tx.so"
+#endif
+
+/* structs for passing startup arguments to threads */
+
+struct FmRadioStartAsyncParameters {
+ int (*startFunc) (void **, const struct fmradio_vendor_callbacks_t*, int, int, int,
+ int);
+ struct FmSession_t *session_p;
+ const struct fmradio_vendor_callbacks_t *callbacks_p;
+ int lowFreq;
+ int highFreq;
+ int defaultFreq;
+ int grid;
+};
+
+struct FmRadioSendExtraCommandParameters {
+ struct FmSession_t *session_p;
+ char* c_command;
+ char ** cparams;
+};
+
+
+pthread_mutex_t rx_tx_common_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+jobject extraCommandRetList2Bundle(JNIEnv * env_p, struct bundle_descriptor_offsets_t
+ *bundleOffsets_p,
+ struct fmradio_extra_command_ret_item_t *itemList)
+{
+ struct fmradio_extra_command_ret_item_t *listIterator = itemList;
+
+ jobject bundle = env_p->NewObject(bundleOffsets_p->mClass,
+ bundleOffsets_p->mConstructor);
+
+ while (listIterator && listIterator->key != NULL) {
+ switch (listIterator->type) {
+ case FMRADIO_TYPE_INT:
+ env_p->CallVoidMethod(bundle, bundleOffsets_p->mPutInt,
+ env_p->NewStringUTF(listIterator->key),
+ listIterator->data.int_value);
+ break;
+ case FMRADIO_TYPE_STRING:
+ env_p->CallVoidMethod(bundle, bundleOffsets_p->mPutString,
+ env_p->NewStringUTF(listIterator->key),
+ env_p->NewStringUTF(listIterator->data.string_value));
+ break;
+ default:
+ ALOGE("warning. Unknown command ret item type %d\n",
+ listIterator->type);
+ break;
+ }
+
+ listIterator++;
+ }
+ return bundle;
+}
+
+void freeExtraCommandRetList(struct fmradio_extra_command_ret_item_t *itemList)
+{
+ struct fmradio_extra_command_ret_item_t *listIterator = itemList;
+
+ while (listIterator && listIterator->key != NULL) {
+ free(listIterator->key);
+ if (listIterator->type == FMRADIO_TYPE_STRING) {
+ free(listIterator->data.string_value);
+ }
+ listIterator++;
+ }
+ free(itemList);
+
+}
+
+static bool jstringArray2cstringArray(JNIEnv * env_p, jobjectArray jarray,
+ char ***carray_p)
+{
+ int arrayLength;
+
+ if (jarray != NULL &&
+ (arrayLength = env_p->GetArrayLength(jarray)) > 0) {
+ int d;
+
+ char **carray = (char **) calloc(arrayLength + 1, sizeof(*carray));
+
+ if (carray == NULL) {
+ ALOGE("malloc failed\n");
+ return false;
+ }
+
+ for (d = 0; d < arrayLength; d++) {
+ const char *itemstr = env_p->GetStringUTFChars((jstring)
+ env_p->GetObjectArrayElement
+ (jarray, d),
+ NULL);
+
+ carray[d] = strdup(itemstr);
+ env_p->ReleaseStringUTFChars((jstring)
+ env_p->GetObjectArrayElement
+ (jarray, d), itemstr);
+ if (carray[d] == NULL) {
+ ALOGE("strdup failed\n");
+ /* free any arrays already allocated, free the array pointer
+ * and exit */
+ while (--d >= 0) {
+ free(carray[d]);
+ }
+ free(carray);
+ return false;
+ }
+ }
+ carray[arrayLength] = NULL; /* to be able to detect end of array */
+ *carray_p = carray;
+ } else {
+ *carray_p = NULL;
+ }
+
+ return true;
+}
+
+static void freeCstringArray(char **cstringarray)
+{
+ if (cstringarray != NULL && *cstringarray != NULL) {
+ char **iterator = cstringarray;
+
+ while (*iterator != NULL) {
+ free(*iterator);
+ iterator++;
+ }
+ free(cstringarray);
+
+ }
+}
+
+/*
+ * Function to temporary resume a paused device for executing command
+ */
+void androidFmRadioTempResumeIfPaused(struct FmSession_t *session_p)
+{
+ if (session_p->state == FMRADIO_STATE_PAUSED) {
+ /* no need to handle error here, the main command will fail anyway */
+ (void)session_p->vendorMethods_p->resume(&session_p->vendorData_p);
+ }
+}
+
+/*
+ * Function to pause device after a temporary resume
+ */
+void androidFmRadioPauseIfTempResumed(struct FmSession_t *session_p)
+{
+ if (session_p->state == FMRADIO_STATE_PAUSED) {
+ if (session_p->vendorMethods_p->pause(&session_p->vendorData_p)
+ != FMRADIO_OK) {
+ ALOGE("androidFmRadioPauseIfTempResumed: pause failed, force "
+ "resetting");
+ /*
+ * Failed to set pause again. Since the device is supposed to be
+ * paused we can't leave it this way, our best choice is to issue
+ * a force reset to put the device in a known idle state. Temporary
+ * drop locks since we might trigger callbacks.
+ */
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_IDLE);
+ /* temporary drop lock to allow reset triggered callbacks */
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ int retval = session_p->vendorMethods_p->reset(&session_p->vendorData_p);
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ if (retval != FMRADIO_OK) {
+ ALOGE("androidFmRadioPauseIfTempResumed: CRITICAL ERROR: "
+ "can't reset device");
+ /* if we can't even reset we have a critical problem */
+ session_p->callbacks_p->onForcedReset(FMRADIO_RESET_CRITICAL);
+ } else {
+ /* now we are in known state */
+ session_p->callbacks_p->onForcedReset(FMRADIO_RESET_NON_CRITICAL);
+ }
+
+ /* unload vendor driver */
+ androidFmRadioUnLoadFmLibrary(session_p);
+ session_p->isRegistered = false;
+ }
+ }
+}
+
+bool
+androidFmRadioIsValidEventForState(struct FmSession_t *session_p,
+ enum FmRadioCommand_t event)
+{
+ bool retval;
+
+ if (!session_p->isRegistered && (event != FMRADIO_EVENT_RESET) &&
+ (event != FMRADIO_EVENT_START) && (event != FMRADIO_EVENT_START_ASYNC)) {
+ ALOGE("ERROR - library not loaded, only reset, start and start async are valid events");
+ retval = false;
+ } else if (session_p->ongoingReset && (event != FMRADIO_EVENT_RESET)) {
+ ALOGE("ERROR - ongoing reset invalidates state changes");
+ retval = false;
+ } else if (!(*session_p->validEventsForStates_p)[event][session_p->state]) {
+ ALOGE("ERROR - Invalid event %u for state %u", event,
+ session_p->state);
+ retval = false;
+ } else {
+ retval = true;
+ }
+
+ return retval;
+}
+
+void
+androidFmRadioThrowException(struct FmSession_t *session_p,
+ const char *exception,
+ const char *message, const char *file,
+ int line, const char *function)
+{
+ bool reAttached = false;
+
+ JNIEnv *env;
+
+ ALOGI("androidFmRadioThrowException, %s ('%s') @ %s %d (%s)\n",
+ exception, message, file, line, function);
+
+
+ if (session_p->jvm_p->GetEnv((void **) &env, JNI_VERSION_1_4) !=
+ JNI_OK) {
+ /* we are probably a subthread. Attach instead */
+ if (session_p->jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread\n");
+ return;
+ }
+ reAttached = true;
+ }
+
+ jniThrowException(env, exception, message);
+
+ if (reAttached) {
+ session_p->jvm_p->DetachCurrentThread();
+ }
+
+}
+
+
+/*
+ * Functions for loading and unloading the vendor dynamic library
+ * (libfmradio.xxxxxx.so)
+ */
+
+static bool
+androidFmRadioGetLibraryName(enum RadioMode_t mode,
+ char *libraryName)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ char foundName[sizeof(dp->d_name)] = "";
+
+ if ((dirp = opendir(LIBRARY_PATH)) == NULL) {
+ ALOGE("couldn't open path '%s'", LIBRARY_PATH);
+ return false;
+ }
+
+ errno = 0;
+
+ while ((dp = readdir(dirp)) != NULL) {
+ char *name = dp->d_name;
+ size_t nameLength = strlen(name);
+
+ /*
+ * since prefix end with . and suffix start with . we need to make sure
+ * we don't get a match on something that is shorter than the two
+ * strings concatinated
+ */
+ if (nameLength < sizeof(LIBRARY_PREFIX) + sizeof(LIBRARY_SUFFIX) - 2) {
+ continue;
+ }
+
+ if ((nameLength > sizeof(LIBRARY_SUFFIX) -1) &&
+ (strcmp(name + nameLength - sizeof(LIBRARY_SUFFIX) + 1,
+ LIBRARY_SUFFIX) == 0)) {
+ } else {
+ continue;
+ }
+
+ if (strncmp(name, LIBRARY_PREFIX, sizeof(LIBRARY_PREFIX) - 1) != 0) {
+ /* prefix doesn't match, this is not our file */
+ continue;
+ }
+
+
+ /* check if it is RX/TX specific or general */
+
+ if ((nameLength > sizeof(LIBRARY_SUFFIX_RX) -1) &&
+ (strcmp(name + nameLength - sizeof(LIBRARY_SUFFIX_RX) + 1,
+ LIBRARY_SUFFIX_RX) == 0)) {
+ if (mode == FMRADIO_RX) {
+ strcpy(foundName, name);
+ break;
+ }
+ } else if ((nameLength > sizeof(LIBRARY_SUFFIX_TX) -1) &&
+ (strcmp(name + nameLength - sizeof(LIBRARY_SUFFIX_TX) + 1,
+ LIBRARY_SUFFIX_TX) == 0)) {
+ if (mode == FMRADIO_TX) {
+ strcpy(foundName, name);
+ break;
+ }
+ } else {
+ strcpy(foundName, name);
+ /* do not break, if there is a rx/tx specific name we prefer it */
+ }
+ }
+
+ (void)closedir(dirp);
+
+ if (dp == NULL && errno != 0) {
+ ALOGE("error reading directory, errno = %d\n", errno);
+ return false;
+ }
+
+ if (foundName[0] == '\0') {
+ ALOGE("No matching library found in path %s\n", LIBRARY_PATH);
+ return false;
+ }
+
+ // copy name with file path
+ strcpy(libraryName, LIBRARY_PATH);
+ // add slash if not last of path
+ if (libraryName[strlen(libraryName) -1] != '/') {
+ strcat(libraryName, "/");
+ }
+ strcat(libraryName, foundName);
+ return true;
+}
+
+bool
+androidFmRadioLoadFmLibrary(struct FmSession_t * session_p,
+ enum RadioMode_t mode)
+{
+ char fmLibName[FM_LIBRARY_NAME_MAX_LENGTH + 1] = "";
+ fmradio_reg_func_t fmRegFunc = NULL;
+ unsigned int magicVal = 0;
+ bool retval = false;
+ bool missingMandatoryFunctions = false;
+
+ // read library directory and find matching library
+
+ if (!androidFmRadioGetLibraryName(mode, fmLibName)) {
+ goto funcret;
+ }
+
+ // load the library
+ session_p->fmLibrary_p = dlopen(fmLibName, RTLD_LAZY);
+ if (session_p->fmLibrary_p == NULL) {
+ ALOGI("Could not load library '%s'\n", fmLibName);
+ goto funcret;
+ } else {
+ ALOGI("Loaded library %s\n", fmLibName);
+ }
+
+ // now we have loaded the library, check for function
+ fmRegFunc = (fmradio_reg_func_t) dlsym(session_p->fmLibrary_p,
+ FMRADIO_REGISTER_FUNC);
+
+ if (fmRegFunc == NULL) {
+ ALOGE("Could not find symbol '%s' in loaded library '%s'\n",
+ FMRADIO_REGISTER_FUNC, fmLibName);
+ goto closelib;
+ }
+
+ // call function
+ if (fmRegFunc(&magicVal, session_p->vendorMethods_p) != 0) {
+ ALOGE("Loaded function '%s' returned unsuccessful\n",
+ FMRADIO_REGISTER_FUNC);
+ goto closelib;
+ }
+
+ // just to make sure correct function was called
+ if (magicVal != FMRADIO_SIGNATURE) {
+ ALOGE("Loaded function '%s' returned successful but failed setting magic value\n", FMRADIO_REGISTER_FUNC);
+ goto closelib;
+ }
+
+ // some methods are considered mandatory to implement, check them
+
+ if(mode == FMRADIO_RX && session_p->vendorMethods_p->rx_start == NULL) {
+ missingMandatoryFunctions = true;
+ ALOGE("Mandatory method rx_start is not implemented\n");
+ }
+ if(mode == FMRADIO_TX && session_p->vendorMethods_p->tx_start == NULL) {
+ missingMandatoryFunctions = true;
+ ALOGE("Mandatory method tx_start is not implemented\n");
+ }
+ if(session_p->vendorMethods_p->pause == NULL) {
+ missingMandatoryFunctions = true;
+ ALOGE("Mandatory method pause is not implemented\n");
+ }
+ if(session_p->vendorMethods_p->resume == NULL) {
+ missingMandatoryFunctions = true;
+ ALOGE("Mandatory method resume is not implemented\n");
+ }
+ if(session_p->vendorMethods_p->reset == NULL) {
+ missingMandatoryFunctions = true;
+ ALOGE("Mandatory method reset is not implemented\n");
+ }
+ if(missingMandatoryFunctions) {
+ goto closelib;
+ }
+
+ retval = true;
+ goto funcret;
+ closelib:
+ dlclose(session_p->fmLibrary_p);
+ funcret:
+ return retval;
+}
+
+void
+androidFmRadioUnLoadFmLibrary(struct FmSession_t * session_p)
+{
+
+ if (session_p->fmLibrary_p != NULL) {
+ dlclose(session_p->fmLibrary_p);
+ free(session_p->vendorMethods_p);
+ session_p->vendorMethods_p = NULL;
+ }
+}
+
+/* methods common for both RX and TX */
+
+static bool androidFmRadioStartSyncPartner(struct FmSession_t *session_p)
+{
+ /* lock is held when entering this mehod */
+ int maxTime = 5000; /* in ms */
+
+ /* if partner has ongoing reset await it finishing */
+ while (session_p->partnerSession_p->ongoingReset && maxTime > 0) {
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ usleep(250000);
+ pthread_mutex_lock(session_p->dataMutex_p);
+ maxTime -= 250;
+ }
+
+ if (session_p->partnerSession_p->ongoingReset) {
+ ALOGE("partner session stale reset");
+ return false;
+ }
+
+ /* if partner has any other state than IDLE it should be stoped */
+ if (session_p->partnerSession_p->state != FMRADIO_STATE_IDLE) {
+ /* if partner is starting it must be allowed to finish */
+
+ session_p->partnerSession_p->ongoingReset = true; /* to make sure it doesn't do anything else */
+
+ while (!session_p->ongoingReset &&
+ (session_p->partnerSession_p->state == FMRADIO_STATE_STARTING && maxTime > 0)){
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ usleep(250000);
+ pthread_mutex_lock(session_p->dataMutex_p);
+ maxTime -= 250;
+ }
+
+ session_p->partnerSession_p->ongoingReset = false;
+
+ /* if we now have a ongoing reset on our own session just exit */
+
+ if (session_p->ongoingReset) {
+ return false;
+ }
+
+ /* if partner is still starting we should exist */
+ if (session_p->partnerSession_p->state == FMRADIO_STATE_STARTING) {
+ ALOGE("time-out waiting for partner startup");
+ return false;
+ }
+
+ /* unless partner already is IDLE, reset and send forced reset */
+ if (session_p->partnerSession_p->state != FMRADIO_STATE_IDLE) {
+ /* temporary drop lock to allow reset triggered callbacks */
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ session_p->partnerSession_p->vendorMethods_p->reset(&session_p->partnerSession_p->vendorData_p);
+ pthread_mutex_lock(session_p->dataMutex_p);
+ FMRADIO_SET_STATE(session_p->partnerSession_p, FMRADIO_STATE_IDLE);
+ session_p->partnerSession_p->callbacks_p->onForcedReset(FMRADIO_RESET_OTHER_IN_USE);
+ }
+ /* unload partner vendor driver */
+ if (session_p->partnerSession_p->isRegistered) {
+ androidFmRadioUnLoadFmLibrary(session_p->partnerSession_p);
+ session_p->partnerSession_p->isRegistered = false;
+ }
+ }
+
+ return true;
+}
+
+static void *execute_androidFmRadioStartAsync(void *args)
+{
+ struct FmRadioStartAsyncParameters *inArgs_p = (struct FmRadioStartAsyncParameters *)args;
+
+ int (*startFunc) (void **, const struct fmradio_vendor_callbacks_t *, int, int, int,
+ int) = inArgs_p->startFunc;
+ struct FmSession_t *session_p = inArgs_p->session_p;
+
+ const struct fmradio_vendor_callbacks_t *callbacks_p = inArgs_p->callbacks_p;
+
+ int lowFreq = inArgs_p->lowFreq;
+ int highFreq = inArgs_p->highFreq;
+ int defaultFreq = inArgs_p->defaultFreq;
+ int grid = inArgs_p->grid;
+ int retval = 0;
+
+ free(inArgs_p);
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ /*
+ * if other session is starting should wait for them to finish unless we
+ * get a ongoing reset
+ */
+
+ if (!androidFmRadioStartSyncPartner(session_p)) {
+ retval = -1;
+ goto fix_state_and_send_retval;
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+
+ retval =
+ startFunc(&session_p->vendorData_p, callbacks_p, lowFreq, highFreq,
+ defaultFreq, grid);
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+ /* sanity check, not even reset should alter the state when starting */
+ if (session_p->state != FMRADIO_STATE_STARTING) {
+ ALOGE("state not starting when going to started...");
+ retval = -1;
+ }
+
+ fix_state_and_send_retval:
+ if (retval >= 0) {
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_STARTED);
+ } else {
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_IDLE);
+ /* unload vendor driver */
+ androidFmRadioUnLoadFmLibrary(session_p);
+ session_p->isRegistered = false;
+ }
+
+ /*
+ * these need to be called after state is updated and after the lock
+ * has been dropped
+ */
+ if (retval >= 0) {
+ session_p->callbacks_p->onStarted();
+ } else {
+ session_p->callbacks_p->onError();
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+
+ pthread_exit(NULL);
+ return NULL;
+}
+
+int
+androidFmRadioStart(struct FmSession_t *session_p, enum RadioMode_t mode,
+ const struct fmradio_vendor_callbacks_t *callbacks_p,
+ bool async, int lowFreq, int highFreq, int defaultFreq,
+ int grid)
+{
+ int retval = 0;
+
+ int (*startFunc) (void **, const struct fmradio_vendor_callbacks_t *,
+ int, int, int, int) = NULL;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_START)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+ // set our state to STARTING here to make sure the partner session
+ // can't start again after it is finished
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_STARTING);
+
+ // if we haven't registred the library yet do it
+
+ if (!session_p->isRegistered) {
+ session_p->vendorMethods_p = (fmradio_vendor_methods_t *)
+ malloc(sizeof(*session_p->vendorMethods_p));
+ if (session_p->vendorMethods_p == NULL) {
+ ALOGE("malloc failed");
+ retval = FMRADIO_IO_ERROR;
+ goto early_exit;
+ } else if (androidFmRadioLoadFmLibrary(session_p, mode)) {
+ session_p->isRegistered = true;
+ } else {
+ ALOGE("vendor registration failed");
+ free(session_p->vendorMethods_p);
+ retval = FMRADIO_IO_ERROR;
+ goto early_exit;
+ }
+ }
+
+ if (mode == FMRADIO_RX) {
+ startFunc = session_p->vendorMethods_p->rx_start;
+ } else if (mode == FMRADIO_TX) {
+ startFunc = session_p->vendorMethods_p->tx_start;
+ }
+
+ if (!startFunc) {
+ ALOGE("androidFmRadioStart - ERROR - No valid start function found.");
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ goto early_exit;
+ }
+
+ if (async) {
+ pthread_t execute_thread;
+
+ struct FmRadioStartAsyncParameters *args_p = (struct FmRadioStartAsyncParameters *)
+ malloc(sizeof(struct FmRadioStartAsyncParameters)); /* freed in created thread */
+
+ if (args_p == NULL) {
+ ALOGE("malloc failed");
+ retval = FMRADIO_IO_ERROR;
+ goto early_exit;
+ }
+
+ args_p->startFunc = startFunc;
+ args_p->session_p = session_p;
+ args_p->callbacks_p = callbacks_p;
+ args_p->lowFreq = lowFreq;
+ args_p->highFreq = highFreq;
+ args_p->defaultFreq = defaultFreq;
+ args_p->grid = grid;
+
+ // we need to create a new thread actually executing the command
+ if (pthread_create
+ (&execute_thread, NULL, execute_androidFmRadioStartAsync,
+ (void *) args_p) != 0) {
+ ALOGE("pthread_create failure...");
+ free(args_p);
+ retval = FMRADIO_IO_ERROR;
+ } else {
+ pthread_detach(execute_thread);
+ }
+ } else {
+ if (!androidFmRadioStartSyncPartner(session_p)) {
+ retval = -1;
+ goto early_exit;
+ }
+
+ /*
+ * drop lock during long time call but set state to make sure no other
+ * process tries to start while we are starting. Do not use
+ * FMRADIO_SET_STATE macro since it will trigger a onStateChanged
+ * callback
+ */
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ retval =
+ startFunc(&session_p->vendorData_p, callbacks_p, lowFreq,
+ highFreq, defaultFreq, grid);
+ /* regain lock */
+ pthread_mutex_lock(session_p->dataMutex_p);
+ /* check that nothing has happened before we regained the lock */
+ if (session_p->state != FMRADIO_STATE_STARTING) {
+ ALOGE("Error, radio not in IDLE when about to set started mode");
+ }
+ }
+
+ // if successful syncronous start update state
+ if (retval == 0 && !async) {
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_STARTED);
+ }
+
+ early_exit:
+
+ if (retval < 0) {
+ if (session_p->state != FMRADIO_STATE_IDLE) {
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_IDLE);
+ }
+
+ if (retval != FMRADIO_INVALID_STATE && session_p->isRegistered) {
+ androidFmRadioUnLoadFmLibrary(session_p);
+ session_p->isRegistered = false;
+ }
+ }
+
+ drop_lock:
+
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(session_p);
+ } else if ((retval == FMRADIO_INVALID_PARAMETER) ||
+ (retval == FMRADIO_UNSUPPORTED_OPERATION)) {
+ THROW_UNSUPPORTED_OPERATION(session_p);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(session_p);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+
+ return retval;
+}
+
+int androidFmRadioPause(struct FmSession_t *session_p)
+{
+ int retval;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_PAUSE)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (session_p->state == FMRADIO_STATE_PAUSED) {
+ // already paused, just return
+ retval = FMRADIO_OK;
+ goto drop_lock;
+ }
+
+
+ retval = session_p->vendorMethods_p->pause(&session_p->vendorData_p);
+
+ if (retval == 0) {
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_PAUSED);
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(session_p);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(session_p);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+
+ return retval;
+}
+
+int androidFmRadioResume(struct FmSession_t *session_p)
+{
+ int retval = 0;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_RESUME)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (session_p->state == FMRADIO_STATE_STARTED) {
+ //already started, just return
+ retval = FMRADIO_OK;
+ goto drop_lock;
+ }
+
+ retval = session_p->vendorMethods_p->resume(&session_p->vendorData_p);
+
+ // if successful update state
+ if (retval == 0) {
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_STARTED);
+ }
+ // nothing on failure
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(session_p);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(session_p);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ return retval;
+}
+
+int androidFmRadioReset(struct FmSession_t *session_p)
+{
+ int retval = FMRADIO_OK;
+ int oldState = session_p->state;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_RESET)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ /* Worker threads must be cleaned up before sending reset */
+ if(session_p->state == FMRADIO_STATE_SCANNING){
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ androidFmRadioStopScan(session_p);
+ pthread_mutex_lock(session_p->dataMutex_p);
+ /* Waiting for worker thread to exit gracefully */
+ pthread_cond_wait(&session_p->sync_cond,
+ session_p->dataMutex_p);
+ }
+ /* idle or about to be reset, just return state */
+ if (session_p->ongoingReset || oldState == FMRADIO_STATE_IDLE) {
+ retval = oldState;
+ goto drop_lock;
+ }
+ session_p->ongoingReset = true;
+
+ /* if we are in starting state we must await the start finishing */
+ if (oldState == FMRADIO_STATE_STARTING) {
+ /* we need to await end of start before starting */
+ int maxTime = 5000; /* in ms */
+ do {
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ usleep(250000);
+ pthread_mutex_lock(session_p->dataMutex_p);
+ maxTime -= 250;
+ } while (maxTime > 0 && (session_p->state == FMRADIO_STATE_STARTING));
+ }
+
+ /* if we still are in STARTING state we must fail now */
+ if (session_p->state == FMRADIO_STATE_STARTING) {
+ retval = FMRADIO_IO_ERROR;
+ goto drop_ongoing_reset;
+ }
+
+ /*
+ * we need to temporary release lock since reset might trigger
+ * callbacks. Set flag to not allow any state changing command
+ */
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_IDLE);
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ retval = session_p->vendorMethods_p->
+ reset(&session_p->vendorData_p);
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ // if successful unload vendor driver
+ if (retval >= 0) {
+ retval = oldState;
+ if (session_p->isRegistered) {
+ androidFmRadioUnLoadFmLibrary(session_p);
+ session_p->isRegistered = false;
+ }
+ } else {
+ ALOGE("androidFmRadioReset failed");
+ }
+ // nothing on failure
+ drop_ongoing_reset:
+ session_p->ongoingReset = false;
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(session_p);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(session_p);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+
+ return retval;
+}
+
+void
+androidFmRadioSetFrequency(struct FmSession_t *session_p, int frequency)
+{
+ int retval = 0;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_SET_FREQUENCY)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (session_p->vendorMethods_p->set_frequency) {
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(session_p);
+
+ retval =
+ session_p->vendorMethods_p->set_frequency(&session_p->
+ vendorData_p,
+ frequency);
+
+ androidFmRadioPauseIfTempResumed(session_p);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ // no state is ever updated
+ if (retval < 0) {
+ ALOGE("androidFmRadioSetFrequency failed\n");
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(session_p);
+ } else if (retval == FMRADIO_INVALID_PARAMETER) {
+ THROW_ILLEGAL_ARGUMENT(session_p);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(session_p);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+}
+
+int androidFmRadioGetFrequency(struct FmSession_t *session_p)
+{
+ int retval = 0;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_GET_FREQUENCY)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (session_p->vendorMethods_p->get_frequency) {
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(session_p);
+
+ retval =
+ session_p->vendorMethods_p->get_frequency(&session_p->
+ vendorData_p);
+
+ androidFmRadioPauseIfTempResumed(session_p);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(session_p);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(session_p);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+
+ return retval;
+}
+
+void androidFmRadioStopScan(struct FmSession_t *session_p)
+{
+ int retval = 0;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_STOP_SCAN)) {
+ goto drop_lock;
+ }
+
+ if (session_p->state != FMRADIO_STATE_SCANNING) {
+ /* if we're not in scanning, don't attempt anything just return */
+ goto drop_lock;
+ }
+
+ if (session_p->vendorMethods_p->stop_scan) {
+ retval =
+ session_p->vendorMethods_p->stop_scan(&session_p->vendorData_p);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ if (retval == 0) {
+ session_p->lastScanAborted = true;
+ }
+
+ retval = FMRADIO_OK;
+ drop_lock:
+ /* note - no exceptions. Just return */
+
+ if (retval != FMRADIO_OK) {
+ ALOGE("androidFmRadioStopScan failed (%d), ignored.\n", retval);
+ }
+ pthread_mutex_unlock(session_p->dataMutex_p);
+}
+
+static void *execute_androidFmRadioSendExtraCommand(void *args_p)
+{
+ struct FmRadioSendExtraCommandParameters* inArgs_p = (struct FmRadioSendExtraCommandParameters*)args_p;
+ struct FmSession_t *session_p = inArgs_p->session_p;
+ char *c_command = inArgs_p->c_command;
+ char **parameter = inArgs_p->cparams;
+ struct fmradio_extra_command_ret_item_t *returnParam = NULL;
+ int retval;
+
+ free(inArgs_p);
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ // we should be in state EXTRA_COMMAND
+ if (session_p->state != FMRADIO_STATE_EXTRA_COMMAND) {
+ ALOGE("execute_androidFmRadioSendExtraCommand - warning, state not extra commands\n");
+ }
+
+ if (session_p->vendorMethods_p->send_extra_command != NULL) {
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ retval =
+ session_p->vendorMethods_p->send_extra_command(&session_p->
+ vendorData_p,
+ c_command,
+ parameter,
+ &returnParam);
+ pthread_mutex_lock(session_p->dataMutex_p);
+ freeCstringArray(parameter);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ if (session_p->state != FMRADIO_STATE_EXTRA_COMMAND) {
+ ALOGE("State changed while executing extra commands (state now %d), keeping\n", session_p->state);
+ } else {
+ if (session_p->pendingPause) {
+ session_p->vendorMethods_p->pause(&session_p->
+ vendorData_p);
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_PAUSED);
+ } else {
+ FMRADIO_SET_STATE(session_p, session_p->oldState);
+ }
+ }
+
+ session_p->pendingPause = false;
+
+ if (retval >= 0) {
+ session_p->callbacks_p->onSendExtraCommand(c_command, returnParam);
+ } else {
+ session_p->callbacks_p->onError();
+ }
+
+ if (returnParam != NULL) {
+ freeExtraCommandRetList(returnParam);
+ }
+
+ if (c_command != NULL) {
+ free(c_command);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+ pthread_exit(NULL);
+ return NULL;
+}
+
+void
+androidFmRadioSendExtraCommand(struct FmSession_t *session_p,
+ JNIEnv * env_p, jstring jcommand,
+ jobjectArray parameter)
+{
+ int retval = FMRADIO_OK;
+ char **cparams;
+ struct FmRadioSendExtraCommandParameters *args_p = NULL;
+ pthread_t execute_thread;
+
+ pthread_mutex_lock(session_p->dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (session_p, FMRADIO_EVENT_EXTRA_COMMAND)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (!jstringArray2cstringArray(env_p, parameter, &cparams)) {
+ retval = FMRADIO_IO_ERROR;
+ goto drop_lock;
+ }
+
+ session_p->oldState = session_p->state;
+
+ args_p = (struct FmRadioSendExtraCommandParameters *) malloc(sizeof(struct FmRadioSendExtraCommandParameters)); /* freed in created thread */
+ if (args_p == NULL) {
+ ALOGE("malloc failed\n");
+ retval = FMRADIO_IO_ERROR;
+ }
+
+ if (retval == FMRADIO_OK) {
+ const char* c_command = env_p->GetStringUTFChars(jcommand, 0);
+
+ args_p->session_p = session_p;
+ args_p->c_command = strdup(c_command);
+ args_p->cparams = cparams;
+
+ env_p->ReleaseStringUTFChars(jcommand, c_command);
+
+ // we need to create a new thread actually executing the command
+ if (pthread_create
+ (&execute_thread, NULL, execute_androidFmRadioSendExtraCommand,
+ args_p) != 0) {
+ ALOGE("pthread_create failed\n");
+ free(args_p->c_command);
+ free(args_p);
+ retval = FMRADIO_IO_ERROR;
+ } else {
+ pthread_detach(execute_thread);
+ }
+
+ }
+
+ if (retval == FMRADIO_OK) {
+ FMRADIO_SET_STATE(session_p, FMRADIO_STATE_EXTRA_COMMAND);
+ }
+
+ drop_lock:
+
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(session_p);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(session_p);
+ }
+
+ pthread_mutex_unlock(session_p->dataMutex_p);
+}
+
+
+namespace android {
+int registerAndroidFmRadioReceiver(JavaVM* vm, JNIEnv *env);
+int registerAndroidFmRadioTransmitter(JavaVM* vm, JNIEnv *env);
+};
+
+using namespace android;
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ ALOGE("GetEnv failed!");
+ return result;
+ }
+ ALOG_ASSERT(env, "Could not retrieve the env!");
+
+ registerAndroidFmRadioReceiver(vm, env);
+ registerAndroidFmRadioTransmitter(vm, env);
+
+ return JNI_VERSION_1_4;
+}
diff --git a/fmradio/jni/android_fmradio_Receiver.cpp b/fmradio/jni/android_fmradio_Receiver.cpp
new file mode 100755
index 0000000..78e3e16
--- /dev/null
+++ b/fmradio/jni/android_fmradio_Receiver.cpp
@@ -0,0 +1,1494 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Authors: johan.xj.palmaeus@stericsson.com
+ * stuart.macdonald@stericsson.com
+ * for ST-Ericsson
+ */
+
+/*
+ * Native part of the generic RX FmRadio inteface
+ */
+
+#define ALOG_TAG "FmReceiverServiceNative"
+
+// #define LOG_NDEBUG 1
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <termios.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <pthread.h>
+#include <math.h>
+
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_fmradio.h"
+#include <utils/Log.h>
+
+
+/* *INDENT-OFF* */
+namespace android {
+
+
+// state machine
+
+static const ValidEventsForStates_t IsValidRxEventForState = {
+ /* this table defines valid transitions. (turn off indent, we want this easy readable) */
+ /* FMRADIO_STATE_ IDLE,STARTING,STARTED,PAUSED,SCANNING,EXTRA_COMMAND */
+
+ /* FMRADIO_EVENT_START */ {true ,false,false,false,false,false},
+ /* FMRADIO_EVENT_START_ASYNC */ {true ,false,false,false,false,false},
+ /* FMRADIO_EVENT_PAUSE */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_RESUME */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_RESET */ {true, true, true, true, true, true },
+ /* FMRADIO_EVENT_GET_FREQUENCY */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_SET_FREQUENCY */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_SET_PARAMETER */ {false,false,true, true, true, true },
+ /* FMRADIO_EVENT_STOP_SCAN */ {true, true, true, true, true, true },
+ /* FMRADIO_EVENT_EXTRA_COMMAND */ {true, true, true, true, true, true },
+ /* Rx Only */
+ /* FMRADIO_EVENT_GET_PARAMETER */ {false,false,true, true, true, true },
+ /* FMRADIO_EVENT_GET_SIGNAL_STRENGTH */{false,false,true,true,false,false},
+ /* FMRADIO_EVENT_SCAN */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_FULL_SCAN */ {false,false,true, true, false,false},
+ // Tx Only - never allowed
+ /* FMRADIO_EVENT_BLOCK_SCAN */ {false,false,false,false,false,false},
+};
+/* *INDENT-ON* */
+
+/* Callbacks to java layer */
+
+static void androidFmRadioRxCallbackOnStateChanged(int oldState,
+ int newState);
+static void androidFmRadioRxCallbackOnError(void);
+
+static void androidFmRadioRxCallbackOnStarted(void);
+
+static void androidFmRadioRxCallbackOnScan(int foundFreq,
+ int signalStrength,
+ int scanDirection,
+ bool aborted);
+static void androidFmRadioRxCallbackOnFullScan(int noItems,
+ int *frequencies,
+ int *sigStrengths,
+ bool aborted);
+static void androidFmRadioRxCallbackOnForcedReset(enum fmradio_reset_reason_t reason);
+
+static void androidFmRadioRxCallbackOnVendorForcedReset(enum fmradio_reset_reason_t reason);
+
+static void androidFmRadioRxCallbackOnSignalStrengthChanged(int newLevel);
+
+static void androidFmRadioRxCallbackOnRDSDataFound(struct
+ fmradio_rds_bundle_t
+ *t, int frequency);
+
+static void androidFmRadioRxCallbackOnPlayingInStereo(int
+ isPlayingInStereo);
+
+static void androidFmRadioRxCallbackOnExtraCommand(char* command,
+ struct
+ fmradio_extra_command_ret_item_t
+ *retItem);
+
+static void androidFmRadioRxCallbackOnAutomaticSwitch(int newFrequency, enum fmradio_switch_reason_t reason);
+
+static const FmRadioCallbacks_t FmRadioRxCallbacks = {
+ androidFmRadioRxCallbackOnStateChanged,
+ androidFmRadioRxCallbackOnError,
+ androidFmRadioRxCallbackOnStarted,
+ androidFmRadioRxCallbackOnScan,
+ androidFmRadioRxCallbackOnFullScan,
+ NULL,
+ androidFmRadioRxCallbackOnForcedReset,
+ androidFmRadioRxCallbackOnExtraCommand,
+};
+
+/* callbacks from vendor layer */
+
+static const fmradio_vendor_callbacks_t FmRadioRxVendorCallbacks = {
+ androidFmRadioRxCallbackOnPlayingInStereo,
+ androidFmRadioRxCallbackOnRDSDataFound,
+ androidFmRadioRxCallbackOnSignalStrengthChanged,
+ androidFmRadioRxCallbackOnAutomaticSwitch,
+ androidFmRadioRxCallbackOnVendorForcedReset
+};
+
+extern struct FmSession_t fmTransmitterSession;
+
+struct FmSession_t fmReceiverSession = {
+ NULL,
+ NULL,
+ false,
+ FMRADIO_STATE_IDLE,
+ NULL,
+ &IsValidRxEventForState,
+ &FmRadioRxCallbacks,
+ NULL,
+ NULL,
+ &fmTransmitterSession,
+ NULL,
+ FMRADIO_STATE_IDLE,
+ false,
+ false,
+ false,
+ &rx_tx_common_mutex,
+ PTHREAD_COND_INITIALIZER,
+ NULL,
+};
+
+// make sure we don't refer the TransmitterSession anymore from here
+#define fmTransmitterSession ERRORDONOTUSERECEIVERSESSIONINTRANSMITTER
+
+/*
+* Implementation of callbacks from within service layer. For these the
+* mutex lock is always held on entry and need to be released before doing
+* calls to java layer (env->Call*Method) becasue these might trigger new
+* calls from java and a deadlock would occure if lock was still held.
+*/
+
+static void androidFmRadioRxCallbackOnStateChanged(int oldState,
+ int newState)
+{
+ jmethodID notifyOnStateChangedMethod;
+ JNIEnv *env;
+ jclass clazz;
+ bool reAttached = false;
+
+ ALOGI("androidFmRadioRxCallbackOnStateChanged: Old state %d, new state %d", oldState, newState);
+
+ /* since we might be both in main thread and subthread both test getenv
+ * and attach */
+ if (fmReceiverSession.jvm_p->GetEnv((void **) &env, JNI_VERSION_1_4) !=
+ JNI_OK) {
+ reAttached = true;
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attach current thread");
+ return;
+ }
+ }
+
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+
+ notifyOnStateChangedMethod =
+ env->GetMethodID(clazz, "notifyOnStateChanged", "(II)V");
+ if (notifyOnStateChangedMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj,
+ notifyOnStateChangedMethod, oldState,
+ newState);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnStateChanged method");
+ }
+
+ if (reAttached) {
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+ }
+}
+
+static void androidFmRadioRxCallbackOnError(void)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ ALOGI("androidFmRadioRxCallbackOnError");
+
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+ notifyMethod = env->GetMethodID(clazz, "notifyOnError", "()V");
+
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnError method");
+ }
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+}
+
+static void androidFmRadioRxCallbackOnStarted(void)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ ALOGI("androidFmRadioRxCallbackOnStarted");
+
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+ notifyMethod = env->GetMethodID(clazz, "notifyOnStarted", "()V");
+
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnStarted method");
+ }
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+}
+
+
+static void androidFmRadioRxCallbackOnScan(int foundFreq,
+ int signalStrength,
+ int scanDirection,
+ bool aborted)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ ALOGI("androidFmRadioRxCallbackOnScan: Callback foundFreq %d, signalStrength %d,"
+ " scanDirection %d, aborted %u", foundFreq, signalStrength, scanDirection,
+ aborted);
+
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+
+ notifyMethod = env->GetMethodID(clazz, "notifyOnScan", "(IIIZ)V");
+
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod, foundFreq, signalStrength,
+ scanDirection, aborted);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnScan method");
+ }
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+}
+
+static void androidFmRadioRxCallbackOnFullScan(int noItems,
+ int *frequencies,
+ int *sigStrengths,
+ bool aborted)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+ jintArray jFreqs;
+ jintArray jSigStrengths;
+
+ int d;
+
+ ALOGI("androidFmRadioRxCallbackOnFullScan: No items %d, aborted %d",
+ noItems, aborted);
+
+ for (d = 0; d < noItems; d++) {
+ ALOGI("%d -> %d", frequencies[d], sigStrengths[d]);
+ }
+
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ jFreqs = env->NewIntArray(noItems);
+ jSigStrengths = env->NewIntArray(noItems);
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+
+ env->SetIntArrayRegion(jFreqs, 0, noItems, frequencies);
+ env->SetIntArrayRegion(jSigStrengths, 0, noItems, sigStrengths);
+
+
+ notifyMethod = env->GetMethodID(clazz, "notifyOnFullScan", "([I[IZ)V");
+
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ env->CallVoidMethod(jobj, notifyMethod,
+ jFreqs, jSigStrengths, aborted);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnFullScan method");
+ }
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+}
+
+static void androidFmRadioRxCallbackOnForcedReset(enum fmradio_reset_reason_t reason)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+ bool reAttached = false;
+
+ ALOGI("androidFmRadioRxCallbackOnForcedReset");
+
+ if (fmReceiverSession.jvm_p->GetEnv((void **) &env, JNI_VERSION_1_4) !=
+ JNI_OK) {
+ reAttached = true;
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+ }
+
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+
+ notifyMethod = env->GetMethodID(clazz, "notifyOnForcedReset", "(I)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod,
+ reason);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ }
+
+ if (reAttached) {
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+ }
+}
+
+static void androidFmRadioRxCallbackOnVendorForcedReset(enum fmradio_reset_reason_t reason)
+{
+
+ ALOGI("androidFmRadioRxCallbackOnVendorForcedReset");
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ if (fmReceiverSession.state != FMRADIO_STATE_IDLE) {
+ FMRADIO_SET_STATE(&fmReceiverSession, FMRADIO_STATE_IDLE);
+ androidFmRadioUnLoadFmLibrary(&fmReceiverSession);
+ fmReceiverSession.isRegistered = false;
+ }
+ fmReceiverSession.callbacks_p->onForcedReset(reason);
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+
+static void androidFmRadioRxCallbackOnExtraCommand(char* command,
+ struct
+ fmradio_extra_command_ret_item_t
+ *retList)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ struct bundle_descriptor_offsets_t *bundle_p =
+ fmReceiverSession.bundleOffsets_p;
+
+ ALOGI("androidFmRadioRxCallbackOnSendExtraCommand");
+
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+ jobject retBundle = extraCommandRetList2Bundle(env, bundle_p, retList);
+ jstring jcommand = env->NewStringUTF(command);
+
+ notifyMethod =
+ env->GetMethodID(clazz, "notifyOnExtraCommand",
+ "(Ljava/lang/String;Landroid/os/Bundle;)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ env->CallVoidMethod(jobj, notifyMethod, jcommand, retBundle);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ }
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+}
+
+/*
+* Implementation of callbacks from vendor layer. For these the mutex lock
+* is NOT held on entry and need to be taken and released before doing
+* calls to java layer (env->Call*Method) becasue these might trigger new
+* calls from java and a deadlock would occure
+*/
+
+static void
+androidFmRadioRxCallbackOnRDSDataFound(struct fmradio_rds_bundle_t *t,
+ int frequency)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+ jobject bundle;
+ jshortArray jsArr;
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ struct bundle_descriptor_offsets_t *bundle_p =
+ fmReceiverSession.bundleOffsets_p;
+
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ goto drop_lock;
+ }
+ bundle = env->NewObject(bundle_p->mClass,
+ bundle_p->mConstructor);
+ /* note, these calls are to predefined methods, no need to release lock */
+ env->CallVoidMethod(bundle, bundle_p->mPutShort,
+ env->NewStringUTF("PI"), t->pi);
+ env->CallVoidMethod(bundle, bundle_p->mPutShort,
+ env->NewStringUTF("TP"), t->tp);
+ env->CallVoidMethod(bundle, bundle_p->mPutShort,
+ env->NewStringUTF("PTY"), t->pty);
+ env->CallVoidMethod(bundle, bundle_p->mPutShort,
+ env->NewStringUTF("TA"), t->ta);
+ env->CallVoidMethod(bundle, bundle_p->mPutShort,
+ env->NewStringUTF("M/S"), t->ms);
+
+ if (t->num_afs > 0 && t->num_afs < RDS_MAX_AFS) {
+ jintArray jArr = env->NewIntArray(t->num_afs);
+ env->SetIntArrayRegion(jArr, 0, t->num_afs, t->af);
+ env->CallVoidMethod(bundle, bundle_p->mPutIntArray,
+ env->NewStringUTF("AF"), jArr);
+ }
+ env->CallVoidMethod(bundle, bundle_p->mPutString,
+ env->NewStringUTF("PSN"),
+ env->NewStringUTF(t->psn));
+ env->CallVoidMethod(bundle, bundle_p->mPutString,
+ env->NewStringUTF("RT"),
+ env->NewStringUTF(t->rt));
+ env->CallVoidMethod(bundle, bundle_p->mPutString,
+ env->NewStringUTF("CT"),
+ env->NewStringUTF(t->ct));
+ env->CallVoidMethod(bundle, bundle_p->mPutString,
+ env->NewStringUTF("PTYN"),
+ env->NewStringUTF(t->ptyn));
+
+ jsArr = env->NewShortArray(3);
+
+ env->SetShortArrayRegion(jsArr, 0, 3, t->tmc);
+ env->CallVoidMethod(bundle, bundle_p->mPutShortArray,
+ env->NewStringUTF("TMC"), jsArr);
+
+ env->CallVoidMethod(bundle, bundle_p->mPutInt,
+ env->NewStringUTF("TAF"), t->taf);
+
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+
+ notifyMethod =
+ env->GetMethodID(clazz, "notifyOnRDSDataFound",
+ "(Landroid/os/Bundle;I)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod,
+ bundle, frequency);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ }
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+
+ drop_lock:
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static void androidFmRadioRxCallbackOnSignalStrengthChanged(int newLevel)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ goto drop_lock;
+ }
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+ notifyMethod =
+ env->GetMethodID(clazz, "notifyOnSignalStrengthChanged", "(I)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod,
+ newLevel);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ }
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+ drop_lock:
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static void androidFmRadioRxCallbackOnPlayingInStereo(int
+ isPlayingInStereo)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ ALOGI("androidFmRadioRxCallbackOnPlayingInStereo (%d)",
+ isPlayingInStereo);
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ goto drop_lock;
+ }
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+ notifyMethod =
+ env->GetMethodID(clazz, "notifyOnPlayingInStereo", "(Z)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod,
+ (bool) isPlayingInStereo);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ }
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+ drop_lock:
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+/*
+ * currently frequency changed event is not supported by interface, to be
+ * implemented quite soon...
+ */
+
+static void androidFmRadioRxCallbackOnAutomaticSwitch(int newFrequency, enum fmradio_switch_reason_t reason)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ ALOGI("androidFmRadioRxCallbackOnAutomaticSwitch: new frequency %d, reason %d",
+ newFrequency, (int) reason);
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ if (fmReceiverSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ goto drop_lock;
+ }
+ clazz = env->GetObjectClass(fmReceiverSession.jobj);
+ notifyMethod =
+ env->GetMethodID(clazz, "notifyOnAutomaticSwitching", "(II)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmReceiverSession.jobj;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod, (jint)newFrequency,
+ (jint)reason);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ }
+
+
+ fmReceiverSession.jvm_p->DetachCurrentThread();
+ drop_lock:
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+/*
+ * function calls from java layer.
+ */
+
+static jint androidFmRadioRxGetState(JNIEnv * env, jobject obj)
+{
+ FmRadioState_t state;
+
+ ALOGI("androidFmRadioRxGetState, state\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ state = fmReceiverSession.state;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ return state;
+}
+
+/* common ones with tx, just forward to the generic androidFmRadioxxxxx version */
+
+static void
+androidFmRadioRxStart(JNIEnv * env, jobject obj, int lowFreq,
+ int highFreq, int defaultFreq, int grid)
+{
+ ALOGI("androidFmRadioRxStart. LowFreq %d, HighFreq %d, DefaultFreq %d, grid %d.", lowFreq, highFreq, defaultFreq, grid);
+
+ if (fmReceiverSession.jobj == NULL)
+ fmReceiverSession.jobj = env->NewGlobalRef(obj);
+ (void) androidFmRadioStart(&fmReceiverSession, FMRADIO_RX,
+ &FmRadioRxVendorCallbacks, false, lowFreq,
+ highFreq, defaultFreq, grid);
+}
+
+
+static void
+androidFmRadioRxStartAsync(JNIEnv * env, jobject obj, int lowFreq,
+ int highFreq, int defaultFreq, int grid)
+{
+ ALOGI("androidFmRadioRxStartAsync...");
+
+ if (fmReceiverSession.jobj == NULL)
+ fmReceiverSession.jobj = env->NewGlobalRef(obj);
+ (void) androidFmRadioStart(&fmReceiverSession, FMRADIO_RX,
+ &FmRadioRxVendorCallbacks, true, lowFreq,
+ highFreq, defaultFreq, grid);
+}
+
+static void androidFmRadioRxPause(JNIEnv * env, jobject obj)
+{
+ ALOGI("androidFmRadioRxPause\n");
+
+ (void)androidFmRadioPause(&fmReceiverSession);
+}
+
+static void androidFmRadioRxResume(JNIEnv * env, jobject obj)
+{
+ ALOGI("androidFmRadioRxResume\n");
+ (void)androidFmRadioResume(&fmReceiverSession);
+}
+
+static jint androidFmRadioRxReset(JNIEnv * env, jobject obj)
+{
+ int retval = 0;
+
+ ALOGI("androidFmRadioRxReset");
+ retval = androidFmRadioReset(&fmReceiverSession);
+
+ if (retval >= 0 && fmReceiverSession.state == FMRADIO_STATE_IDLE &&
+ fmReceiverSession.jobj != NULL) {
+ env->DeleteGlobalRef(fmReceiverSession.jobj);
+ fmReceiverSession.jobj = NULL;
+ }
+
+ return retval;
+}
+
+static void
+androidFmRadioRxSetFrequency(JNIEnv * env, jobject obj, jint frequency)
+{
+ ALOGI("androidFmRadioRxSetFrequency tuneTo:%d\n", (int) frequency);
+ return androidFmRadioSetFrequency(&fmReceiverSession, (int) frequency);
+}
+
+static jint androidFmRadioRxGetFrequency(JNIEnv * env, jobject obj)
+{
+ ALOGI("androidFmRadioRxGetFrequency:\n");
+ return androidFmRadioGetFrequency(&fmReceiverSession);
+}
+
+static void androidFmRadioRxStopScan(JNIEnv * env, jobject obj)
+{
+ ALOGI("androidFmRadioRxStopScan\n");
+ androidFmRadioStopScan(&fmReceiverSession);
+}
+
+/* the rest of the calls are specific for RX */
+
+static jint androidFmRadioRxGetSignalStrength(JNIEnv * env, jobject obj)
+{
+ int retval = SIGNAL_STRENGTH_UNKNOWN;
+
+ ALOGI("androidFmRadioRxGetSignalStrength\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_GET_SIGNAL_STRENGTH)) {
+ goto drop_lock;
+ }
+
+ if (fmReceiverSession.vendorMethods_p->get_signal_strength) {
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(&fmReceiverSession);
+
+ retval =
+ fmReceiverSession.vendorMethods_p->
+ get_signal_strength(&fmReceiverSession.vendorData_p);
+
+ if (retval < 0) {
+ retval = SIGNAL_STRENGTH_UNKNOWN;
+ } else if (retval > SIGNAL_STRENGTH_MAX) {
+ retval = SIGNAL_STRENGTH_MAX;
+ }
+ androidFmRadioPauseIfTempResumed(&fmReceiverSession);
+ }
+
+ drop_lock:
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ return retval;
+}
+
+static jboolean
+androidFmRadioRxIsPlayingInStereo(JNIEnv * env, jobject obj)
+{
+ bool retval;
+
+ ALOGI("androidFmRadioRxIsPlayingInStereo:\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ /* if we haven't register we don't know yet */
+ if (!fmReceiverSession.isRegistered) {
+ retval = false;
+ goto drop_lock;
+ }
+ // valid in all states
+ if (fmReceiverSession.vendorMethods_p->is_playing_in_stereo != NULL) {
+ retval =
+ fmReceiverSession.vendorMethods_p->
+ is_playing_in_stereo(&fmReceiverSession.vendorData_p);
+ } else {
+ retval = false;
+ }
+
+ drop_lock:
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ return retval;
+}
+
+static jboolean
+androidFmRadioRxIsRDSDataSupported(JNIEnv * env, jobject obj)
+{
+ bool retval;
+
+ ALOGI("androidFmRadioRxIsRDSDataSupported:\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ /* if we haven't register we don't know yet */
+ if (!fmReceiverSession.isRegistered) {
+ retval = false;
+ goto drop_lock;
+ }
+ // valid in all states
+ if (fmReceiverSession.vendorMethods_p->is_rds_data_supported != NULL) {
+ retval =
+ fmReceiverSession.vendorMethods_p->
+ is_rds_data_supported(&fmReceiverSession.vendorData_p);
+ } else {
+ retval = false;
+ }
+
+ drop_lock:
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ return retval;
+}
+
+static jboolean
+androidFmRadioRxIsTunedToValidChannel(JNIEnv * env, jobject obj)
+{
+ bool retval;
+
+ ALOGI("androidFmRadioRxIsTunedToValidChannel:\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ /* if we haven't register we don't know yet */
+ if (!fmReceiverSession.isRegistered) {
+ retval = false;
+ goto drop_lock;
+ }
+ // valid in all states
+ if (fmReceiverSession.vendorMethods_p->is_tuned_to_valid_channel != NULL) {
+ retval =
+ fmReceiverSession.vendorMethods_p->
+ is_tuned_to_valid_channel(&fmReceiverSession.vendorData_p);
+ } else {
+ retval = false;
+ }
+
+ drop_lock:
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ return retval;
+}
+
+static void *execute_androidFmRadioRxScan(void *args)
+{
+ enum fmradio_seek_direction_t scanDirection =
+ *(enum fmradio_seek_direction_t *) args;
+ int signalStrength = -1;
+ int retval;
+ enum FmRadioState_t oldState;
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ free(args);
+ // we should still be in SCANNING mode, but we can't be 100.00 % sure since main thread released lock
+ // before we could run
+
+ if (fmReceiverSession.state != FMRADIO_STATE_SCANNING) {
+ ALOGE("execute_androidFmRadioRxScan - warning, state not scanning");
+ }
+
+ /*
+ * if mode has been changed to IDLE in the mean time by main thread,
+ * exit the worker thread gracefully
+ */
+ if (fmReceiverSession.state == FMRADIO_STATE_IDLE) {
+ goto drop_lock;
+ }
+
+ oldState = fmReceiverSession.oldState;
+
+ // temporary resume chip if sleeping
+ if (oldState == FMRADIO_STATE_PAUSED) {
+ (void) fmReceiverSession.
+ vendorMethods_p->resume(&fmReceiverSession.vendorData_p);
+ }
+
+ if (pthread_cond_signal(&fmReceiverSession.sync_cond) != 0) {
+ ALOGE("execute_androidFmRadioRxScan - warning, signal failed");
+ }
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ retval =
+ fmReceiverSession.vendorMethods_p->scan(&fmReceiverSession.
+ vendorData_p,
+ scanDirection);
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (retval >= 0) {
+ // also get signal strength (if supported)
+ if (fmReceiverSession.vendorMethods_p->get_signal_strength)
+ signalStrength =
+ fmReceiverSession.vendorMethods_p->
+ get_signal_strength(&fmReceiverSession.vendorData_p);
+ }
+ /*
+ * if state has changed we should keep it, probably a forced reset
+ */
+ if (fmReceiverSession.state != FMRADIO_STATE_SCANNING) {
+ ALOGI("State changed while scanning (state now %d), keeping",
+ fmReceiverSession.state);
+ retval = -1;
+ } else {
+ // put back to sleep if we did a temporary wake-up
+ if ((oldState == FMRADIO_STATE_PAUSED
+ || fmReceiverSession.pendingPause))
+ (void) fmReceiverSession.
+ vendorMethods_p->pause(&fmReceiverSession.vendorData_p);
+ if (fmReceiverSession.pendingPause) {
+ FMRADIO_SET_STATE(&fmReceiverSession, FMRADIO_STATE_PAUSED);
+ } else {
+ FMRADIO_SET_STATE(&fmReceiverSession, oldState);
+ }
+
+ // if we failed but we have a pending abort just read the current frequency to give a proper
+ // onScan return
+
+ if (retval < 0 && fmReceiverSession.lastScanAborted &&
+ fmReceiverSession.vendorMethods_p->get_frequency) {
+ retval = fmReceiverSession.vendorMethods_p->get_frequency(&fmReceiverSession.vendorData_p);
+ }
+ }
+
+ fmReceiverSession.pendingPause = false;
+
+ if (retval >= 0) {
+ fmReceiverSession.callbacks_p->onScan(retval,
+ signalStrength,
+ scanDirection,
+ fmReceiverSession.
+ lastScanAborted);
+ } else {
+ fmReceiverSession.callbacks_p->onError();
+ }
+ drop_lock:
+ /* Wake up the main thread if it is currently waiting on the condition variable */
+ if (pthread_cond_signal(&fmReceiverSession.sync_cond) != 0) {
+ ALOGE("execute_androidFmRadioRxScan - signal failed\n");
+ }
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ pthread_exit(NULL);
+ return NULL;
+}
+
+
+static void androidFmRadioRxScan(enum fmradio_seek_direction_t scanDirection)
+{
+ int retval = 0;
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_SCAN)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (fmReceiverSession.vendorMethods_p->scan) {
+ enum fmradio_seek_direction_t *scanDirectionParam_p =
+ (enum fmradio_seek_direction_t *)
+ malloc(sizeof(*scanDirectionParam_p));
+
+ pthread_t execute_thread;
+
+ // we need to create a new thread actually executing the command
+
+ fmReceiverSession.oldState = fmReceiverSession.state;
+ FMRADIO_SET_STATE(&fmReceiverSession, FMRADIO_STATE_SCANNING);
+ *scanDirectionParam_p = scanDirection;
+
+ fmReceiverSession.lastScanAborted = false;
+
+ if (pthread_create
+ (&execute_thread, NULL, execute_androidFmRadioRxScan,
+ (void *) scanDirectionParam_p) != 0) {
+
+ ALOGE("pthread_create failure...\n");
+ free(scanDirectionParam_p);
+ FMRADIO_SET_STATE(&fmReceiverSession, fmReceiverSession.oldState);
+ retval = FMRADIO_IO_ERROR;
+ } else {
+ /* await thread startup, THREAD_WAIT_TIMEOUT_S sec timeout */
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += THREAD_WAIT_TIMEOUT_S;
+ if (pthread_cond_timedwait(&fmReceiverSession.sync_cond,
+ fmReceiverSession.dataMutex_p,
+ &ts) != 0) {
+ ALOGE("androidFmRadioRxScan: warning, wait failure\n");
+ }
+ pthread_detach(execute_thread);
+
+ }
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmReceiverSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmReceiverSession);
+ }
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ if (retval < 0) {
+ ALOGE("androidFmRadioRxScan failed\n");
+ }
+}
+
+static void
+androidFmRadioRxScanUp(JNIEnv * env, jobject obj, jlong * frequency)
+{
+ ALOGI("androidFmRadioRxScanUp\n");
+
+ androidFmRadioRxScan(FMRADIO_SEEK_UP);
+}
+
+static void
+androidFmRadioRxScanDown(JNIEnv * env, jobject obj, jlong * frequency)
+{
+ ALOGI("androidFmRadioRxScanDown\n");
+
+ androidFmRadioRxScan(FMRADIO_SEEK_DOWN);
+}
+
+static void *execute_androidFmRadioRxFullScan(void *args)
+{
+ int retval;
+ enum FmRadioState_t oldState = fmReceiverSession.oldState;
+ int *frequencies_p = NULL;
+ int *rssi_p = NULL;
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ // we should still be in SCANNING mode, but we can't be 100.00 % sure since main thread released lock
+ // before we could run
+
+ if (fmReceiverSession.state != FMRADIO_STATE_SCANNING) {
+ ALOGE("execute_androidFmRadioRxFullScan - warning, state not scanning\n");
+ }
+
+ /*
+ * if mode has been changed to IDLE in the mean time by main thread,
+ * exit the worker thread gracefully
+ */
+ if (fmReceiverSession.state == FMRADIO_STATE_IDLE) {
+ goto drop_lock;
+ }
+ // temporary resume chip if sleeping
+ if (oldState == FMRADIO_STATE_PAUSED) {
+ (void) fmReceiverSession.
+ vendorMethods_p->resume(&fmReceiverSession.vendorData_p);
+ }
+
+ if (pthread_cond_signal(&fmReceiverSession.sync_cond) != 0) {
+ ALOGE("execute_androidFmRadioRxFullScan - warning, signal failed\n");
+ }
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ retval =
+ fmReceiverSession.vendorMethods_p->full_scan(&fmReceiverSession.
+ vendorData_p,
+ &frequencies_p,
+ &rssi_p);
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ /*
+ * if state has changed we should keep it, probably a forced pause or
+ * forced reset
+ */
+ if (fmReceiverSession.state != FMRADIO_STATE_SCANNING) {
+ ALOGI("State changed while scanning (state now %d), keeping\n",
+ fmReceiverSession.state);
+ retval = -1;
+ } else {
+ if (fmReceiverSession.pendingPause) {
+ FMRADIO_SET_STATE(&fmReceiverSession, FMRADIO_STATE_PAUSED);
+ } else {
+ FMRADIO_SET_STATE(&fmReceiverSession, oldState);
+ }
+
+ fmReceiverSession.pendingPause = false;
+ }
+
+ if (retval >= 0) {
+ fmReceiverSession.callbacks_p->onFullScan(retval,
+ frequencies_p,
+ rssi_p,
+ fmReceiverSession.
+ lastScanAborted);
+ } else {
+ fmReceiverSession.callbacks_p->onError();
+ }
+
+ if (frequencies_p != NULL) {
+ free(frequencies_p);
+ }
+
+ if (rssi_p != NULL) {
+ free(rssi_p);
+ }
+
+ drop_lock:
+ /* Wake up the main thread if it is currently waiting on the condition variable */
+ if (pthread_cond_signal(&fmReceiverSession.sync_cond) != 0) {
+ ALOGE("execute_androidFmRadioRxFullScan - signal failed\n");
+ }
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ pthread_exit(NULL);
+ return NULL;
+}
+
+static void androidFmRadioRxStartFullScan(JNIEnv * env, jobject obj)
+{
+ ALOGI("androidFmRadioRxStartFullScan\n");
+ int retval = 0;
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_FULL_SCAN)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+
+ if (fmReceiverSession.vendorMethods_p->full_scan) {
+ pthread_t execute_thread;
+
+ fmReceiverSession.oldState = fmReceiverSession.state;
+ FMRADIO_SET_STATE(&fmReceiverSession, FMRADIO_STATE_SCANNING);
+ fmReceiverSession.lastScanAborted = false;
+
+ if (pthread_create
+ (&execute_thread, NULL, execute_androidFmRadioRxFullScan,
+ NULL) != 0) {
+
+ ALOGE("pthread_create failure...\n");
+ FMRADIO_SET_STATE(&fmReceiverSession, fmReceiverSession.oldState);
+ retval = FMRADIO_IO_ERROR;
+ } else {
+ /* await thread startup, THREAD_WAIT_TIMEOUT_S sec timeout */
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += THREAD_WAIT_TIMEOUT_S;
+ if (pthread_cond_timedwait(&fmReceiverSession.sync_cond,
+ fmReceiverSession.dataMutex_p,
+ &ts) != 0) {
+ ALOGE("androidFmRadioRxStartFullScan: warning, wait failure\n");
+ }
+ pthread_detach(execute_thread);
+ }
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmReceiverSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmReceiverSession);
+ }
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static void androidFmRadioRxSetAutomaticAFSwitching(JNIEnv * env,
+ jobject obj,
+ jboolean automatic)
+{
+ int retval = -1;
+
+ ALOGI("androidFmRadioRxSetAutomaticAFSwitching\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_SET_PARAMETER)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+
+ if (fmReceiverSession.vendorMethods_p->set_automatic_af_switching) {
+ retval =
+ fmReceiverSession.vendorMethods_p->
+ set_automatic_af_switching(&fmReceiverSession.vendorData_p, automatic);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmReceiverSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmReceiverSession);
+ }
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static void androidFmRadioRxSetAutomaticTASwitching(JNIEnv * env, jobject obj,
+ jboolean automatic)
+{
+ int retval = -1;
+
+ ALOGI("androidFmRadioRxSetAutomaticTASwitching\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_SET_PARAMETER)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+
+ if (fmReceiverSession.vendorMethods_p->set_automatic_ta_switching) {
+ retval =
+ fmReceiverSession.vendorMethods_p->
+ set_automatic_ta_switching(&fmReceiverSession.vendorData_p, automatic);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmReceiverSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmReceiverSession);
+ }
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static void androidFmRadioRxSetForceMono(JNIEnv * env, jobject obj,
+ jboolean forceMono)
+{
+ int retval = -1;
+
+ ALOGI("androidFmRadioRxSetForceMono\n");
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_SET_PARAMETER)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+
+ if (fmReceiverSession.vendorMethods_p->set_force_mono) {
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(&fmReceiverSession);
+
+ retval =
+ fmReceiverSession.vendorMethods_p->
+ set_force_mono(&fmReceiverSession.vendorData_p, forceMono);
+
+ androidFmRadioPauseIfTempResumed(&fmReceiverSession);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmReceiverSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmReceiverSession);
+ }
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static void
+androidFmRadioRxSetThreshold(JNIEnv * env, jobject obj, jint threshold)
+{
+ int retval;
+
+ ALOGI("androidFmRadioRxSetThreshold threshold:%d\n", (int) threshold);
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_SET_PARAMETER)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+
+ if (fmReceiverSession.vendorMethods_p->set_threshold) {
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(&fmReceiverSession);
+
+ retval =
+ fmReceiverSession.
+ vendorMethods_p->set_threshold(&fmReceiverSession.vendorData_p,
+ threshold);
+ /* if in pause state temporary resume */
+ androidFmRadioPauseIfTempResumed(&fmReceiverSession);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmReceiverSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmReceiverSession);
+ }
+
+ drop_lock:
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static jint androidFmRadioRxGetThreshold(JNIEnv * env, jobject obj)
+{
+ int retval;
+
+ ALOGI("androidFmRadioRxGetThreshold\n");
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_GET_PARAMETER)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (fmReceiverSession.vendorMethods_p->get_threshold) {
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(&fmReceiverSession);
+ retval =
+ fmReceiverSession.
+ vendorMethods_p->get_threshold(&fmReceiverSession.vendorData_p);
+ androidFmRadioPauseIfTempResumed(&fmReceiverSession);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+ drop_lock:
+
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmReceiverSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmReceiverSession);
+ }
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+
+ return retval;
+}
+
+static void androidFmRadioRxSetRDS(JNIEnv * env, jobject obj,
+ jboolean receiveRDS)
+{
+ int retval = -1;
+
+ ALOGI("androidFmRadioRxSetRDS(%d)", (int)receiveRDS);
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmReceiverSession, FMRADIO_EVENT_SET_PARAMETER)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (fmReceiverSession.vendorMethods_p->set_rds_reception) {
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(&fmReceiverSession);
+
+ retval = fmReceiverSession.vendorMethods_p->
+ set_rds_reception(&fmReceiverSession.vendorData_p, receiveRDS);
+
+ androidFmRadioPauseIfTempResumed(&fmReceiverSession);
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ /*
+ * Set rds is not executed by explicit command but rather triggered
+ * on startup and on adding and removal of listeners. Because of this
+ * it should not trigger exceptions, just ALOG any failure.
+ */
+
+ if (retval != FMRADIO_OK) {
+ ALOGE("androidFmRadioRxSetRDS failed, retval = %d.", retval);
+ }
+
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+}
+
+static jboolean androidFmRadioRxSendExtraCommand(JNIEnv * env, jobject obj,
+ jstring command,
+ jobjectArray parameters)
+{
+ ALOGI("androidFmRadioRxSendExtraCommand");
+
+/* we need to set jobj since this might be called before start */
+
+ if (fmReceiverSession.jobj == NULL)
+ fmReceiverSession.jobj = env->NewGlobalRef(obj);
+
+ androidFmRadioSendExtraCommand(&fmReceiverSession, env, command,
+ parameters);
+
+ return true;
+}
+
+
+static JNINativeMethod gMethods[] = {
+ {(char *)"_fm_receiver_getState", (char *)"()I",
+ (void *) androidFmRadioRxGetState},
+ {(char *)"_fm_receiver_start", (char *)"(IIII)V",
+ (void *) androidFmRadioRxStart},
+ {(char *)"_fm_receiver_startAsync", (char *)"(IIII)V",
+ (void *) androidFmRadioRxStartAsync},
+ {(char *)"_fm_receiver_pause", (char *)"()V",
+ (void *) androidFmRadioRxPause},
+ {(char *)"_fm_receiver_resume", (char *)"()V",
+ (void *) androidFmRadioRxResume},
+ {(char *)"_fm_receiver_reset", (char *)"()I",
+ (void *) androidFmRadioRxReset},
+ {(char *)"_fm_receiver_setFrequency", (char *)"(I)V",
+ (void *) androidFmRadioRxSetFrequency},
+ {(char *)"_fm_receiver_getFrequency", (char *)"()I",
+ (void *) androidFmRadioRxGetFrequency},
+ {(char *)"_fm_receiver_getSignalStrength", (char *)"()I",
+ (void *) androidFmRadioRxGetSignalStrength},
+ {(char *)"_fm_receiver_scanUp", (char *)"()V",
+ (void *) androidFmRadioRxScanUp},
+ {(char *)"_fm_receiver_scanDown", (char *)"()V",
+ (void *) androidFmRadioRxScanDown},
+ {(char *)"_fm_receiver_startFullScan", (char *)"()V",
+ (void *) androidFmRadioRxStartFullScan},
+ {(char *)"_fm_receiver_isPlayingInStereo", (char *)"()Z",
+ (void *) androidFmRadioRxIsPlayingInStereo},
+ {(char *)"_fm_receiver_isRDSDataSupported", (char *)"()Z",
+ (void *) androidFmRadioRxIsRDSDataSupported},
+ {(char *)"_fm_receiver_isTunedToValidChannel", (char *)"()Z",
+ (void *) androidFmRadioRxIsTunedToValidChannel},
+ {(char *)"_fm_receiver_stopScan", (char *)"()V",
+ (void *) androidFmRadioRxStopScan},
+ {(char *)"_fm_receiver_setAutomaticAFSwitching", (char *)"(Z)V",
+ (void *) androidFmRadioRxSetAutomaticAFSwitching},
+ {(char *)"_fm_receiver_setAutomaticTASwitching", (char *)"(Z)V",
+ (void *) androidFmRadioRxSetAutomaticTASwitching},
+ {(char *)"_fm_receiver_setForceMono", (char *)"(Z)V",
+ (void *) androidFmRadioRxSetForceMono},
+ {(char *)"_fm_receiver_sendExtraCommand",
+ (char *)"(Ljava/lang/String;[Ljava/lang/String;)Z",
+ (void *) androidFmRadioRxSendExtraCommand},
+ {(char *)"_fm_receiver_getThreshold", (char *)"()I",
+ (void *) androidFmRadioRxGetThreshold},
+ {(char *)"_fm_receiver_setThreshold", (char *)"(I)V",
+ (void *) androidFmRadioRxSetThreshold},
+ {(char *)"_fm_receiver_setRDS", (char *)"(Z)V",
+ (void *) androidFmRadioRxSetRDS},
+};
+
+
+
+
+int registerAndroidFmRadioReceiver(JavaVM * vm, JNIEnv * env)
+{
+ ALOGI("registerAndroidFmRadioReceiver\n");
+ jclass clazz;
+
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
+ fmReceiverSession.jvm_p = vm;
+
+ struct bundle_descriptor_offsets_t *bundle_p =
+ (struct bundle_descriptor_offsets_t *)
+ malloc(sizeof(struct bundle_descriptor_offsets_t));
+
+ clazz = env->FindClass("android/os/Bundle");
+ bundle_p->mClass = (jclass) env->NewGlobalRef(clazz);
+ bundle_p->mConstructor = env->GetMethodID(clazz, "<init>", "()V");
+ bundle_p->mPutInt =
+ env->GetMethodID(clazz, "putInt", "(Ljava/lang/String;I)V");
+ bundle_p->mPutShort =
+ env->GetMethodID(clazz, "putShort", "(Ljava/lang/String;S)V");
+ bundle_p->mPutIntArray =
+ env->GetMethodID(clazz, "putIntArray", "(Ljava/lang/String;[I)V");
+ bundle_p->mPutShortArray =
+ env->GetMethodID(clazz, "putShortArray",
+ "(Ljava/lang/String;[S)V");
+ bundle_p->mPutString =
+ env->GetMethodID(clazz, "putString",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ fmReceiverSession.bundleOffsets_p = bundle_p;
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
+ return jniRegisterNativeMethods(env,
+ "com/stericsson/hardware/fm/FmReceiverService",
+ gMethods, NELEM(gMethods));
+}
+
+/* *INDENT-OFF* */
+}; // namespace android
diff --git a/fmradio/jni/android_fmradio_Transmitter.cpp b/fmradio/jni/android_fmradio_Transmitter.cpp
new file mode 100755
index 0000000..b8a7e48
--- /dev/null
+++ b/fmradio/jni/android_fmradio_Transmitter.cpp
@@ -0,0 +1,1098 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Authors: johan.xj.palmaeus@stericsson.com
+ * stuart.macdonald@stericsson.com
+ * for ST-Ericsson
+ */
+
+/*
+ * Native part of the generic TX FmRadio inteface
+ */
+
+#define ALOG_TAG "FmTransmitterServiceNative"
+
+// #define LOG_NDEBUG 1
+
+#include <stdio.h>
+#include <unistd.h>
+#include <termios.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <media/AudioSystem.h>
+#include <system/audio.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_fmradio.h"
+#include <utils/Log.h>
+
+
+/* *INDENT-OFF* */
+namespace android {
+
+// RDS Fields
+
+static const char* rds_field_names[] = {
+ "PI",
+ "TP",
+ "PTY",
+ "TA",
+ "M/S",
+ "AF",
+ "numAFs",
+ "PSN",
+ "RT",
+ "CT",
+ "PTYN",
+ "TMC",
+ "TAF",
+ NULL
+};
+
+
+// state machine
+
+static const ValidEventsForStates_t IsValidTxEventForState = {
+/* this table defines valid transitions. (turn off indent, we want this easy readable) */
+ /* FMRADIO_STATE_ IDLE,STARTING,STARTED,PAUSED,SCANNING,EXTRA_COMMAND */
+
+ /* FMRADIO_EVENT_START */ {true, false,false,false,false,false},
+ /* FMRADIO_EVENT_START_ASYNC */ {true, false,false,false,false,false},
+ /* FMRADIO_EVENT_PAUSE */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_RESUME */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_RESET */ {true, true, true, true, true, true },
+ /* FMRADIO_EVENT_GET_FREQUENCY */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_SET_FREQUENCY */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_SET_PARAMETER */ {false,false,true, true, false,false},
+ /* FMRADIO_EVENT_STOP_SCAN */ {true, true, true, true, true, true },
+ /* FMRADIO_EVENT_EXTRA_COMMAND */ {true, true, true, true, true, true },
+ /* Rx Only - never allowed */
+ /* FMRADIO_EVENT_GET_PARAMETER */ {false,false,false,false,false,false},
+ /* FMRADIO_EVENT_GET_SIGNAL_STRENGTH */{false,false,false,false,false,false},
+ /* FMRADIO_EVENT_SCAN */ {false,false,false,false,false,false},
+ /* FMRADIO_EVENT_FULL_SCAN */ {false,false,false,false,false,false},
+ /* Tx Only */
+ /* FMRADIO_EVENT_BLOCK_SCAN */ {false,false,true, true, false,false},
+};
+/* *INDENT-ON* */
+
+static void androidFmRadioTxCallbackOnStateChanged(int oldState,
+ int newState);
+
+static void androidFmRadioTxCallbackOnError(void);
+
+static void androidFmRadioTxCallbackOnStarted(void);
+
+static void androidFmRadioTxCallbackOnBlockScan(int noValues,
+ int *freqs,
+ int *sigStrengths,
+ bool aborted);
+static void androidFmRadioTxCallbackOnForcedReset(enum fmradio_reset_reason_t reason);
+
+static void androidFmRadioTxCallbackOnVendorForcedReset(enum fmradio_reset_reason_t reason);
+
+static void androidFmRadioTxCallbackOnExtraCommand(char* command,
+ struct
+ fmradio_extra_command_ret_item_t
+ *retList);
+
+static const FmRadioCallbacks_t FmRadioTxCallbacks = {
+ androidFmRadioTxCallbackOnStateChanged,
+ androidFmRadioTxCallbackOnError,
+ androidFmRadioTxCallbackOnStarted,
+ NULL,
+ NULL,
+ androidFmRadioTxCallbackOnBlockScan,
+ androidFmRadioTxCallbackOnForcedReset,
+ androidFmRadioTxCallbackOnExtraCommand,
+};
+
+
+/* callbacks from vendor layer */
+
+static const fmradio_vendor_callbacks_t FmRadioTxVendorCallbacks = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ androidFmRadioTxCallbackOnVendorForcedReset
+};
+
+extern struct FmSession_t fmReceiverSession;
+
+struct FmSession_t fmTransmitterSession = {
+ NULL,
+ NULL,
+ false,
+ FMRADIO_STATE_IDLE,
+ NULL,
+ &IsValidTxEventForState,
+ &FmRadioTxCallbacks,
+ NULL,
+ NULL,
+ &fmReceiverSession,
+ NULL,
+ FMRADIO_STATE_IDLE,
+ false,
+ false,
+ false,
+ &rx_tx_common_mutex,
+ PTHREAD_COND_INITIALIZER,
+ NULL,
+};
+
+struct FmRadioBlockScanParameters {
+ int startFreq;
+ int endFreq;
+};
+
+// make sure we don't refere the ReceiverSession anymore from here
+#define fmReceiverSession ERRORDONOTUSERECEIVERSESSIONINTRANSMITTER
+
+/*
+* Implementation of callbacks from within service layer. For these the
+* mutex lock is always held on entry and need to be released before doing
+* calls to java layer (env->Call*Method) becasue these calls might trigger
+* new calls from java and a deadlock would occure if lock was still held.
+*/
+
+
+static void androidFmRadioTxCallbackOnStateChanged(int oldState,
+ int newState)
+{
+ jmethodID notifyOnStateChangedMethod;
+ JNIEnv *env;
+ jclass clazz;
+ bool reAttached = false;
+
+ ALOGI("androidFmRadioTxCallbackOnStateChanged: Old state %d, new state %d", oldState, newState);
+
+ /* since we might be both in main thread and subthread both test getenv
+ * and attach */
+ if (fmTransmitterSession.jvm_p->
+ GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
+ reAttached = true;
+ if (fmTransmitterSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attach current thread");
+ return;
+ }
+ }
+
+ clazz = env->GetObjectClass(fmTransmitterSession.jobj);
+
+ notifyOnStateChangedMethod =
+ env->GetMethodID(clazz, "notifyOnStateChanged", "(II)V");
+ if (notifyOnStateChangedMethod != NULL) {
+ jobject jobj = fmTransmitterSession.jobj;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+ env->CallVoidMethod(jobj,
+ notifyOnStateChangedMethod, oldState,
+ newState);
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ }
+ if (reAttached) {
+ fmTransmitterSession.jvm_p->DetachCurrentThread();
+ }
+}
+
+static void androidFmRadioTxCallbackOnError(void)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+
+ ALOGI("androidFmRadioTxCallbackOnError");
+
+
+ if (fmTransmitterSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmTransmitterSession.jobj);
+ notifyMethod = env->GetMethodID(clazz, "notifyOnError", "()V");
+
+ if (notifyMethod != NULL) {
+ jobject jobj = fmTransmitterSession.jobj;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod);
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnError method");
+ }
+
+ fmTransmitterSession.jvm_p->DetachCurrentThread();
+}
+
+static void androidFmRadioTxCallbackOnStarted(void)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+ status_t err;
+
+ ALOGI("androidFmRadioTxCallbackOnStarted: Callback");
+
+ if (fmTransmitterSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmTransmitterSession.jobj);
+ notifyMethod = env->GetMethodID(clazz, "notifyOnStarted", "()V");
+
+ if (notifyMethod != NULL) {
+ jobject jobj = fmTransmitterSession.jobj;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod);
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnStarted method");
+ }
+
+ // err =
+ //AudioSystem::
+ // setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_AVAILABLE, "");
+
+ if (err != OK) {
+ ALOGE("ERROR - Unable to set audio output device to FM Radio TX");
+ // AudioSystem::
+ // setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ // "");
+ }
+
+ fmTransmitterSession.jvm_p->DetachCurrentThread();
+}
+
+static void androidFmRadioTxCallbackOnBlockScan(int noItems,
+ int *freqs,
+ int *sigStrengths,
+ bool aborted)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+ jintArray jFreqs;
+ jintArray jSigStrengths;
+ int d;
+
+ ALOGI("androidFmRadioTxCallbackOnBlockScan: No items %d, aborted %d",
+ noItems, aborted);
+
+ for (d = 0; d < noItems; d++) {
+ ALOGI("%d->%d", freqs[d], sigStrengths[d]);
+ }
+
+ if (fmTransmitterSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmTransmitterSession.jobj);
+
+ jFreqs = env->NewIntArray(noItems);
+ jSigStrengths = env->NewIntArray(noItems);
+
+ env->SetIntArrayRegion(jFreqs, 0, noItems, freqs);
+ env->SetIntArrayRegion(jSigStrengths, 0, noItems, sigStrengths);
+
+ notifyMethod =
+ env->GetMethodID(clazz, "notifyOnBlockScan", "([I[IZ)V");
+
+
+ if (notifyMethod != NULL) {
+ jobject jobj = fmTransmitterSession.jobj;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod,
+ jFreqs, jSigStrengths, aborted);
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ } else {
+ ALOGE("ERROR - JNI can't find java notifyOnBlockScan method");
+ }
+
+ fmTransmitterSession.jvm_p->DetachCurrentThread();
+}
+
+static void androidFmRadioTxCallbackOnForcedReset(enum fmradio_reset_reason_t reason)
+{
+ jmethodID notifyMethod;
+ JNIEnv *env;
+ jclass clazz;
+ bool reAttached = false;
+
+ ALOGI("androidFmRadioTxCallbackOnForcedReset");
+
+ if (fmTransmitterSession.jvm_p->
+ GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
+ reAttached = true;
+ if (fmTransmitterSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+ }
+
+ clazz = env->GetObjectClass(fmTransmitterSession.jobj);
+
+ notifyMethod = env->GetMethodID(clazz, "notifyOnForcedReset", "(I)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmTransmitterSession.jobj;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod, reason);
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ }
+
+ //AudioSystem::
+ // setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ // "");
+
+ if (reAttached) {
+ fmTransmitterSession.jvm_p->DetachCurrentThread();
+ }
+}
+
+static void androidFmRadioTxCallbackOnVendorForcedReset(enum fmradio_reset_reason_t reason)
+{
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ if (fmTransmitterSession.state != FMRADIO_STATE_IDLE) {
+ FMRADIO_SET_STATE(&fmTransmitterSession, FMRADIO_STATE_IDLE);
+ androidFmRadioUnLoadFmLibrary(&fmTransmitterSession);
+ fmTransmitterSession.isRegistered = false;
+ }
+ fmTransmitterSession.callbacks_p->onForcedReset(reason);
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+}
+
+static void androidFmRadioTxCallbackOnExtraCommand(char* command,
+ struct
+ fmradio_extra_command_ret_item_t
+ *retList)
+{
+ jmethodID notifyMethod;
+
+ JNIEnv *env;
+
+ jclass clazz;
+
+ struct bundle_descriptor_offsets_t *bundle_p =
+ fmTransmitterSession.bundleOffsets_p;
+ ALOGI("androidFmRadioTxCallbackOnExtraCommand");
+
+ if (fmTransmitterSession.jvm_p->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ ALOGE("Error, can't attch current thread");
+ return;
+ }
+
+ clazz = env->GetObjectClass(fmTransmitterSession.jobj);
+
+ jobject retBundle = extraCommandRetList2Bundle(env, bundle_p, retList);
+ jstring jcommand = env->NewStringUTF(command);
+
+ notifyMethod =
+ env->GetMethodID(clazz, "notifyOnExtraCommand",
+ "(Ljava/lang/String;Landroid/os/Bundle;)V");
+ if (notifyMethod != NULL) {
+ jobject jobj = fmTransmitterSession.jobj;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+ env->CallVoidMethod(jobj, notifyMethod,
+ jcommand, retBundle);
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ }
+
+ fmTransmitterSession.jvm_p->DetachCurrentThread();
+}
+
+/*
+ * function calls from java layer
+ */
+
+static jint androidFmRadioTxGetState(JNIEnv * env, jobject obj)
+{
+ FmRadioState_t state;
+
+ ALOGI("androidFmRadioTxGetState\n");
+
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ state = fmTransmitterSession.state;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+
+ return state;
+}
+
+/* common ones with rx, just forward to the generic androidFmRadioxxxxx version */
+
+static void
+androidFmRadioTxStart(JNIEnv * env, jobject obj, int lowFreq,
+ int highFreq, int defaultFreq, int grid)
+{
+ int retval;
+
+ status_t err;
+
+ ALOGI("androidFmRadioTxStart...");
+
+ if (fmTransmitterSession.jobj == NULL)
+ fmTransmitterSession.jobj = env->NewGlobalRef(obj);
+
+ retval =
+ androidFmRadioStart(&fmTransmitterSession, FMRADIO_TX,
+ &FmRadioTxVendorCallbacks, false, lowFreq,
+ highFreq, defaultFreq, grid);
+ if (retval >= 0) {
+ //err =
+ // AudioSystem::
+ // setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ // "");
+
+ if (err != OK) {
+ ALOGE("ERROR - Unable to set audio output device to FM Radio TX");
+ // (void) AudioSystem::setDeviceConnectionState
+ // (AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, "");
+ }
+ }
+
+}
+
+static void
+androidFmRadioTxStartAsync(JNIEnv * env, jobject obj, int lowFreq,
+ int highFreq, int defaultFreq, int grid)
+{
+ ALOGI("androidFmRadioTxStartAsync...");
+
+
+ if (fmTransmitterSession.jobj == NULL)
+ fmTransmitterSession.jobj = env->NewGlobalRef(obj);
+
+ androidFmRadioStart(&fmTransmitterSession, FMRADIO_TX,
+ &FmRadioTxVendorCallbacks, true, lowFreq, highFreq,
+ defaultFreq, grid);
+}
+
+static void androidFmRadioTxPause(JNIEnv * env, jobject obj)
+{
+ int retval;
+
+ ALOGI("androidFmRadioTxPause\n");
+
+ retval = androidFmRadioPause(&fmTransmitterSession);
+
+ if (retval >= 0) {
+ //AudioSystem::
+ // setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ // "");
+ }
+}
+
+static void androidFmRadioTxResume(JNIEnv * env, jobject obj)
+{
+ int retval;
+
+ ALOGI("androidFmResumeTxResume\n");
+ retval = androidFmRadioResume(&fmTransmitterSession);
+
+ if (retval >= 0) {
+ // status_t err =
+ // AudioSystem::
+ //setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_AVAILABLE, "");
+
+ //if (err != OK) {
+ ALOGE("ERROR - Unable to set audio output device to FM Radio TX\n");
+ //AudioSystem::
+ // setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ // "");
+ // }
+ }
+}
+
+static jint androidFmRadioTxReset(JNIEnv * env, jobject obj)
+{
+ int retval;
+
+ ALOGI("androidFmRadioTxReset");
+
+ retval = androidFmRadioReset(&fmTransmitterSession);
+
+ if (retval >= 0) {
+ if (retval != FMRADIO_STATE_IDLE) {
+ // (void) AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_FM_TX,
+ // AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ // "");
+ }
+
+
+ if (fmTransmitterSession.state == FMRADIO_STATE_IDLE &&
+ fmTransmitterSession.jobj != NULL) {
+ env->DeleteGlobalRef(fmTransmitterSession.jobj);
+ fmTransmitterSession.jobj = NULL;
+ }
+ }
+
+ return retval;
+}
+
+static void
+androidFmRadioTxSetFrequency(JNIEnv * env, jobject obj, jlong frequency)
+{
+ ALOGI("androidFmRadioTxSetFrequency tuneTo:%d\n", (int) frequency);
+ androidFmRadioSetFrequency(&fmTransmitterSession, (int) frequency);
+}
+
+static void
+androidFmRadioTxSetRDSData(JNIEnv * env, jobject obj, jobject bundle)
+{
+ ALOGI("androidFmRadioTxSetRDSData start");
+
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmTransmitterSession, FMRADIO_EVENT_SET_PARAMETER)) {
+ THROW_INVALID_STATE(&fmTransmitterSession);
+ goto drop_lock;
+ }
+
+ /* if in pause state temporary resume */
+ androidFmRadioTempResumeIfPaused(&fmTransmitterSession);
+
+ if (bundle == NULL) {
+ /* just shut down RDS transmission and leave */
+ fmTransmitterSession.vendorMethods_p->
+ set_rds_data(&fmTransmitterSession.vendorData_p, NULL, NULL);
+ goto resume_and_drop_lock;
+ };
+
+ /* new block to control variable life time */
+ {
+ struct bundle_descriptor_offsets_t *bundle_p =
+ fmTransmitterSession.bundleOffsets_p;
+ jobject keys_set = env->CallObjectMethod(bundle, bundle_p->mKeySet);
+ jclass setClass = env->FindClass("java/util/Set");
+ jclass entryClass = env->FindClass("java/lang/String");
+ jmethodID iterator =
+ env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
+ jobject iter = env->CallObjectMethod(keys_set, iterator);
+ jobject iter2 = env->CallObjectMethod(keys_set, iterator);
+ jclass iteratorClass = env->FindClass("java/util/Iterator");
+ jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
+ jmethodID next =
+ env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
+ jmethodID getString =
+ env->GetMethodID(entryClass, "toString", "()Ljava/lang/String;");
+
+ while (env->CallBooleanMethod(iter, hasNext)) {
+ int i;
+ jobject entry = env->CallObjectMethod(iter, next);
+ jstring string = (jstring) env->CallObjectMethod(entry, getString);
+ const char *str = env->GetStringUTFChars(string, NULL);
+ int found = 0;
+
+ if (!str) { // Out of memory
+ THROW_IO_ERROR(&fmTransmitterSession); /* excecution will continue to cleanup */
+ env->DeleteLocalRef(entry);
+ env->DeleteLocalRef(string);
+ goto free_up_and_leave;
+ }
+
+ for (i = 0; rds_field_names[i] != NULL; i++) {
+ if (!strcmp(rds_field_names[i], str)) {
+ found = 1;
+ break;
+ }
+ }
+
+ env->DeleteLocalRef(entry);
+ env->ReleaseStringUTFChars(string, str);
+ env->DeleteLocalRef(string);
+
+ if (!found) {
+ ALOGE("androidFmRadioTxSetRDSData: Error, invalid key");
+ THROW_ILLEGAL_ARGUMENT(&fmTransmitterSession); /* excecution will continue to cleanup */
+ goto free_up_and_leave;
+ }
+ }
+
+ while (env->CallBooleanMethod(iter2, hasNext)) {
+ jobject entry = env->CallObjectMethod(iter2, next);
+ jstring string = (jstring) env->CallObjectMethod(entry, getString);
+ char *str = (char *) env->GetStringUTFChars(string, NULL);
+ int rv = -1;
+
+ if (!str) { // Out of memory
+ ALOGE("androidFmRadioTxSetRDSData: out of memory");
+ THROW_IO_ERROR(&fmTransmitterSession); /* excecution will continue to cleanup */
+ rv = -2; /* not -1 since we already thrown exception */
+ } else if ((strcmp(str, "PI") == 0) ||
+ (strcmp(str, "TP") == 0) ||
+ (strcmp(str, "PTY") == 0) ||
+ (strcmp(str, "TA") == 0) ||
+ (strcmp(str, "M/S") == 0)) {
+ /* types setting numeric (short) value */
+ int passedval = 0;
+ short value = env->CallShortMethod(bundle, bundle_p->mGetShort,
+ env->NewStringUTF(str));
+
+ passedval = (int) value;
+ rv = fmTransmitterSession.
+ vendorMethods_p->set_rds_data(&fmTransmitterSession.
+ vendorData_p, str,
+ &passedval);
+ } else if (!strcmp(str, "TAF")) {
+ /* type setting numeric (int) value */
+ int value = env->CallIntMethod(bundle, bundle_p->mGetInt,
+ env->NewStringUTF(str));
+
+ rv = fmTransmitterSession.
+ vendorMethods_p->set_rds_data(&fmTransmitterSession.
+ vendorData_p, str,
+ &value);
+ } else if (strcmp(str, "AF") == 0) {
+ /* type setting array of ints */
+ jintArray value = (jintArray) env->CallObjectMethod(bundle,
+ bundle_p->mGetIntArray,
+ env->NewStringUTF
+ (str));
+
+ int numInts = (value ? env->GetArrayLength(value) : 0);
+
+ if (numInts == 0) {
+ env->DeleteLocalRef(entry);
+ env->ReleaseStringUTFChars(string, str);
+ env->DeleteLocalRef(string);
+ goto free_up_and_leave;
+ }
+
+ int *temparray = env->GetIntArrayElements(value, NULL);
+ int *array = (int *) malloc((numInts + 1) * sizeof(*temparray));
+
+
+ if (array != NULL) {
+ // Place a 0 after the final entry
+ memcpy(array, temparray, numInts * sizeof(*temparray));
+ array[numInts] = 0;
+ rv = fmTransmitterSession.vendorMethods_p->
+ set_rds_data(&fmTransmitterSession.vendorData_p, str, array);
+ free(array);
+ } else {
+ ALOGE("android_setRdsData:malloc failed");
+ rv = -1;
+ }
+ env->ReleaseIntArrayElements(value, temparray, 0);
+ } else if (strcmp(str, "TMC") == 0) {
+ /* type setting array of shorts */
+ jshortArray value = (jshortArray) env->CallObjectMethod(bundle,
+ bundle_p->mGetShortArray,
+ env->NewStringUTF
+ ("TMC"));
+ int numShorts = (value ? env->GetArrayLength(value) : 0);
+ short *temparray = env->GetShortArrayElements(value, NULL);
+ short *array = (short *) malloc((numShorts + 1) * sizeof(*temparray));
+
+ if (array != NULL) {
+ // Place a 0 after the final entry
+ memcpy(array, temparray, numShorts * sizeof(*temparray));
+ array[numShorts] = 0;
+ rv = fmTransmitterSession.vendorMethods_p->
+ set_rds_data(&fmTransmitterSession.vendorData_p, str, array);
+ free(array);
+ } else {
+ ALOGE("android_setRdsData:malloc failed");
+ rv = -1;
+ }
+ env->ReleaseShortArrayElements(value, temparray, 0);
+ /* types setting string */
+ } else if ((strcmp(str, "PSN") == 0) ||
+ (strcmp(str, "RT") == 0) ||
+ (strcmp(str, "CT") == 0) ||
+ (strcmp(str, "PTYN") == 0)) {
+ unsigned int maxLength = 0;
+
+ if (strcmp(str, "PSN") == 0) {
+ maxLength = RDS_PSN_MAX_LENGTH;
+ } else if (strcmp(str, "RT") == 0) {
+ maxLength = RDS_RT_MAX_LENGTH;
+ } else if (strcmp(str, "CT") == 0) {
+ maxLength = RDS_CT_MAX_LENGTH;
+ } else if (strcmp(str, "PTYN") == 0) {
+ maxLength = RDS_PTYN_MAX_LENGTH;
+ }
+
+ jstring value = (jstring) env->CallObjectMethod(bundle,
+ bundle_p->
+ mGetString,
+ env->
+ NewStringUTF
+ (str));
+
+ if (value == NULL) {
+ ALOGI("android_setRdsData:No key found for %s", str);
+ rv = -1;
+ } else {
+ const char *cvalue = env->GetStringUTFChars(value, NULL);
+
+ // May need to add termination char
+ if (strlen(cvalue) > maxLength) {
+ ALOGE("android_setRdsData:%s - Too long value.", str);
+ rv = -1;
+ } else {
+ rv = fmTransmitterSession.vendorMethods_p->
+ set_rds_data(&fmTransmitterSession.vendorData_p, str, (char *) cvalue);
+ }
+ env->ReleaseStringUTFChars(value, cvalue);
+ }
+ }
+ if (rv == FMRADIO_UNSUPPORTED_OPERATION) {
+ ALOGE("android_setRdsData: key '%s' unsupported by vendor.", str);
+ } else if (rv < 0){
+ ALOGE("Error processing key '%s'", str);
+ THROW_ILLEGAL_ARGUMENT(&fmTransmitterSession); /* execution will continue to cleanup */
+ }
+ env->DeleteLocalRef(entry);
+ if (str != NULL) {
+ env->ReleaseStringUTFChars(string, str);
+ }
+ env->DeleteLocalRef(string);
+ if (rv < 0 && rv != FMRADIO_UNSUPPORTED_OPERATION) {
+ break;
+ }
+ }
+ free_up_and_leave:
+ env->DeleteLocalRef(entryClass);
+ env->DeleteLocalRef(iteratorClass);
+ env->DeleteLocalRef(iter);
+ env->DeleteLocalRef(iter2);
+ env->DeleteLocalRef(setClass);
+ env->DeleteLocalRef(keys_set);
+ }
+ resume_and_drop_lock:
+ androidFmRadioPauseIfTempResumed(&fmTransmitterSession);
+ drop_lock:
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+}
+
+static jint androidFmRadioTxGetFrequency(JNIEnv * env, jobject obj)
+{
+ ALOGI("androidFmRadioTxGetFrequency \n");
+ return androidFmRadioGetFrequency(&fmTransmitterSession);
+}
+
+static void androidFmRadioTxStopScan(JNIEnv * env, jobject obj)
+{
+ ALOGI("androidFmRadioTxStopScan\n");
+
+ androidFmRadioStopScan(&fmTransmitterSession);
+}
+
+static jboolean
+androidFmRadioTxIsBlockScanSupported(JNIEnv * env, jobject obj)
+{
+ bool retval;
+
+ ALOGI("androidFmRadioTxIsBlockScanSupported:\n");
+
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+
+ /* if we haven't register we don't know yet */
+ if (!fmTransmitterSession.isRegistered) {
+ retval = false;
+ goto drop_lock;
+ }
+ // valid in all states
+ if (fmTransmitterSession.vendorMethods_p->block_scan != NULL) {
+ retval = true;
+ } else {
+ retval = false;
+ }
+
+ drop_lock:
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+ return retval;
+}
+
+static void *execute_androidFmRadioTxBlockScan(void *args_p)
+{
+ struct FmRadioBlockScanParameters *inArgs_p = (struct FmRadioBlockScanParameters *) args_p;
+ int startFreq = inArgs_p->startFreq;
+ int endFreq = inArgs_p->endFreq;
+ int retval;
+ enum FmRadioState_t oldState = fmTransmitterSession.oldState;
+ int *rssi_p = NULL;
+ int *freqs_p = NULL;
+
+ free(inArgs_p);
+
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+
+ /*
+ * we should still be in SCANNING mode, but we can't be 100.00 % sure since
+ * main thread released lock before we could run
+ *
+ */
+
+ if (fmTransmitterSession.state != FMRADIO_STATE_SCANNING) {
+ ALOGE("execute_androidFmRadioTxBlockScan - warning, state not scanning\n");
+ }
+
+ /*
+ * if mode has been changed to IDLE in the mean time by main thread,
+ * exit the worker thread gracefully
+ */
+ if (fmTransmitterSession.state == FMRADIO_STATE_IDLE) {
+ goto drop_lock;
+ }
+ // temporary resume chip if sleeping
+ if (oldState == FMRADIO_STATE_PAUSED) {
+ (void) fmTransmitterSession.vendorMethods_p->
+ resume(&fmTransmitterSession.vendorData_p);
+ }
+
+ if (pthread_cond_signal(&fmTransmitterSession.sync_cond) != 0) {
+ ALOGE("execute_androidFmRadioTxBlockScan - warning, signal failed\n");
+ }
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+
+ retval =
+ fmTransmitterSession.
+ vendorMethods_p->block_scan(&fmTransmitterSession.vendorData_p,
+ startFreq, endFreq, &freqs_p, &rssi_p);
+
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+
+ /*
+ * if state has changed we should keep it, probably a forced pause or
+ * forced reset
+ */
+ if (fmTransmitterSession.state != FMRADIO_STATE_SCANNING) {
+ ALOGI("State changed while scanning (state now %d), keeping\n",
+ fmTransmitterSession.state);
+ retval = -1;
+ } else {
+ if (fmTransmitterSession.pendingPause) {
+ FMRADIO_SET_STATE(&fmTransmitterSession, FMRADIO_STATE_PAUSED);
+ } else {
+ FMRADIO_SET_STATE(&fmTransmitterSession, oldState);
+ }
+
+ fmTransmitterSession.pendingPause = false;
+ }
+
+ if (retval >= 0) {
+ fmTransmitterSession.callbacks_p->onBlockScan(retval, freqs_p,
+ rssi_p,
+ fmTransmitterSession.
+ lastScanAborted);
+ } else {
+ fmTransmitterSession.callbacks_p->onError();
+ }
+
+ drop_lock:
+
+ if (rssi_p != NULL) {
+ free(rssi_p);
+ }
+
+ if (freqs_p != NULL) {
+ free(freqs_p);
+ }
+
+ /* Wake up the main thread if it is currently waiting on the condition variable */
+ if (pthread_cond_signal(&fmTransmitterSession.sync_cond) != 0) {
+ ALOGE("execute_androidFmRadioTxBlockScan - signal failed\n");
+ }
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+
+ pthread_exit(NULL);
+
+ return NULL;
+}
+
+static void
+androidFmRadioTxStartBlockScan(JNIEnv * env, jobject obj,
+ int startFreq, int endFreq)
+{
+ int retval = 0;
+
+ ALOGI("androidFmRadioTxStartBlockScan, From = %d, To = %d\n",
+ startFreq, endFreq);
+
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+
+ if (!androidFmRadioIsValidEventForState
+ (&fmTransmitterSession, FMRADIO_EVENT_BLOCK_SCAN)) {
+ retval = FMRADIO_INVALID_STATE;
+ goto drop_lock;
+ }
+
+ if (fmTransmitterSession.vendorMethods_p->block_scan) {
+ struct FmRadioBlockScanParameters* args_p = (struct FmRadioBlockScanParameters*) malloc(sizeof(struct FmRadioBlockScanParameters));
+
+ pthread_t execute_thread;
+
+ args_p->startFreq = startFreq;
+ args_p->endFreq = endFreq;
+
+ fmTransmitterSession.oldState = fmTransmitterSession.state;
+
+ FMRADIO_SET_STATE(&fmTransmitterSession, FMRADIO_STATE_SCANNING);
+
+ fmTransmitterSession.lastScanAborted = false;
+
+ if (pthread_create
+ (&execute_thread, NULL, execute_androidFmRadioTxBlockScan,
+ args_p) != 0) {
+
+ ALOGE("pthread_create failure...\n");
+ free(args_p);
+
+ FMRADIO_SET_STATE(&fmTransmitterSession, fmTransmitterSession.oldState);
+ retval = FMRADIO_IO_ERROR;
+ } else {
+ /* await thread startup, THREAD_WAIT_TIMEOUT_S sec timeout */
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += THREAD_WAIT_TIMEOUT_S;
+ if (pthread_cond_timedwait(&fmTransmitterSession.sync_cond,
+ fmTransmitterSession.dataMutex_p,
+ &ts) != 0) {
+ ALOGE("androidFmRadioTxStartBlockScan: warning, wait failure\n");
+ }
+ pthread_detach(execute_thread);
+ }
+ } else {
+ retval = FMRADIO_UNSUPPORTED_OPERATION;
+ }
+
+ drop_lock:
+ if (retval == FMRADIO_INVALID_STATE) {
+ THROW_INVALID_STATE(&fmTransmitterSession);
+ } else if (retval < 0) {
+ THROW_IO_ERROR(&fmTransmitterSession);
+ }
+
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+}
+
+static jboolean androidFmRadioTxSendExtraCommand(JNIEnv * env, jobject obj,
+ jstring command,
+ jobjectArray parameters)
+{
+ ALOGI("androidFmRadioTxSendExtraCommand");
+
+ /* we need to set jobj since this might be called before start */
+
+
+ if (fmTransmitterSession.jobj == NULL)
+ fmTransmitterSession.jobj = env->NewGlobalRef(obj);
+
+ androidFmRadioSendExtraCommand(&fmTransmitterSession, env, command,
+ parameters);
+
+ return true;
+}
+
+static JNINativeMethod gMethods[] = {
+ {(char*)"_fm_transmitter_getState", (char*)"()I",
+ (void *) androidFmRadioTxGetState},
+ {(char*)"_fm_transmitter_start", (char*)"(IIII)V",
+ (void *) androidFmRadioTxStart},
+ {(char*)"_fm_transmitter_startAsync", (char*)"(IIII)V",
+ (void *) androidFmRadioTxStartAsync},
+ {(char*)"_fm_transmitter_pause", (char*)"()V",
+ (void *) androidFmRadioTxPause},
+ {(char*)"_fm_transmitter_resume", (char*)"()V",
+ (void *) androidFmRadioTxResume},
+ {(char*)"_fm_transmitter_reset", (char*)"()I",
+ (void *) androidFmRadioTxReset},
+ {(char*)"_fm_transmitter_setFrequency", (char*)"(I)V",
+ (void *) androidFmRadioTxSetFrequency},
+ {(char*)"_fm_transmitter_getFrequency", (char*)"()I",
+ (void *) androidFmRadioTxGetFrequency},
+ {(char*)"_fm_transmitter_isBlockScanSupported", (char*)"()Z",
+ (void *) androidFmRadioTxIsBlockScanSupported},
+ {(char*)"_fm_transmitter_startBlockScan", (char*)"(II)V",
+ (void *) androidFmRadioTxStartBlockScan},
+ {(char*)"_fm_transmitter_stopScan", (char*)"()V",
+ (void *) androidFmRadioTxStopScan},
+ {(char*)"_fm_transmitter_setRdsData", (char*)"(Landroid/os/Bundle;)V",
+ (void *) androidFmRadioTxSetRDSData},
+ {(char*)"_fm_transmitter_sendExtraCommand",
+ (char*)"(Ljava/lang/String;[Ljava/lang/String;)Z",
+ (void *) androidFmRadioTxSendExtraCommand},
+
+};
+
+int registerAndroidFmRadioTransmitter(JavaVM * vm, JNIEnv * env)
+{
+
+ ALOGI("registerAndroidFmRadioTransmitter\n");
+ pthread_mutex_lock(fmTransmitterSession.dataMutex_p);
+ fmTransmitterSession.jvm_p = vm;
+ // setRDS bundle handling
+ jclass clazz = env->FindClass("android/os/Bundle");
+
+
+ struct bundle_descriptor_offsets_t *bundle_p =
+ (struct bundle_descriptor_offsets_t *)
+ malloc(sizeof(struct bundle_descriptor_offsets_t));
+
+ bundle_p->mSize = env->GetMethodID(clazz, "size", "()I");
+ bundle_p->mGetInt =
+ env->GetMethodID(clazz, "getInt", "(Ljava/lang/String;)I");
+ bundle_p->mGetIntArray =
+ env->GetMethodID(clazz, "getIntArray", "(Ljava/lang/String;)[I");
+ bundle_p->mGetShort =
+ env->GetMethodID(clazz, "getShort", "(Ljava/lang/String;)S");
+ bundle_p->mGetShortArray =
+ env->GetMethodID(clazz, "getShortArray", "(Ljava/lang/String;)[S");
+ bundle_p->mGetString =
+ env->GetMethodID(clazz, "getString",
+ "(Ljava/lang/String;)Ljava/lang/String;");
+ bundle_p->mContainsKey =
+ env->GetMethodID(clazz, "containsKey", "(Ljava/lang/String;)Z");
+ bundle_p->mKeySet =
+ env->GetMethodID(clazz, "keySet", "()Ljava/util/Set;");
+ bundle_p->mClass = (jclass) env->NewGlobalRef(clazz);
+ bundle_p->mConstructor = env->GetMethodID(clazz, "<init>", "()V");
+ bundle_p->mPutInt =
+ env->GetMethodID(clazz, "putInt", "(Ljava/lang/String;I)V");
+ bundle_p->mPutIntArray =
+ env->GetMethodID(clazz, "putIntArray", "(Ljava/lang/String;[I)V");
+ bundle_p->mPutShortArray =
+ env->GetMethodID(clazz, "putShortArray",
+ "(Ljava/lang/String;[S)V");
+ bundle_p->mPutString =
+ env->GetMethodID(clazz, "putString",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ fmTransmitterSession.bundleOffsets_p = bundle_p;
+ pthread_mutex_unlock(fmTransmitterSession.dataMutex_p);
+
+ return jniRegisterNativeMethods(env,
+ "com/stericsson/hardware/fm/FmTransmitterService",
+ gMethods, NELEM(gMethods));
+}
+
+/* *INDENT-OFF* */
+}; // namespace android
diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h
index d153c31..2717de9 100644
--- a/include/androidfw/AssetManager.h
+++ b/include/androidfw/AssetManager.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +23,7 @@
#include <androidfw/Asset.h>
#include <androidfw/AssetDir.h>
+#include <androidfw/PackageRedirectionMap.h>
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include <utils/String16.h>
@@ -92,7 +94,7 @@ public:
* then on success, *cookie is set to the value corresponding to the
* newly-added asset source.
*/
- bool addAssetPath(const String8& path, void** cookie);
+ bool addAssetPath(const String8& path, void** cookie, bool asSkin=false);
/*
* Convenience for adding the standard system assets. Uses the
@@ -218,14 +220,28 @@ public:
*/
void getLocales(Vector<String8>* locales) const;
+ /*
+ * Remove existing source for assets.
+ *
+ * Also updates the ResTable object to reflect the change.
+ *
+ * Returns "true" on success, "false" on failure.
+ */
+ bool detachThemePath(const String8& packageName, void *cookie);
+ bool attachThemePath(const String8& path, void** cookie);
+ void addRedirections(PackageRedirectionMap* resMap);
+ void clearRedirections();
+
private:
struct asset_path
{
String8 path;
FileType type;
String8 idmap;
+ bool asSkin;
};
+ void updateResTableFromAssetPath(ResTable* rt, const asset_path& ap, void* cookie) const;
Asset* openInPathLocked(const char* fileName, AccessMode mode,
const asset_path& path);
Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
diff --git a/include/androidfw/PackageRedirectionMap.h b/include/androidfw/PackageRedirectionMap.h
new file mode 100644
index 0000000..9e6435b
--- /dev/null
+++ b/include/androidfw/PackageRedirectionMap.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+#ifndef ANDROID_PACKAGEREDIRECTIONMAP_H
+#define ANDROID_PACKAGEREDIRECTIONMAP_H
+
+#include <binder/Parcel.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class PackageRedirectionMap
+{
+public:
+ PackageRedirectionMap();
+ ~PackageRedirectionMap();
+
+ bool addRedirection(uint32_t fromIdent, uint32_t toIdent);
+ uint32_t lookupRedirection(uint32_t fromIdent);
+
+ // If there are no redirections present in this map, this method will
+ // return -1.
+ int getPackage();
+
+ // Usage of the following methods is intended to be used only by the JNI
+ // methods for the purpose of parceling.
+ size_t getNumberOfTypes();
+ size_t getNumberOfUsedTypes();
+
+ size_t getNumberOfEntries(int type);
+ size_t getNumberOfUsedEntries(int type);
+
+ // Similar to lookupRedirection, but with no sanity checking.
+ uint32_t getEntry(int type, int entry);
+
+private:
+ int mPackage;
+
+ /*
+ * Sparse array organized into two layers: first by type, then by entry.
+ * The result of each lookup will be a qualified resource ID in the theme
+ * package scope.
+ *
+ * Underneath each layer is a SharedBuffer which
+ * indicates the array size.
+ */
+ uint32_t** mEntriesByType;
+};
+
+} // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_PACKAGEREDIRECTIONMAP_H
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 48f5bf3..ddefff4 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2005 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +24,7 @@
#include <androidfw/Asset.h>
#include <utils/ByteOrder.h>
#include <utils/Errors.h>
+#include <androidfw/PackageRedirectionMap.h>
#include <utils/String16.h>
#include <utils/Vector.h>
@@ -1284,6 +1286,9 @@ public:
bool copyData=false, const void* idmap = NULL);
status_t add(ResTable* src);
+ void addRedirections(PackageRedirectionMap* resMap);
+ void clearRedirections();
+
status_t getError() const;
void uninit();
@@ -1331,6 +1336,8 @@ public:
uint32_t* inoutTypeSpecFlags = NULL,
ResTable_config* outConfig = NULL) const;
+ uint32_t lookupRedirectionMap(uint32_t resID) const;
+
enum {
TMP_BUFFER_SIZE = 16
};
@@ -1551,6 +1558,7 @@ public:
// IDMAP_HEADER_SIZE_BYTES) bytes of an idmap file.
static bool getIdmapInfo(const void* idmap, size_t size,
uint32_t* pOriginalCrc, uint32_t* pOverlayCrc);
+ void removeAssetsByCookie(const String8 &packageName, void* cookie);
#ifndef HAVE_ANDROID_OS
void print(bool inclValues) const;
@@ -1593,6 +1601,11 @@ private:
// Mapping from resource package IDs to indices into the internal
// package array.
uint8_t mPackageMap[256];
+
+ // Resource redirection mapping provided by the applied theme (if there is
+ // one). Resources requested which are found in this map will be
+ // automatically redirected to the appropriate themed value.
+ Vector<PackageRedirectionMap*> mRedirectionMap;
};
} // namespace android
diff --git a/include/androidfw/ZipEntry.h b/include/androidfw/ZipEntry.h
new file mode 100644
index 0000000..7f721b4
--- /dev/null
+++ b/include/androidfw/ZipEntry.h
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Zip archive entries.
+//
+// The ZipEntry class is tightly meshed with the ZipFile class.
+//
+#ifndef __LIBS_ZIPENTRY_H
+#define __LIBS_ZIPENTRY_H
+
+#include <utils/Errors.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+namespace android {
+
+class ZipFile;
+
+/*
+ * ZipEntry objects represent a single entry in a Zip archive.
+ *
+ * You can use one of these to get or set information about an entry, but
+ * there are no functions here for accessing the data itself. (We could
+ * tuck a pointer to the ZipFile in here for convenience, but that raises
+ * the likelihood of using ZipEntry objects after discarding the ZipFile.)
+ *
+ * File information is stored in two places: next to the file data (the Local
+ * File Header, and possibly a Data Descriptor), and at the end of the file
+ * (the Central Directory Entry). The two must be kept in sync.
+ */
+class ZipEntry {
+public:
+ friend class ZipFile;
+
+ ZipEntry(void)
+ : mDeleted(false), mMarked(false)
+ {}
+ ~ZipEntry(void) {}
+
+ /*
+ * Returns "true" if the data is compressed.
+ */
+ bool isCompressed(void) const {
+ return mCDE.mCompressionMethod != kCompressStored;
+ }
+ int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }
+
+ /*
+ * Return the uncompressed length.
+ */
+ off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }
+
+ /*
+ * Return the compressed length. For uncompressed data, this returns
+ * the same thing as getUncompresesdLen().
+ */
+ off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }
+
+ /*
+ * Return the absolute file offset of the start of the compressed or
+ * uncompressed data.
+ */
+ off_t getFileOffset(void) const {
+ return mCDE.mLocalHeaderRelOffset +
+ LocalFileHeader::kLFHLen +
+ mLFH.mFileNameLength +
+ mLFH.mExtraFieldLength;
+ }
+
+ /*
+ * Return the data CRC.
+ */
+ unsigned long getCRC32(void) const { return mCDE.mCRC32; }
+
+ /*
+ * Return file modification time in UNIX seconds-since-epoch.
+ */
+ time_t getModWhen(void) const;
+
+ /*
+ * Return the archived file name.
+ */
+ const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
+
+ /*
+ * Application-defined "mark". Can be useful when synchronizing the
+ * contents of an archive with contents on disk.
+ */
+ bool getMarked(void) const { return mMarked; }
+ void setMarked(bool val) { mMarked = val; }
+
+ /*
+ * Some basic functions for raw data manipulation. "LE" means
+ * Little Endian.
+ */
+ static inline unsigned short getShortLE(const unsigned char* buf) {
+ return buf[0] | (buf[1] << 8);
+ }
+ static inline unsigned long getLongLE(const unsigned char* buf) {
+ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+ }
+ static inline void putShortLE(unsigned char* buf, short val) {
+ buf[0] = (unsigned char) val;
+ buf[1] = (unsigned char) (val >> 8);
+ }
+ static inline void putLongLE(unsigned char* buf, long val) {
+ buf[0] = (unsigned char) val;
+ buf[1] = (unsigned char) (val >> 8);
+ buf[2] = (unsigned char) (val >> 16);
+ buf[3] = (unsigned char) (val >> 24);
+ }
+
+ /* defined for Zip archives */
+ enum {
+ kCompressStored = 0, // no compression
+ // shrunk = 1,
+ // reduced 1 = 2,
+ // reduced 2 = 3,
+ // reduced 3 = 4,
+ // reduced 4 = 5,
+ // imploded = 6,
+ // tokenized = 7,
+ kCompressDeflated = 8, // standard deflate
+ // Deflate64 = 9,
+ // lib imploded = 10,
+ // reserved = 11,
+ // bzip2 = 12,
+ };
+
+ /*
+ * Deletion flag. If set, the entry will be removed on the next
+ * call to "flush".
+ */
+ bool getDeleted(void) const { return mDeleted; }
+
+protected:
+ /*
+ * Initialize the structure from the file, which is pointing at
+ * our Central Directory entry.
+ */
+ status_t initFromCDE(FILE* fp);
+
+ /*
+ * Initialize the structure for a new file. We need the filename
+ * and comment so that we can properly size the LFH area. The
+ * filename is mandatory, the comment is optional.
+ */
+ void initNew(const char* fileName, const char* comment);
+
+ /*
+ * Initialize the structure with the contents of a ZipEntry from
+ * another file.
+ */
+ status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);
+
+ /*
+ * Add some pad bytes to the LFH. We do this by adding or resizing
+ * the "extra" field.
+ */
+ status_t addPadding(int padding);
+
+ /*
+ * Set information about the data for this entry.
+ */
+ void setDataInfo(long uncompLen, long compLen, unsigned long crc32,
+ int compressionMethod);
+
+ /*
+ * Set the modification date.
+ */
+ void setModWhen(time_t when);
+
+ /*
+ * Return the offset of the local file header.
+ */
+ off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
+
+ /*
+ * Set the offset of the local file header, relative to the start of
+ * the current file.
+ */
+ void setLFHOffset(off_t offset) {
+ mCDE.mLocalHeaderRelOffset = (long) offset;
+ }
+
+ /* mark for deletion; used by ZipFile::remove() */
+ void setDeleted(void) { mDeleted = true; }
+
+private:
+ /* these are private and not defined */
+ ZipEntry(const ZipEntry& src);
+ ZipEntry& operator=(const ZipEntry& src);
+
+ /* returns "true" if the CDE and the LFH agree */
+ bool compareHeaders(void) const;
+ void copyCDEtoLFH(void);
+
+ bool mDeleted; // set if entry is pending deletion
+ bool mMarked; // app-defined marker
+
+ /*
+ * Every entry in the Zip archive starts off with one of these.
+ */
+ class LocalFileHeader {
+ public:
+ LocalFileHeader(void) :
+ mVersionToExtract(0),
+ mGPBitFlag(0),
+ mCompressionMethod(0),
+ mLastModFileTime(0),
+ mLastModFileDate(0),
+ mCRC32(0),
+ mCompressedSize(0),
+ mUncompressedSize(0),
+ mFileNameLength(0),
+ mExtraFieldLength(0),
+ mFileName(NULL),
+ mExtraField(NULL)
+ {}
+ virtual ~LocalFileHeader(void) {
+ delete[] mFileName;
+ delete[] mExtraField;
+ }
+
+ status_t read(FILE* fp);
+ status_t write(FILE* fp);
+
+ // unsigned long mSignature;
+ unsigned short mVersionToExtract;
+ unsigned short mGPBitFlag;
+ unsigned short mCompressionMethod;
+ unsigned short mLastModFileTime;
+ unsigned short mLastModFileDate;
+ unsigned long mCRC32;
+ unsigned long mCompressedSize;
+ unsigned long mUncompressedSize;
+ unsigned short mFileNameLength;
+ unsigned short mExtraFieldLength;
+ unsigned char* mFileName;
+ unsigned char* mExtraField;
+
+ enum {
+ kSignature = 0x04034b50,
+ kLFHLen = 30, // LocalFileHdr len, excl. var fields
+ };
+
+ void dump(void) const;
+ };
+
+ /*
+ * Every entry in the Zip archive has one of these in the "central
+ * directory" at the end of the file.
+ */
+ class CentralDirEntry {
+ public:
+ CentralDirEntry(void) :
+ mVersionMadeBy(0),
+ mVersionToExtract(0),
+ mGPBitFlag(0),
+ mCompressionMethod(0),
+ mLastModFileTime(0),
+ mLastModFileDate(0),
+ mCRC32(0),
+ mCompressedSize(0),
+ mUncompressedSize(0),
+ mFileNameLength(0),
+ mExtraFieldLength(0),
+ mFileCommentLength(0),
+ mDiskNumberStart(0),
+ mInternalAttrs(0),
+ mExternalAttrs(0),
+ mLocalHeaderRelOffset(0),
+ mFileName(NULL),
+ mExtraField(NULL),
+ mFileComment(NULL)
+ {}
+ virtual ~CentralDirEntry(void) {
+ delete[] mFileName;
+ delete[] mExtraField;
+ delete[] mFileComment;
+ }
+
+ status_t read(FILE* fp);
+ status_t write(FILE* fp);
+
+ // unsigned long mSignature;
+ unsigned short mVersionMadeBy;
+ unsigned short mVersionToExtract;
+ unsigned short mGPBitFlag;
+ unsigned short mCompressionMethod;
+ unsigned short mLastModFileTime;
+ unsigned short mLastModFileDate;
+ unsigned long mCRC32;
+ unsigned long mCompressedSize;
+ unsigned long mUncompressedSize;
+ unsigned short mFileNameLength;
+ unsigned short mExtraFieldLength;
+ unsigned short mFileCommentLength;
+ unsigned short mDiskNumberStart;
+ unsigned short mInternalAttrs;
+ unsigned long mExternalAttrs;
+ unsigned long mLocalHeaderRelOffset;
+ unsigned char* mFileName;
+ unsigned char* mExtraField;
+ unsigned char* mFileComment;
+
+ void dump(void) const;
+
+ enum {
+ kSignature = 0x02014b50,
+ kCDELen = 46, // CentralDirEnt len, excl. var fields
+ };
+ };
+
+ enum {
+ //kDataDescriptorSignature = 0x08074b50, // currently unused
+ kDataDescriptorLen = 16, // four 32-bit fields
+
+ kDefaultVersion = 20, // need deflate, nothing much else
+ kDefaultMadeBy = 0x0317, // 03=UNIX, 17=spec v2.3
+ kUsesDataDescr = 0x0008, // GPBitFlag bit 3
+ };
+
+ LocalFileHeader mLFH;
+ CentralDirEntry mCDE;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ZIPENTRY_H
diff --git a/include/androidfw/ZipFile.h b/include/androidfw/ZipFile.h
new file mode 100644
index 0000000..dbbd072
--- /dev/null
+++ b/include/androidfw/ZipFile.h
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// General-purpose Zip archive access. This class allows both reading and
+// writing to Zip archives, including deletion of existing entries.
+//
+#ifndef __LIBS_ZIPFILE_H
+#define __LIBS_ZIPFILE_H
+
+#include <utils/Vector.h>
+#include <utils/Errors.h>
+#include <stdio.h>
+
+#include "ZipEntry.h"
+
+namespace android {
+
+/*
+ * Manipulate a Zip archive.
+ *
+ * Some changes will not be visible in the until until "flush" is called.
+ *
+ * The correct way to update a file archive is to make all changes to a
+ * copy of the archive in a temporary file, and then unlink/rename over
+ * the original after everything completes. Because we're only interested
+ * in using this for packaging, we don't worry about such things. Crashing
+ * after making changes and before flush() completes could leave us with
+ * an unusable Zip archive.
+ */
+class ZipFile {
+public:
+ ZipFile(void)
+ : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)
+ {}
+ ~ZipFile(void) {
+ if (!mReadOnly)
+ flush();
+ if (mZipFp != NULL)
+ fclose(mZipFp);
+ discardEntries();
+ }
+
+ /*
+ * Open a new or existing archive.
+ */
+ typedef enum {
+ kOpenReadOnly = 0x01,
+ kOpenReadWrite = 0x02,
+ kOpenCreate = 0x04, // create if it doesn't exist
+ kOpenTruncate = 0x08, // if it exists, empty it
+ };
+ status_t open(const char* zipFileName, int flags);
+
+ /*
+ * Add a file to the end of the archive. Specify whether you want the
+ * library to try to store it compressed.
+ *
+ * If "storageName" is specified, the archive will use that instead
+ * of "fileName".
+ *
+ * If there is already an entry with the same name, the call fails.
+ * Existing entries with the same name must be removed first.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t add(const char* fileName, int compressionMethod,
+ ZipEntry** ppEntry)
+ {
+ return add(fileName, fileName, compressionMethod, ppEntry);
+ }
+ status_t add(const char* fileName, const char* storageName,
+ int compressionMethod, ZipEntry** ppEntry)
+ {
+ return addCommon(fileName, NULL, 0, storageName,
+ ZipEntry::kCompressStored,
+ compressionMethod, ppEntry);
+ }
+
+ /*
+ * Add a file that is already compressed with gzip.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t addGzip(const char* fileName, const char* storageName,
+ ZipEntry** ppEntry)
+ {
+ return addCommon(fileName, NULL, 0, storageName,
+ ZipEntry::kCompressDeflated,
+ ZipEntry::kCompressDeflated, ppEntry);
+ }
+
+ /*
+ * Add a file from an in-memory data buffer.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t add(const void* data, size_t size, const char* storageName,
+ int compressionMethod, ZipEntry** ppEntry)
+ {
+ return addCommon(NULL, data, size, storageName,
+ ZipEntry::kCompressStored,
+ compressionMethod, ppEntry);
+ }
+
+ /*
+ * Add an entry by copying it from another zip file. If "padding" is
+ * nonzero, the specified number of bytes will be added to the "extra"
+ * field in the header.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+ int padding, ZipEntry** ppEntry);
+
+ /*
+ * Mark an entry as having been removed. It is not actually deleted
+ * from the archive or our internal data structures until flush() is
+ * called.
+ */
+ status_t remove(ZipEntry* pEntry);
+
+ /*
+ * Flush changes. If mNeedCDRewrite is set, this writes the central dir.
+ */
+ status_t flush(void);
+
+ /*
+ * Expand the data into the buffer provided. The buffer must hold
+ * at least <uncompressed len> bytes. Variation expands directly
+ * to a file.
+ *
+ * Returns "false" if an error was encountered in the compressed data.
+ */
+ //bool uncompress(const ZipEntry* pEntry, void* buf) const;
+ //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
+ void* uncompress(const ZipEntry* pEntry);
+
+ /*
+ * Get an entry, by name. Returns NULL if not found.
+ *
+ * Does not return entries pending deletion.
+ */
+ ZipEntry* getEntryByName(const char* fileName) const;
+
+ /*
+ * Get the Nth entry in the archive.
+ *
+ * This will return an entry that is pending deletion.
+ */
+ int getNumEntries(void) const { return mEntries.size(); }
+ ZipEntry* getEntryByIndex(int idx) const;
+
+private:
+ /* these are private and not defined */
+ ZipFile(const ZipFile& src);
+ ZipFile& operator=(const ZipFile& src);
+
+ class EndOfCentralDir {
+ public:
+ EndOfCentralDir(void) :
+ mDiskNumber(0),
+ mDiskWithCentralDir(0),
+ mNumEntries(0),
+ mTotalNumEntries(0),
+ mCentralDirSize(0),
+ mCentralDirOffset(0),
+ mCommentLen(0),
+ mComment(NULL)
+ {}
+ virtual ~EndOfCentralDir(void) {
+ delete[] mComment;
+ }
+
+ status_t readBuf(const unsigned char* buf, int len);
+ status_t write(FILE* fp);
+
+ //unsigned long mSignature;
+ unsigned short mDiskNumber;
+ unsigned short mDiskWithCentralDir;
+ unsigned short mNumEntries;
+ unsigned short mTotalNumEntries;
+ unsigned long mCentralDirSize;
+ unsigned long mCentralDirOffset; // offset from first disk
+ unsigned short mCommentLen;
+ unsigned char* mComment;
+
+ enum {
+ kSignature = 0x06054b50,
+ kEOCDLen = 22, // EndOfCentralDir len, excl. comment
+
+ kMaxCommentLen = 65535, // longest possible in ushort
+ kMaxEOCDSearch = kMaxCommentLen + EndOfCentralDir::kEOCDLen,
+
+ };
+
+ void dump(void) const;
+ };
+
+
+ /* read all entries in the central dir */
+ status_t readCentralDir(void);
+
+ /* crunch deleted entries out */
+ status_t crunchArchive(void);
+
+ /* clean up mEntries */
+ void discardEntries(void);
+
+ /* common handler for all "add" functions */
+ status_t addCommon(const char* fileName, const void* data, size_t size,
+ const char* storageName, int sourceType, int compressionMethod,
+ ZipEntry** ppEntry);
+
+ /* copy all of "srcFp" into "dstFp" */
+ status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);
+ /* copy all of "data" into "dstFp" */
+ status_t copyDataToFp(FILE* dstFp,
+ const void* data, size_t size, unsigned long* pCRC32);
+ /* copy some of "srcFp" into "dstFp" */
+ status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
+ unsigned long* pCRC32);
+ /* like memmove(), but on parts of a single file */
+ status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);
+ /* compress all of "srcFp" into "dstFp", using Deflate */
+ status_t compressFpToFp(FILE* dstFp, FILE* srcFp,
+ const void* data, size_t size, unsigned long* pCRC32);
+
+ /* get modification date from a file descriptor */
+ time_t getModTime(int fd);
+
+ /*
+ * We use stdio FILE*, which gives us buffering but makes dealing
+ * with files >2GB awkward. Until we support Zip64, we're fine.
+ */
+ FILE* mZipFp; // Zip file pointer
+
+ /* one of these per file */
+ EndOfCentralDir mEOCD;
+
+ /* did we open this read-only? */
+ bool mReadOnly;
+
+ /* set this when we trash the central dir */
+ bool mNeedCDRewrite;
+
+ /*
+ * One ZipEntry per entry in the zip file. I'm using pointers instead
+ * of objects because it's easier than making operator= work for the
+ * classes and sub-classes.
+ */
+ Vector<ZipEntry*> mEntries;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ZIPFILE_H
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 3ed75a2..7e53000 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -22,8 +22,11 @@ commonUtilsSources:= \
Asset.cpp \
AssetDir.cpp \
AssetManager.cpp \
+ PackageRedirectionMap.cpp \
ObbFile.cpp \
ResourceTypes.cpp \
+ ../../tools/aapt/ZipFile.cpp \
+ ../../tools/aapt/ZipEntry.cpp \
StreamingZipInflater.cpp
# formerly in libui
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 8bd805c..806e716 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -152,7 +153,7 @@ AssetManager::~AssetManager(void)
delete[] mVendor;
}
-bool AssetManager::addAssetPath(const String8& path, void** cookie)
+bool AssetManager::addAssetPath(const String8& path, void** cookie, bool asSkin)
{
AutoMutex _l(mLock);
@@ -162,6 +163,7 @@ bool AssetManager::addAssetPath(const String8& path, void** cookie)
if (kAppZipName) {
realPath.appendPath(kAppZipName);
}
+ ap.asSkin = asSkin;
ap.type = ::getFileType(realPath.string());
if (ap.type == kFileTypeRegular) {
ap.path = realPath;
@@ -516,9 +518,13 @@ Asset* AssetManager::open(const char* fileName, AccessMode mode)
size_t i = mAssetPaths.size();
while (i > 0) {
i--;
+ const asset_path& ap = mAssetPaths.itemAt(i);
+ if (ap.asSkin) {
+ continue;
+ }
ALOGV("Looking for asset '%s' in '%s'\n",
- assetName.string(), mAssetPaths.itemAt(i).path.string());
- Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
+ assetName.string(), ap.path.string());
+ Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, ap);
if (pAsset != NULL) {
return pAsset != kExcludedAsset ? pAsset : NULL;
}
@@ -550,9 +556,13 @@ Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
size_t i = mAssetPaths.size();
while (i > 0) {
i--;
- ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
+ const asset_path& ap = mAssetPaths.itemAt(i);
+ if (ap.asSkin) {
+ continue;
+ }
+ ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, ap.path.string());
Asset* pAsset = openNonAssetInPathLocked(
- fileName, mode, mAssetPaths.itemAt(i));
+ fileName, mode, ap);
if (pAsset != NULL) {
return pAsset != kExcludedAsset ? pAsset : NULL;
}
@@ -631,76 +641,13 @@ const ResTable* AssetManager::getResTable(bool required) const
if (mCacheMode != CACHE_OFF && !mCacheValid)
const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
+ mResources = rt = new ResTable();
- const size_t N = mAssetPaths.size();
- for (size_t i=0; i<N; i++) {
- Asset* ass = NULL;
- ResTable* sharedRes = NULL;
- bool shared = true;
- const asset_path& ap = mAssetPaths.itemAt(i);
- Asset* idmap = openIdmapLocked(ap);
- ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
- if (ap.type != kFileTypeDirectory) {
- if (i == 0) {
- // The first item is typically the framework resources,
- // which we want to avoid parsing every time.
- sharedRes = const_cast<AssetManager*>(this)->
- mZipSet.getZipResourceTable(ap.path);
- }
- if (sharedRes == NULL) {
- ass = const_cast<AssetManager*>(this)->
- mZipSet.getZipResourceTableAsset(ap.path);
- if (ass == NULL) {
- ALOGV("loading resource table %s\n", ap.path.string());
- ass = const_cast<AssetManager*>(this)->
- openNonAssetInPathLocked("resources.arsc",
- Asset::ACCESS_BUFFER,
- ap);
- if (ass != NULL && ass != kExcludedAsset) {
- ass = const_cast<AssetManager*>(this)->
- mZipSet.setZipResourceTableAsset(ap.path, ass);
- }
- }
-
- if (i == 0 && ass != NULL) {
- // If this is the first resource table in the asset
- // manager, then we are going to cache it so that we
- // can quickly copy it out for others.
- ALOGV("Creating shared resources for %s", ap.path.string());
- sharedRes = new ResTable();
- sharedRes->add(ass, (void*)(i+1), false, idmap);
- sharedRes = const_cast<AssetManager*>(this)->
- mZipSet.setZipResourceTable(ap.path, sharedRes);
- }
- }
- } else {
- ALOGV("loading resource table %s\n", ap.path.string());
- Asset* ass = const_cast<AssetManager*>(this)->
- openNonAssetInPathLocked("resources.arsc",
- Asset::ACCESS_BUFFER,
- ap);
- shared = false;
- }
- if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {
- if (rt == NULL) {
- mResources = rt = new ResTable();
- updateResourceParamsLocked();
- }
- ALOGV("Installing resource asset %p in to table %p\n", ass, mResources);
- if (sharedRes != NULL) {
- ALOGV("Copying existing resources for %s", ap.path.string());
- rt->add(sharedRes);
- } else {
- ALOGV("Parsing resources for %s", ap.path.string());
- rt->add(ass, (void*)(i+1), !shared, idmap);
- }
-
- if (!shared) {
- delete ass;
- }
- }
- if (idmap != NULL) {
- delete idmap;
+ if (rt) {
+ const size_t N = mAssetPaths.size();
+ for (size_t i=0; i<N; i++) {
+ const asset_path& ap = mAssetPaths.itemAt(i);
+ updateResTableFromAssetPath(rt, ap, (void*)(i+1));
}
}
@@ -708,9 +655,73 @@ const ResTable* AssetManager::getResTable(bool required) const
if (!rt) {
mResources = rt = new ResTable();
}
+
return rt;
}
+void AssetManager::updateResTableFromAssetPath(ResTable *rt, const asset_path& ap, void *cookie) const
+{
+ Asset* ass = NULL;
+ ResTable* sharedRes = NULL;
+ bool shared = true;
+ size_t cookiePos = (size_t)cookie;
+ ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
+ if (ap.type != kFileTypeDirectory) {
+ if (cookiePos == 1) {
+ // The first item is typically the framework resources,
+ // which we want to avoid parsing every time.
+ sharedRes = const_cast<AssetManager*>(this)->
+ mZipSet.getZipResourceTable(ap.path);
+ }
+ if (sharedRes == NULL) {
+ ass = const_cast<AssetManager*>(this)->
+ mZipSet.getZipResourceTableAsset(ap.path);
+ if (ass == NULL) {
+ ALOGV("loading resource table %s\n", ap.path.string());
+ ass = const_cast<AssetManager*>(this)->
+ openNonAssetInPathLocked("resources.arsc",
+ Asset::ACCESS_BUFFER,
+ ap);
+ if (ass != NULL && ass != kExcludedAsset) {
+ ass = const_cast<AssetManager*>(this)->
+ mZipSet.setZipResourceTableAsset(ap.path, ass);
+ }
+ }
+ if (cookiePos == 0 && ass != NULL) {
+ // If this is the first resource table in the asset
+ // manager, then we are going to cache it so that we
+ // can quickly copy it out for others.
+ ALOGV("Creating shared resources for %s", ap.path.string());
+ sharedRes = new ResTable();
+ sharedRes->add(ass, cookie, false);
+ sharedRes = const_cast<AssetManager*>(this)->
+ mZipSet.setZipResourceTable(ap.path, sharedRes);
+ }
+ }
+ } else {
+ ALOGV("loading resource table %s\n", ap.path.string());
+ Asset* ass = const_cast<AssetManager*>(this)->
+ openNonAssetInPathLocked("resources.arsc",
+ Asset::ACCESS_BUFFER,
+ ap);
+ shared = false;
+ }
+ if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {
+ updateResourceParamsLocked();
+ ALOGV("Installing resource asset %p in to table %p\n", ass, mResources);
+ if (sharedRes != NULL) {
+ ALOGV("Copying existing resources for %s", ap.path.string());
+ rt->add(sharedRes);
+ } else {
+ ALOGV("Parsing resources for %s", ap.path.string());
+ rt->add(ass, cookie, !shared);
+ }
+ if (!shared) {
+ delete ass;
+ }
+ }
+}
+
void AssetManager::updateResourceParamsLocked() const
{
ResTable* res = mResources;
@@ -1163,6 +1174,9 @@ AssetDir* AssetManager::openDir(const char* dirName)
while (i > 0) {
i--;
const asset_path& ap = mAssetPaths.itemAt(i);
+ if (ap.asSkin) {
+ continue;
+ }
if (ap.type == kFileTypeRegular) {
ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
@@ -2017,3 +2031,52 @@ int AssetManager::ZipSet::getIndex(const String8& zip) const
return mZipPath.size()-1;
}
+
+bool AssetManager::attachThemePath(const String8& path, void** cookie)
+{
+ bool res = addAssetPath(path, cookie, true);
+ ResTable* rt = mResources;
+ if (res && rt != NULL && ((size_t)*cookie == mAssetPaths.size())) {
+ AutoMutex _l(mLock);
+ const asset_path& ap = mAssetPaths.itemAt((size_t)*cookie - 1);
+ updateResTableFromAssetPath(rt, ap, *cookie);
+ }
+ return res;
+}
+
+bool AssetManager::detachThemePath(const String8 &packageName, void* cookie)
+{
+ AutoMutex _l(mLock);
+
+ const size_t which = ((size_t)cookie)-1;
+ if (which >= mAssetPaths.size()) {
+ return false;
+ }
+
+ /* TODO: Ensure that this cookie is added with asSkin == true. */
+ mAssetPaths.removeAt(which);
+
+ ResTable* rt = mResources;
+ if (rt == NULL) {
+ ALOGV("ResTable must not be NULL");
+ return false;
+ }
+
+ rt->removeAssetsByCookie(packageName, (void *)cookie);
+
+ return true;
+}
+
+void AssetManager::addRedirections(PackageRedirectionMap* resMap)
+{
+ getResources();
+ ResTable* rt = mResources;
+ rt->addRedirections(resMap);
+}
+
+void AssetManager::clearRedirections()
+{
+ getResources();
+ ResTable* rt = mResources;
+ rt->clearRedirections();
+}
diff --git a/libs/androidfw/PackageRedirectionMap.cpp b/libs/androidfw/PackageRedirectionMap.cpp
new file mode 100644
index 0000000..92cf312
--- /dev/null
+++ b/libs/androidfw/PackageRedirectionMap.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
+ *
+ * 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.
+ */
+
+//
+// Provide access to read-only assets.
+//
+
+#define LOG_TAG "packageresmap"
+
+#include <androidfw/PackageRedirectionMap.h>
+#include <androidfw/ResourceTypes.h>
+#include <utils/misc.h>
+
+using namespace android;
+
+PackageRedirectionMap::PackageRedirectionMap()
+ : mPackage(-1), mEntriesByType(NULL)
+{
+}
+
+static void clearEntriesByType(uint32_t** entriesByType)
+{
+ SharedBuffer* buf = SharedBuffer::bufferFromData(entriesByType);
+ const size_t N = buf->size() / sizeof(entriesByType[0]);
+ for (size_t i = 0; i < N; i++) {
+ uint32_t* entries = entriesByType[i];
+ if (entries != NULL) {
+ SharedBuffer::bufferFromData(entries)->release();
+ }
+ }
+ buf->release();
+}
+
+PackageRedirectionMap::~PackageRedirectionMap()
+{
+ if (mEntriesByType != NULL) {
+ clearEntriesByType(mEntriesByType);
+ }
+}
+
+unsigned int roundUpPower2(unsigned int val)
+{
+ val--;
+ val |= val >> 1;
+ val |= val >> 2;
+ val |= val >> 4;
+ val |= val >> 8;
+ val |= val >> 16;
+ val++;
+
+ return val;
+}
+static void* ensureCapacity(void* data, size_t nmemb, size_t size)
+{
+ SharedBuffer* buf;
+ size_t currentSize;
+
+ if (data != NULL) {
+ buf = SharedBuffer::bufferFromData(data);
+ currentSize = buf->size();
+ } else {
+ buf = NULL;
+ currentSize = 0;
+ }
+
+ size_t minSize = nmemb * size;
+ if (minSize > currentSize) {
+ unsigned int requestSize = roundUpPower2(minSize);
+ if (buf == NULL) {
+ buf = SharedBuffer::alloc(requestSize);
+ } else {
+ buf = buf->editResize(requestSize);
+ }
+ memset((unsigned char*)buf->data()+currentSize, 0, requestSize - currentSize);
+ }
+
+ return buf->data();
+}
+
+bool PackageRedirectionMap::addRedirection(uint32_t fromIdent, uint32_t toIdent)
+{
+ const int package = Res_GETPACKAGE(fromIdent);
+ const int type = Res_GETTYPE(fromIdent);
+ const int entry = Res_GETENTRY(fromIdent);
+
+ // The first time we add a redirection we can infer the package for all
+ // future redirections.
+ if (mPackage == -1) {
+ mPackage = package+1;
+ } else if (mPackage != (package+1)) {
+ ALOGW("cannot add redirection for conflicting package 0x%02x (expecting package 0x%02x)\n", package+1, mPackage);
+ return false;
+ }
+
+ mEntriesByType = (uint32_t**)ensureCapacity(mEntriesByType, type + 1, sizeof(uint32_t*));
+ uint32_t* entries = mEntriesByType[type];
+ entries = (uint32_t*)ensureCapacity(entries, entry + 1, sizeof(uint32_t));
+ entries[entry] = toIdent;
+ mEntriesByType[type] = entries;
+
+ return true;
+}
+
+uint32_t PackageRedirectionMap::lookupRedirection(uint32_t fromIdent)
+{
+ if (mPackage == -1 || mEntriesByType == NULL || fromIdent == 0) {
+ return 0;
+ }
+
+ const int package = Res_GETPACKAGE(fromIdent);
+ const int type = Res_GETTYPE(fromIdent);
+ const int entry = Res_GETENTRY(fromIdent);
+
+ if (package+1 != mPackage) {
+ return 0;
+ }
+
+ size_t nTypes = getNumberOfTypes();
+ if (type < 0 || type >= nTypes) {
+ return 0;
+ }
+ uint32_t* entries = mEntriesByType[type];
+ if (entries == NULL) {
+ return 0;
+ }
+ size_t nEntries = getNumberOfEntries(type);
+ if (entry < 0 || entry >= nEntries) {
+ return 0;
+ }
+ return entries[entry];
+}
+
+int PackageRedirectionMap::getPackage()
+{
+ return mPackage;
+}
+
+size_t PackageRedirectionMap::getNumberOfTypes()
+{
+ if (mEntriesByType == NULL) {
+ return 0;
+ } else {
+ return SharedBuffer::bufferFromData(mEntriesByType)->size() /
+ sizeof(mEntriesByType[0]);
+ }
+}
+
+size_t PackageRedirectionMap::getNumberOfUsedTypes()
+{
+ uint32_t** entriesByType = mEntriesByType;
+ size_t N = getNumberOfTypes();
+ size_t count = 0;
+ for (size_t i=0; i<N; i++) {
+ if (entriesByType[i] != NULL) {
+ count++;
+ }
+ }
+ return count;
+}
+
+size_t PackageRedirectionMap::getNumberOfEntries(int type)
+{
+ uint32_t* entries = mEntriesByType[type];
+ if (entries == NULL) {
+ return 0;
+ } else {
+ return SharedBuffer::bufferFromData(entries)->size() /
+ sizeof(entries[0]);
+ }
+}
+
+size_t PackageRedirectionMap::getNumberOfUsedEntries(int type)
+{
+ size_t N = getNumberOfEntries(type);
+ uint32_t* entries = mEntriesByType[type];
+ size_t count = 0;
+ for (size_t i=0; i<N; i++) {
+ if (entries[i] != 0) {
+ count++;
+ }
+ }
+ return count;
+}
+
+uint32_t PackageRedirectionMap::getEntry(int type, int entry)
+{
+ uint32_t* entries = mEntriesByType[type];
+ return entries[entry];
+}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index dfef47e..6282657 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +26,7 @@
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/TextOutput.h>
+#include <utils/misc.h>
#include <stdlib.h>
#include <string.h>
@@ -43,6 +45,7 @@
#define TABLE_SUPER_NOISY(x) //x
#define LOAD_TABLE_NOISY(x) //x
#define TABLE_THEME(x) //x
+#define REDIRECT_NOISY(x) //x
namespace android {
@@ -2488,6 +2491,13 @@ status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
const bag_entry* bag;
uint32_t bagTypeSpecFlags = 0;
mTable.lock();
+ uint32_t redirect = mTable.lookupRedirectionMap(resID);
+ if (redirect != 0 || resID == 0x01030005) {
+ REDIRECT_NOISY(ALOGW("applyStyle: PERFORMED REDIRECT OF ident=0x%08x FOR redirect=0x%08x\n", resID, redirect));
+ }
+ if (redirect != 0) {
+ resID = redirect;
+ }
const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
if (N < 0) {
@@ -2935,6 +2945,8 @@ void ResTable::uninit()
mPackageGroups.clear();
mHeaders.clear();
+
+ clearRedirections();
}
bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
@@ -3192,6 +3204,24 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
return blockIndex;
}
+uint32_t ResTable::lookupRedirectionMap(uint32_t resID) const
+{
+ if (mError != NO_ERROR) {
+ return 0;
+ }
+
+ const int p = Res_GETPACKAGE(resID)+1;
+
+ const size_t N = mRedirectionMap.size();
+ for (size_t i=0; i<N; i++) {
+ PackageRedirectionMap* resMap = mRedirectionMap[i];
+ if (resMap->getPackage() == p) {
+ return resMap->lookupRedirection(resID);
+ }
+ }
+ return 0;
+}
+
const char16_t* ResTable::valueToString(
const Res_value* value, size_t stringBlock,
char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen)
@@ -3397,7 +3427,19 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
if (parent) {
const bag_entry* parentBag;
uint32_t parentTypeSpecFlags = 0;
- const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags);
+ uint32_t parentRedirect = lookupRedirectionMap(parent);
+ uint32_t parentActual = parent;
+ if (parentRedirect != 0 || parent == 0x01030005) {
+ if (parentRedirect == resID) {
+ REDIRECT_NOISY(ALOGW("applyStyle(parent): ignoring circular redirect from parent=0x%08x to parentRedirect=0x%08x\n", parent, parentRedirect));
+ } else {
+ REDIRECT_NOISY(ALOGW("applyStyle(parent): PERFORMED REDIRECT OF parent=0x%08x FOR parentRedirect=0x%08x\n", parent, parentRedirect));
+ if (parentRedirect != 0) {
+ parentActual = parentRedirect;
+ }
+ }
+ }
+ const ssize_t NP = getBagLocked(parentActual, &parentBag, &parentTypeSpecFlags);
const size_t NT = ((NP >= 0) ? NP : 0) + N;
set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);
if (set == NULL) {
@@ -5319,6 +5361,78 @@ bool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes,
return true;
}
+void ResTable::removeAssetsByCookie(const String8 &packageName, void* cookie)
+{
+ mError = NO_ERROR;
+
+ size_t N = mHeaders.size();
+ for (size_t i = 0; i < N; i++) {
+ Header* header = mHeaders[i];
+ if ((size_t)header->cookie == (size_t)cookie) {
+ if (header->ownedData != NULL) {
+ free(header->ownedData);
+ }
+ mHeaders.removeAt(i);
+ break;
+ }
+ }
+ size_t pgCount = mPackageGroups.size();
+ for (size_t pgIndex = 0; pgIndex < pgCount; pgIndex++) {
+ PackageGroup* pg = mPackageGroups[pgIndex];
+
+ size_t pkgCount = pg->packages.size();
+ size_t index = pkgCount;
+ for (size_t pkgIndex = 0; pkgIndex < pkgCount; pkgIndex++) {
+ const Package* pkg = pg->packages[pkgIndex];
+ if (String8(String16(pkg->package->name)).compare(packageName) == 0) {
+ index = pkgIndex;
+ ALOGV("Delete Package %d id=%d name=%s\n",
+ (int)pkgIndex, pkg->package->id,
+ String8(String16(pkg->package->name)).string());
+ break;
+ }
+ }
+ if (index < pkgCount) {
+ const Package* pkg = pg->packages[index];
+ uint32_t id = dtohl(pkg->package->id);
+ if (id != 0 && id < 256) {
+ mPackageMap[id] = 0;
+ }
+ if (pkgCount == 1) {
+ ALOGV("Delete Package Group %d id=%d packageCount=%d name=%s\n",
+ (int)pgIndex, pg->id, (int)pg->packages.size(),
+ String8(pg->name).string());
+ mPackageGroups.removeAt(pgIndex);
+ delete pg;
+ } else {
+ pg->packages.removeAt(index);
+ delete pkg;
+ }
+ return;
+ }
+ }
+}
+
+/*
+ * Load the redirection map from the supplied map path.
+ *
+ * The path is expected to be a directory containing individual map cache files
+ * for each package that is to have resources redirected. Only those packages
+ * that are included in this ResTable will be loaded into the redirection map.
+ * For this reason, this method should be called only after all resource
+ * bundles have been added to the table.
+ */
+void ResTable::addRedirections(PackageRedirectionMap* resMap)
+{
+ // TODO: Replace an existing entry matching the same package.
+ mRedirectionMap.add(resMap);
+}
+
+void ResTable::clearRedirections()
+{
+ /* This memory is being managed by strong references at the Java layer. */
+ mRedirectionMap.clear();
+}
#ifndef HAVE_ANDROID_OS
#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 49f498e..adfc135 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -36,6 +36,16 @@ public class AudioFormat {
public static final int ENCODING_PCM_16BIT = 2;
/** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */
public static final int ENCODING_PCM_8BIT = 3;
+ /** @hide */
+ public static final int ENCODING_AMRNB = 100; // accessed by native code
+ /** @hide */
+ public static final int ENCODING_AMRWB = 101; // accessed by native code
+ /** @hide */
+ public static final int ENCODING_EVRC = 102; // accessed by native code
+ /** @hide */
+ public static final int ENCODING_EVRCB = 103; // accessed by native code
+ /** @hide */
+ public static final int ENCODING_EVRCWB = 104; // accessed by native code
/** Invalid audio channel configuration */
/** @deprecated use CHANNEL_INVALID instead */
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 035b282..f55a0bb 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -19,6 +19,8 @@ package android.media;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.PendingIntent;
+import android.app.ProfileGroup;
+import android.app.ProfileManager;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
@@ -51,6 +53,7 @@ public class AudioManager {
private final boolean mUseMasterVolume;
private final boolean mUseVolumeKeySounds;
private static String TAG = "AudioManager";
+ private final ProfileManager mProfileManager;
/**
* Broadcast intent, a hint for applications that audio is about to become
@@ -422,6 +425,7 @@ public class AudioManager {
com.android.internal.R.bool.config_useMasterVolume);
mUseVolumeKeySounds = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useVolumeKeySounds);
+ mProfileManager = (ProfileManager) context.getSystemService(Context.PROFILE_SERVICE);
}
private static IAudioService getService()
@@ -1000,6 +1004,26 @@ public class AudioManager {
* current ringer mode that can be queried via {@link #getRingerMode()}.
*/
public boolean shouldVibrate(int vibrateType) {
+ String packageName = mContext.getPackageName();
+ // Don't apply profiles for "android" context, as these could
+ // come from the NotificationManager, and originate from a real package.
+ if (!packageName.equals("android")) {
+ ProfileGroup profileGroup = mProfileManager.getActiveProfileGroup(packageName);
+ if (profileGroup != null) {
+ Log.v(TAG, "shouldVibrate, group: " + profileGroup.getUuid()
+ + " mode: " + profileGroup.getVibrateMode());
+ switch (profileGroup.getVibrateMode()) {
+ case OVERRIDE :
+ return true;
+ case SUPPRESS :
+ return false;
+ case DEFAULT :
+ // Drop through
+ }
+ }
+ } else {
+ Log.v(TAG, "Not applying override for 'android' package");
+ }
IAudioService service = getService();
try {
return service.shouldVibrate(vibrateType);
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 81e8028..59177a7 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -308,6 +308,11 @@ public class AudioRecord
break;
case AudioFormat.ENCODING_PCM_16BIT:
case AudioFormat.ENCODING_PCM_8BIT:
+ case AudioFormat.ENCODING_AMRNB:
+ case AudioFormat.ENCODING_AMRWB:
+ case AudioFormat.ENCODING_EVRC:
+ case AudioFormat.ENCODING_EVRCB:
+ case AudioFormat.ENCODING_EVRCWB:
mAudioFormat = audioFormat;
break;
default:
@@ -327,8 +332,15 @@ public class AudioRecord
private void audioBuffSizeCheck(int audioBufferSize) {
// NB: this section is only valid with PCM data.
// To update when supporting compressed formats
- int frameSizeInBytes = mChannelCount
- * (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2);
+ int bytesPerSample;
+ if(mAudioFormat == AudioFormat.ENCODING_PCM_8BIT)
+ bytesPerSample = 1;
+ else if((mAudioFormat == AudioFormat.ENCODING_AMRWB) &&
+ (mRecordSource != MediaRecorder.AudioSource.VOICE_COMMUNICATION))
+ bytesPerSample = 61;
+ else
+ bytesPerSample = 2;
+ int frameSizeInBytes = mChannelCount * bytesPerSample;
if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
throw (new IllegalArgumentException("Invalid audio buffer size."));
}
@@ -476,7 +488,12 @@ public class AudioRecord
}
// PCM_8BIT is not supported at the moment
- if (audioFormat != AudioFormat.ENCODING_PCM_16BIT) {
+ if (audioFormat != AudioFormat.ENCODING_PCM_16BIT
+ && audioFormat != AudioFormat.ENCODING_AMRNB
+ && audioFormat != AudioFormat.ENCODING_AMRWB
+ && audioFormat != AudioFormat.ENCODING_EVRC
+ && audioFormat != AudioFormat.ENCODING_EVRCB
+ && audioFormat != AudioFormat.ENCODING_EVRCWB) {
loge("getMinBufferSize(): Invalid audio format.");
return AudioRecord.ERROR_BAD_VALUE;
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index ef97d2a..5c4b315 100644..100755
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -42,9 +42,11 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -61,6 +63,7 @@ import android.os.UserHandle;
import android.os.Vibrator;
import android.provider.Settings;
import android.provider.Settings.System;
+import android.provider.Settings.SettingNotFoundException;
import android.speech.RecognizerIntent;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -70,6 +73,7 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.VolumePanel;
+import com.android.internal.app.ThemeUtils;
import com.android.internal.telephony.ITelephony;
import java.io.FileDescriptor;
@@ -115,6 +119,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
/** The UI */
private VolumePanel mVolumePanel;
+ private Context mUiContext;
+ private Handler mHandler;
// sendMsg() flags
/** If the msg is already queued, replace it with this one. */
@@ -175,6 +181,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
/** @see VolumeStreamState */
private VolumeStreamState[] mStreamStates;
private SettingsObserver mSettingsObserver;
+ private boolean noDelayInATwoDP =
+ Resources.getSystem().getBoolean(com.android.internal.R.bool.config_noDelayInATwoDP);
private int mMode;
// protects mRingerMode
@@ -237,7 +245,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
* NOTE: do not create loops in aliases!
* Some streams alias to different streams according to device category (phone or tablet) or
* use case (in call s off call...).See updateStreamVolumeAlias() for more details
- * mStreamVolumeAlias contains the default aliases for a voice capable device (phone) and
+ * STREAM_VOLUME_ALIAS contains the default aliases for a voice capable device (phone) and
* STREAM_VOLUME_ALIAS_NON_VOICE for a non voice capable device (tablet).*/
private final int[] STREAM_VOLUME_ALIAS = new int[] {
AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
@@ -279,6 +287,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
"STREAM_TTS"
};
+ private boolean mLinkNotificationWithVolume;
+
private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
@@ -430,7 +440,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// Devices for which the volume is fixed and VolumePanel slider should be disabled
final int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_AUX_DIGITAL |
AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET |
- AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET |
AudioSystem.DEVICE_OUT_ALL_USB;
private final boolean mMonitorOrientation;
@@ -447,6 +456,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
public AudioService(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
+ mHandler = new Handler();
mVoiceCapable = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_voice_capable);
@@ -464,7 +474,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
sSoundEffectVolumeDb = context.getResources().getInteger(
com.android.internal.R.integer.config_soundEffectVolumeDb);
- mVolumePanel = new VolumePanel(context, this);
mMode = AudioSystem.MODE_NORMAL;
mForcedUseForComm = AudioSystem.FORCE_NONE;
@@ -507,6 +516,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// Register for device connection intent broadcasts.
IntentFilter intentFilter =
new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+ if (noDelayInATwoDP) {
+ intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+ }
intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
@@ -514,7 +526,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+ intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+ intentFilter.addAction(Intent.ACTION_WIFI_DISPLAY_AUDIO);
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
// Register a configuration change listener only if requested by system properties
@@ -534,6 +548,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
pkgFilter.addDataScheme("package");
context.registerReceiver(mReceiver, pkgFilter);
+ ThemeUtils.registerThemeChangeReceiver(context, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ });
+
// Register for phone state monitoring
TelephonyManager tmgr = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
@@ -628,6 +649,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
}
mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
+
+ if (mLinkNotificationWithVolume) {
+ mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
+ } else {
+ mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
+ }
+
if (updateVolumes) {
mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
false /*lastAudible*/);
@@ -663,6 +691,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
0);
}
+ private boolean safeVolumeEnabled(ContentResolver cr) {
+ boolean safeMediaVolumeEnabled = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_safe_media_volume_enabled);
+ boolean safeHeadsetVolumeEnabled = Settings.System.getIntForUser(cr,
+ Settings.System.SAFE_HEADSET_VOLUME, safeMediaVolumeEnabled ? 1 : 0,
+ UserHandle.USER_CURRENT_OR_SELF) != 0;
+ return safeHeadsetVolumeEnabled;
+ }
+
private void readPersistedSettings() {
final ContentResolver cr = mContentResolver;
@@ -728,8 +765,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
UserHandle.USER_CURRENT);
readDockAudioSettings(cr);
+
+ mSafeVolumeEnabled = new Boolean(safeVolumeEnabled(cr));
}
+ mLinkNotificationWithVolume = Settings.System.getIntForUser(cr,
+ Settings.System.VOLUME_LINK_NOTIFICATION, 1, UserHandle.USER_CURRENT) == 1;
+
mMuteAffectedStreams = System.getIntForUser(cr,
System.MUTE_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_MUSIC)|
@@ -1077,7 +1119,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
streamType = AudioSystem.STREAM_NOTIFICATION;
}
- mVolumePanel.postVolumeChanged(streamType, flags);
+ showVolumeChangeUi(streamType, flags);
if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) {
oldIndex = (oldIndex + 5) / 10;
@@ -1092,7 +1134,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// UI update and Broadcast Intent
private void sendMasterVolumeUpdate(int flags, int oldVolume, int newVolume) {
- mVolumePanel.postMasterVolumeChanged(flags);
+ masterVolumeChanged(flags);
Intent intent = new Intent(AudioManager.MASTER_VOLUME_CHANGED_ACTION);
intent.putExtra(AudioManager.EXTRA_PREV_MASTER_VOLUME_VALUE, oldVolume);
@@ -1102,7 +1144,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// UI update and Broadcast Intent
private void sendMasterMuteUpdate(boolean muted, int flags) {
- mVolumePanel.postMasterMuteChanged(flags);
+ masterMuteChanged(flags);
broadcastMasterMuteStatus(muted);
}
@@ -1825,7 +1867,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
checkAllAliasStreamVolumes();
synchronized (mSafeMediaVolumeState) {
- if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
+ if (mSafeVolumeEnabled &&
+ mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
enforceSafeMediaVolume();
}
}
@@ -1867,6 +1910,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
/** @see AudioManager#setBluetoothA2dpOn() */
public void setBluetoothA2dpOn(boolean on) {
+ if (!checkAudioSettingsPermission("setBluetoothA2dpOn()") && noDelayInATwoDP) {
+ return;
+ }
synchronized (mBluetoothA2dpEnabledLock) {
mBluetoothA2dpEnabled = on;
sendMsg(mAudioHandler, MSG_SET_FORCE_BT_A2DP_USE, SENDMSG_QUEUE,
@@ -2173,17 +2219,21 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
deviceList = a2dp.getConnectedDevices();
if (deviceList.size() > 0) {
btDevice = deviceList.get(0);
- synchronized (mConnectedDevices) {
- int state = a2dp.getConnectionState(btDevice);
- int delay = checkSendBecomingNoisyIntent(
+ if (!noDelayInATwoDP) {
+ synchronized (mConnectedDevices) {
+ int state = a2dp.getConnectionState(btDevice);
+ int delay = checkSendBecomingNoisyIntent(
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
(state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
- queueMsgUnderWakeLock(mAudioHandler,
- MSG_SET_A2DP_CONNECTION_STATE,
- state,
- 0,
- btDevice,
- delay);
+ queueMsgUnderWakeLock(mAudioHandler,
+ MSG_SET_A2DP_CONNECTION_STATE,
+ state,
+ 0,
+ btDevice,
+ delay);
+ }
+ } else {
+ onSetA2dpConnectionState(btDevice, a2dp.getConnectionState(btDevice));
}
}
break;
@@ -2279,7 +2329,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private void onCheckMusicActive() {
synchronized (mSafeMediaVolumeState) {
- if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
+ if (mSafeVolumeEnabled &&
+ mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);
if ((device & mSafeMediaVolumeDevices) != 0) {
@@ -2299,7 +2350,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {
setSafeMediaVolumeEnabled(true);
mMusicActiveMs = 0;
- mVolumePanel.postDisplaySafeVolumeWarning();
+ displaySafeVolumeWarning();
}
}
}
@@ -2368,11 +2419,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
if (step <= oldIndex && oldIndex < 2 * step) {
ringerMode = RINGER_MODE_VIBRATE;
+ if (mVoiceCapable)
+ adjustVolumeIndex = false;
}
} else {
// (oldIndex < step) is equivalent to (old UI index == 0)
if ((oldIndex < step) && mPrevVolDirection != AudioManager.ADJUST_LOWER) {
ringerMode = RINGER_MODE_SILENT;
+ if (mVoiceCapable)
+ adjustVolumeIndex = false;
}
}
}
@@ -2613,18 +2668,21 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
}
- public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state)
- {
+ public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state) {
int delay;
- synchronized (mConnectedDevices) {
- delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
- queueMsgUnderWakeLock(mAudioHandler,
- MSG_SET_A2DP_CONNECTION_STATE,
- state,
- 0,
- device,
- delay);
+ if (!noDelayInATwoDP) {
+ synchronized (mConnectedDevices) {
+ delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ queueMsgUnderWakeLock(mAudioHandler,
+ MSG_SET_A2DP_CONNECTION_STATE,
+ state,
+ 0,
+ device,
+ delay);
+ }
+ } else {
+ delay = 0;
}
return delay;
}
@@ -3481,42 +3539,62 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
mContentResolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.VOLUME_LINK_NOTIFICATION), false, this);
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.SAFE_HEADSET_VOLUME), false, this);
}
@Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
// FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
// However there appear to be some missing locks around mRingerModeMutedStreams
// and mRingerModeAffectedStreams, so will leave this synchronized for now.
// mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
synchronized (mSettingsLock) {
- int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
- Settings.System.MODE_RINGER_STREAMS_AFFECTED,
- ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
- (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
- UserHandle.USER_CURRENT);
- if (mVoiceCapable) {
- ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
- } else {
- ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_MUSIC);
- }
- synchronized (mCameraSoundForced) {
- if (mCameraSoundForced) {
- ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+ if (uri.equals(Settings.System.getUriFor(Settings.System.MODE_RINGER_STREAMS_AFFECTED))) {
+ int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
+ (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
+ UserHandle.USER_CURRENT);
+ if (mVoiceCapable) {
+ ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
} else {
- ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+ ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_MUSIC);
}
+ synchronized (mCameraSoundForced) {
+ if (mCameraSoundForced) {
+ ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+ } else {
+ ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+ }
+ }
+ if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
+ /*
+ * Ensure all stream types that should be affected by ringer mode
+ * are in the proper state.
+ */
+ mRingerModeAffectedStreams = ringerModeAffectedStreams;
+ setRingerModeInt(getRingerMode(), false);
+ }
+
+ } else if (uri.equals(Settings.Global.getUriFor(Settings.Global.DOCK_AUDIO_MEDIA_ENABLED))) {
+ readDockAudioSettings(mContentResolver);
+
+ } else if (uri.equals(Settings.System.getUriFor(Settings.System.VOLUME_LINK_NOTIFICATION))) {
+ mLinkNotificationWithVolume = Settings.System.getInt(mContentResolver,
+ Settings.System.VOLUME_LINK_NOTIFICATION, 1) == 1;
+ if (mLinkNotificationWithVolume) {
+ mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
+ } else {
+ mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
+ }
+
+ } else if (uri.equals(Settings.System.getUriFor(Settings.System.SAFE_HEADSET_VOLUME))) {
+ mSafeVolumeEnabled = safeVolumeEnabled(mContentResolver);
}
- if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
- /*
- * Ensure all stream types that should be affected by ringer mode
- * are in the proper state.
- */
- mRingerModeAffectedStreams = ringerModeAffectedStreams;
- setRingerModeInt(getRingerMode(), false);
- }
- readDockAudioSettings(mContentResolver);
}
}
}
@@ -3541,6 +3619,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// must be called synchronized on mConnectedDevices
private void makeA2dpDeviceUnavailableNow(String address) {
+ if (noDelayInATwoDP) {
+ onSendBecomingNoisyIntent();
+ }
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
address);
@@ -3805,6 +3886,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
default:
config = AudioSystem.FORCE_NONE;
}
+
// Low end docks have a menu to enable or disable audio
// (see mDockAudioMediaEnabled)
if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
@@ -3813,6 +3895,12 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
}
mDockState = dockState;
+ } else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED) && noDelayInATwoDP) {
+ state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
+ BluetoothProfile.STATE_DISCONNECTED);
+ BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+ onSetA2dpConnectionState(btDevice, state);
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothProfile.STATE_DISCONNECTED);
@@ -3957,7 +4045,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
AudioSystem.setParameters("screen_state=off");
} else if (action.equalsIgnoreCase(Intent.ACTION_CONFIGURATION_CHANGED)) {
handleConfigurationChanged(context);
- } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
+ } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
// attempt to stop music playback for background user
sendMsg(mAudioHandler,
MSG_BROADCAST_AUDIO_BECOMING_NOISY,
@@ -3966,6 +4054,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
0,
null,
0);
+ } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
// the current audio focus owner is no longer valid
discardAudioFocusOwner();
@@ -3978,10 +4067,158 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
0,
0,
mStreamStates[AudioSystem.STREAM_MUSIC], 0);
+ } else if (action.equals(Intent.ACTION_WIFI_DISPLAY_AUDIO)) {
+ state = intent.getIntExtra("state", 0);
+ Log.v(TAG, "WiFi Display device state "+state);
+ boolean isConnected = mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_PROXY);
+ if(state == 1 && !isConnected){
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_PROXY,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ "");
+ mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_PROXY), "");
+ }else if(state == 0 && isConnected){
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_PROXY,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ "");
+ mConnectedDevices.remove(AudioSystem.DEVICE_OUT_PROXY);
+ }
}
}
}
+ private void masterVolumeChanged(final int flags) {
+ if (mUiContext != null && mVolumePanel != null) {
+ mVolumePanel.postMasterVolumeChanged(flags);
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+
+ final Context context = mUiContext != null ? mUiContext : mContext;
+ mVolumePanel = new VolumePanel(context, AudioService.this);
+ mVolumePanel.postMasterVolumeChanged(flags);
+ }
+ });
+ }
+ }
+
+ private void masterMuteChanged(final int flags) {
+ if (mUiContext != null && mVolumePanel != null) {
+ mVolumePanel.postMasterMuteChanged(flags);
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+
+ final Context context = mUiContext != null ? mUiContext : mContext;
+ mVolumePanel = new VolumePanel(context, AudioService.this);
+ mVolumePanel.postMasterMuteChanged(flags);
+ }
+ });
+ }
+ }
+
+ private void remoteSliderVisibility(final boolean hasRemotePlayback) {
+ if (mUiContext != null && mVolumePanel != null) {
+ mVolumePanel.postRemoteSliderVisibility(hasRemotePlayback);
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+
+ final Context context = mUiContext != null ? mUiContext : mContext;
+ mVolumePanel = new VolumePanel(context, AudioService.this);
+ mVolumePanel.postRemoteSliderVisibility(hasRemotePlayback);
+ }
+ });
+ }
+ }
+
+ private void showVolumeChangeUi(final int streamType, final int flags) {
+ if (mUiContext != null && mVolumePanel != null) {
+ mVolumePanel.postVolumeChanged(streamType, flags);
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+
+ final Context context = mUiContext != null ? mUiContext : mContext;
+ mVolumePanel = new VolumePanel(context, AudioService.this);
+ mVolumePanel.postVolumeChanged(streamType, flags);
+ }
+ });
+ }
+ }
+
+ private void remoteVolumeChanged(final int streamType, final int flags) {
+ if (mUiContext != null && mVolumePanel != null) {
+ mVolumePanel.postRemoteVolumeChanged(streamType, flags);
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+
+ final Context context = mUiContext != null ? mUiContext : mContext;
+ mVolumePanel = new VolumePanel(context, AudioService.this);
+ mVolumePanel.postRemoteVolumeChanged(streamType, flags);
+ }
+ });
+ }
+ }
+
+ private void displaySafeVolumeWarning() {
+ if (mUiContext != null && mVolumePanel != null) {
+ mVolumePanel.postDisplaySafeVolumeWarning();
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+
+ final Context context = mUiContext != null ? mUiContext : mContext;
+ mVolumePanel = new VolumePanel(context, AudioService.this);
+ mVolumePanel.postDisplaySafeVolumeWarning();
+ }
+ });
+ }
+ }
+
+ private void hasNewRemotePlaybackInfo() {
+ if (mUiContext != null && mVolumePanel != null) {
+ mVolumePanel.postHasNewRemotePlaybackInfo();
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+
+ final Context context = mUiContext != null ? mUiContext : mContext;
+ mVolumePanel = new VolumePanel(context, AudioService.this);
+ mVolumePanel.postHasNewRemotePlaybackInfo();
+ }
+ });
+ }
+ }
+
//==========================================================================================
// AudioFocus
//==========================================================================================
@@ -4042,10 +4279,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private void notifyTopOfAudioFocusStack() {
// notify the top of the stack it gained focus
if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
- if (canReassignAudioFocus()) {
+ String clientId = mFocusStack.peek().mClientId;
+ if (canReassignAudioFocusTo(clientId)) {
try {
mFocusStack.peek().mFocusDispatcher.dispatchAudioFocusChange(
- AudioManager.AUDIOFOCUS_GAIN, mFocusStack.peek().mClientId);
+ AudioManager.AUDIOFOCUS_GAIN, clientId);
} catch (RemoteException e) {
Log.e(TAG, "Failure to signal gain of audio control focus due to "+ e);
e.printStackTrace();
@@ -4193,9 +4431,12 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
* Helper function:
* Returns true if the system is in a state where the focus can be reevaluated, false otherwise.
*/
- private boolean canReassignAudioFocus() {
+ private boolean canReassignAudioFocusTo(String clientId) {
// focus requests are rejected during a phone call or when the phone is ringing
// this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
+ if (IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
+ return true;
+ }
if (!mFocusStack.isEmpty() && IN_VOICE_COMM_FOCUS_ID.equals(mFocusStack.peek().mClientId)) {
return false;
}
@@ -4240,7 +4481,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
synchronized(mAudioFocusLock) {
- if (!canReassignAudioFocus()) {
+ if (!canReassignAudioFocusTo(clientId)) {
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
@@ -5497,7 +5738,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolume = value;
- mVolumePanel.postHasNewRemotePlaybackInfo();
+ hasNewRemotePlaybackInfo();
}
}
break;
@@ -5506,7 +5747,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolumeMax = value;
- mVolumePanel.postHasNewRemotePlaybackInfo();
+ hasNewRemotePlaybackInfo();
}
}
break;
@@ -5515,7 +5756,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolumeHandling = value;
- mVolumePanel.postHasNewRemotePlaybackInfo();
+ hasNewRemotePlaybackInfo();
}
}
break;
@@ -5633,7 +5874,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
// fire up the UI
- mVolumePanel.postRemoteVolumeChanged(streamType, flags);
+ remoteVolumeChanged(streamType, flags);
}
private void sendVolumeUpdateToRemote(int rccId, int direction) {
@@ -5737,7 +5978,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
synchronized (mMainRemote) {
if (mHasRemotePlayback != hasRemotePlayback) {
mHasRemotePlayback = hasRemotePlayback;
- mVolumePanel.postRemoteSliderVisibility(hasRemotePlayback);
+ remoteSliderVisibility(hasRemotePlayback);
}
}
}
@@ -5894,6 +6135,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private Integer mSafeMediaVolumeState;
private int mMcc = 0;
+ // mSafeVolumeEnabled indicates whether to check the volume of media play via headset
+ private boolean mSafeVolumeEnabled;
// mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
private int mSafeMediaVolumeIndex;
// mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
@@ -5909,7 +6152,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private void setSafeMediaVolumeEnabled(boolean on) {
synchronized (mSafeMediaVolumeState) {
- if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
+ if (mSafeVolumeEnabled &&
+ (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
(mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {
if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
@@ -5968,11 +6212,12 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private boolean checkSafeMediaVolume(int streamType, int index, int device) {
synchronized (mSafeMediaVolumeState) {
- if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
+ if (mSafeVolumeEnabled &&
+ (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
(mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
((device & mSafeMediaVolumeDevices) != 0) &&
(index > mSafeMediaVolumeIndex)) {
- mVolumePanel.postDisplaySafeVolumeWarning();
+ displaySafeVolumeWarning();
return false;
}
return true;
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index dde2979..01e79e7 100644..100755
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -219,7 +219,9 @@ public class AudioSystem
public static final int DEVICE_OUT_USB_ACCESSORY = 0x2000;
public static final int DEVICE_OUT_USB_DEVICE = 0x4000;
public static final int DEVICE_OUT_REMOTE_SUBMIX = 0x8000;
-
+ public static final int DEVICE_OUT_ANC_HEADSET = 0x10000;
+ public static final int DEVICE_OUT_ANC_HEADPHONE = 0x20000;
+ public static final int DEVICE_OUT_PROXY = 0x40000;
public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT;
public static final int DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE |
@@ -238,6 +240,9 @@ public class AudioSystem
DEVICE_OUT_USB_ACCESSORY |
DEVICE_OUT_USB_DEVICE |
DEVICE_OUT_REMOTE_SUBMIX |
+ DEVICE_OUT_ANC_HEADSET |
+ DEVICE_OUT_ANC_HEADPHONE |
+ DEVICE_OUT_PROXY |
DEVICE_OUT_DEFAULT);
public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP |
DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
@@ -262,6 +267,8 @@ public class AudioSystem
public static final int DEVICE_IN_DGTL_DOCK_HEADSET = DEVICE_BIT_IN | 0x400;
public static final int DEVICE_IN_USB_ACCESSORY = DEVICE_BIT_IN | 0x800;
public static final int DEVICE_IN_USB_DEVICE = DEVICE_BIT_IN | 0x1000;
+ public static final int DEVICE_IN_ANC_HEADSET = DEVICE_BIT_IN | 0x2000;
+ public static final int DEVICE_IN_PROXY = DEVICE_BIT_IN | 0x4000;
public static final int DEVICE_IN_DEFAULT = DEVICE_BIT_IN | DEVICE_BIT_DEFAULT;
public static final int DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION |
@@ -277,6 +284,8 @@ public class AudioSystem
DEVICE_IN_DGTL_DOCK_HEADSET |
DEVICE_IN_USB_ACCESSORY |
DEVICE_IN_USB_DEVICE |
+ DEVICE_IN_ANC_HEADSET |
+ DEVICE_IN_PROXY |
DEVICE_IN_DEFAULT);
public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
@@ -301,6 +310,9 @@ public class AudioSystem
public static final String DEVICE_OUT_USB_ACCESSORY_NAME = "usb_accessory";
public static final String DEVICE_OUT_USB_DEVICE_NAME = "usb_device";
public static final String DEVICE_OUT_REMOTE_SUBMIX_NAME = "remote_submix";
+ public static final String DEVICE_OUT_ANC_HEADSET_NAME = "anc_headset";
+ public static final String DEVICE_OUT_ANC_HEADPHONE_NAME = "anc_headphone";
+ public static final String DEVICE_OUT_PROXY_NAME = "proxy";
public static String getDeviceName(int device)
{
@@ -337,6 +349,12 @@ public class AudioSystem
return DEVICE_OUT_USB_DEVICE_NAME;
case DEVICE_OUT_REMOTE_SUBMIX:
return DEVICE_OUT_REMOTE_SUBMIX_NAME;
+ case DEVICE_OUT_ANC_HEADSET:
+ return DEVICE_OUT_ANC_HEADSET_NAME;
+ case DEVICE_OUT_ANC_HEADPHONE:
+ return DEVICE_OUT_ANC_HEADPHONE_NAME;
+ case DEVICE_OUT_PROXY:
+ return DEVICE_OUT_PROXY_NAME;
case DEVICE_OUT_DEFAULT:
default:
return "";
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 96f01db..61e7932 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -421,6 +421,11 @@ public class AudioTrack
break;
case AudioFormat.ENCODING_PCM_16BIT:
case AudioFormat.ENCODING_PCM_8BIT:
+ case AudioFormat.ENCODING_AMRNB:
+ case AudioFormat.ENCODING_AMRWB:
+ case AudioFormat.ENCODING_EVRC:
+ case AudioFormat.ENCODING_EVRCB:
+ case AudioFormat.ENCODING_EVRCWB:
mAudioFormat = audioFormat;
break;
default:
@@ -679,7 +684,12 @@ public class AudioTrack
}
if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)
- && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) {
+ && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)
+ && (audioFormat != AudioFormat.ENCODING_AMRNB)
+ && (audioFormat != AudioFormat.ENCODING_AMRWB)
+ && (audioFormat != AudioFormat.ENCODING_EVRC)
+ && (audioFormat != AudioFormat.ENCODING_EVRCB)
+ && (audioFormat != AudioFormat.ENCODING_EVRCWB)) {
loge("getMinBufferSize(): Invalid audio format.");
return AudioTrack.ERROR_BAD_VALUE;
}
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 06d43a2..95c9ad4 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,16 +48,27 @@ public class MediaFile {
public static final int FILE_TYPE_AAC = 8;
public static final int FILE_TYPE_MKA = 9;
public static final int FILE_TYPE_FLAC = 10;
+ public static final int FILE_TYPE_3GPA = 11;
+ public static final int FILE_TYPE_AC3 = 12;
+ public static final int FILE_TYPE_QCP = 13;
+ public static final int FILE_TYPE_WEBMA = 14;
+ public static final int FILE_TYPE_PCM = 15;
+ public static final int FILE_TYPE_EC3 = 16;
private static final int FIRST_AUDIO_FILE_TYPE = FILE_TYPE_MP3;
- private static final int LAST_AUDIO_FILE_TYPE = FILE_TYPE_FLAC;
+ private static final int LAST_AUDIO_FILE_TYPE = FILE_TYPE_EC3;
+
+ // More audio file types
+ public static final int FILE_TYPE_DTS = 300;
+ private static final int FIRST_AUDIO_FILE_TYPE2 = FILE_TYPE_DTS;
+ private static final int LAST_AUDIO_FILE_TYPE2 = FILE_TYPE_DTS;
// MIDI file types
- public static final int FILE_TYPE_MID = 11;
- public static final int FILE_TYPE_SMF = 12;
- public static final int FILE_TYPE_IMY = 13;
+ public static final int FILE_TYPE_MID = 17;
+ public static final int FILE_TYPE_SMF = 18;
+ public static final int FILE_TYPE_IMY = 19;
private static final int FIRST_MIDI_FILE_TYPE = FILE_TYPE_MID;
private static final int LAST_MIDI_FILE_TYPE = FILE_TYPE_IMY;
-
+
// Video file types
public static final int FILE_TYPE_MP4 = 21;
public static final int FILE_TYPE_M4V = 22;
@@ -68,24 +80,25 @@ public class MediaFile {
public static final int FILE_TYPE_MP2TS = 28;
public static final int FILE_TYPE_AVI = 29;
public static final int FILE_TYPE_WEBM = 30;
+ public static final int FILE_TYPE_DIVX = 31;
private static final int FIRST_VIDEO_FILE_TYPE = FILE_TYPE_MP4;
- private static final int LAST_VIDEO_FILE_TYPE = FILE_TYPE_WEBM;
-
+ private static final int LAST_VIDEO_FILE_TYPE = FILE_TYPE_DIVX;
+
// More video file types
public static final int FILE_TYPE_MP2PS = 200;
private static final int FIRST_VIDEO_FILE_TYPE2 = FILE_TYPE_MP2PS;
private static final int LAST_VIDEO_FILE_TYPE2 = FILE_TYPE_MP2PS;
// Image file types
- public static final int FILE_TYPE_JPEG = 31;
- public static final int FILE_TYPE_GIF = 32;
- public static final int FILE_TYPE_PNG = 33;
- public static final int FILE_TYPE_BMP = 34;
- public static final int FILE_TYPE_WBMP = 35;
- public static final int FILE_TYPE_WEBP = 36;
+ public static final int FILE_TYPE_JPEG = 32;
+ public static final int FILE_TYPE_GIF = 33;
+ public static final int FILE_TYPE_PNG = 34;
+ public static final int FILE_TYPE_BMP = 35;
+ public static final int FILE_TYPE_WBMP = 36;
+ public static final int FILE_TYPE_WEBP = 37;
private static final int FIRST_IMAGE_FILE_TYPE = FILE_TYPE_JPEG;
private static final int LAST_IMAGE_FILE_TYPE = FILE_TYPE_WEBP;
-
+
// Playlist file types
public static final int FILE_TYPE_M3U = 41;
public static final int FILE_TYPE_PLS = 42;
@@ -109,17 +122,17 @@ public class MediaFile {
public static final int FILE_TYPE_MS_EXCEL = 105;
public static final int FILE_TYPE_MS_POWERPOINT = 106;
public static final int FILE_TYPE_ZIP = 107;
-
+
public static class MediaFileType {
public final int fileType;
public final String mimeType;
-
+
MediaFileType(int fileType, String mimeType) {
this.fileType = fileType;
this.mimeType = mimeType;
}
}
-
+
private static final HashMap<String, MediaFileType> sFileTypeMap
= new HashMap<String, MediaFileType>();
private static final HashMap<String, Integer> sMimeTypeMap
@@ -175,18 +188,22 @@ public class MediaFile {
addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG);
addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV);
+ addFileType("WAV", FILE_TYPE_PCM, "audio/wav");
addFileType("AMR", FILE_TYPE_AMR, "audio/amr");
addFileType("AWB", FILE_TYPE_AWB, "audio/amr-wb");
+ addFileType("DIVX", FILE_TYPE_DIVX, "video/divx");
if (isWMAEnabled()) {
addFileType("WMA", FILE_TYPE_WMA, "audio/x-ms-wma", MtpConstants.FORMAT_WMA);
}
+ addFileType("QCP", FILE_TYPE_QCP, "audio/qcelp");
addFileType("OGG", FILE_TYPE_OGG, "audio/ogg", MtpConstants.FORMAT_OGG);
addFileType("OGG", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG);
+ addFileType("OGA", FILE_TYPE_OGG, "audio/ogg", MtpConstants.FORMAT_OGG);
addFileType("OGA", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG);
addFileType("AAC", FILE_TYPE_AAC, "audio/aac", MtpConstants.FORMAT_AAC);
addFileType("AAC", FILE_TYPE_AAC, "audio/aac-adts", MtpConstants.FORMAT_AAC);
addFileType("MKA", FILE_TYPE_MKA, "audio/x-matroska");
-
+
addFileType("MID", FILE_TYPE_MID, "audio/midi");
addFileType("MIDI", FILE_TYPE_MID, "audio/midi");
addFileType("XMF", FILE_TYPE_MID, "audio/midi");
@@ -196,7 +213,7 @@ public class MediaFile {
addFileType("RTX", FILE_TYPE_MID, "audio/midi");
addFileType("OTA", FILE_TYPE_MID, "audio/midi");
addFileType("MXMF", FILE_TYPE_MID, "audio/midi");
-
+
addFileType("MPEG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG);
addFileType("MPG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG);
addFileType("MP4", FILE_TYPE_MP4, "video/mp4", MtpConstants.FORMAT_MPEG);
@@ -208,6 +225,8 @@ public class MediaFile {
addFileType("MKV", FILE_TYPE_MKV, "video/x-matroska");
addFileType("WEBM", FILE_TYPE_WEBM, "video/webm");
addFileType("TS", FILE_TYPE_MP2TS, "video/mp2ts");
+ addFileType("MPG", FILE_TYPE_MP2TS, "video/mp2ts");
+
addFileType("AVI", FILE_TYPE_AVI, "video/avi");
if (isWMVEnabled()) {
@@ -222,7 +241,7 @@ public class MediaFile {
addFileType("BMP", FILE_TYPE_BMP, "image/x-ms-bmp", MtpConstants.FORMAT_BMP);
addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp");
addFileType("WEBP", FILE_TYPE_WEBP, "image/webp");
-
+
addFileType("M3U", FILE_TYPE_M3U, "audio/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
addFileType("M3U", FILE_TYPE_M3U, "application/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
addFileType("PLS", FILE_TYPE_PLS, "audio/x-scpls", MtpConstants.FORMAT_PLS_PLAYLIST);
@@ -250,7 +269,9 @@ public class MediaFile {
return ((fileType >= FIRST_AUDIO_FILE_TYPE &&
fileType <= LAST_AUDIO_FILE_TYPE) ||
(fileType >= FIRST_MIDI_FILE_TYPE &&
- fileType <= LAST_MIDI_FILE_TYPE));
+ fileType <= LAST_MIDI_FILE_TYPE) ||
+ (fileType >= FIRST_AUDIO_FILE_TYPE2 &&
+ fileType <= LAST_AUDIO_FILE_TYPE2));
}
public static boolean isVideoFileType(int fileType) {
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 48bea52..544410f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -241,6 +241,13 @@ public class MediaRecorder
/** @hide H.264/AAC data encapsulated in MPEG2/TS */
public static final int OUTPUT_FORMAT_MPEG2TS = 8;
+
+ /** @hide QCP file format */
+ public static final int QCP = 9;
+ /** @hide 3GPP2 media file format*/
+ public static final int THREE_GPP2 = 10;
+ /** @hide WAVE media file format*/
+ public static final int WAVE = 11;
};
/**
@@ -263,6 +270,12 @@ public class MediaRecorder
public static final int HE_AAC = 4;
/** Enhanced Low Delay AAC (AAC-ELD) audio codec */
public static final int AAC_ELD = 5;
+ /** @hide EVRC audio codec */
+ public static final int EVRC = 6;
+ /** @hide QCELP audio codec */
+ public static final int QCELP =7;
+ /** @hide Linear PCM audio codec */
+ public static final int LPCM =8;
}
/**
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index f190eb9..4cad61c 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -109,6 +110,19 @@ public class Ringtone {
return mTitle = getTitle(context, mUri, true);
}
+ private static String stringForQuery(Cursor cursor) {
+ if (cursor != null) {
+ try {
+ if (cursor.moveToFirst()) {
+ return cursor.getString(0);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ return null;
+ }
+
private static String getTitle(Context context, Uri uri, boolean followSettingsUri) {
Cursor cursor = null;
ContentResolver res = context.getContentResolver();
@@ -127,6 +141,14 @@ public class Ringtone {
.getString(com.android.internal.R.string.ringtone_default_with_actual,
actualTitle);
}
+ } else if (RingtoneManager.THEME_AUTHORITY.equals(authority)) {
+ Uri themes = Uri.parse("content://com.tmobile.thememanager.themes/themes");
+ title = stringForQuery(res.query(themes, new String[] { "ringtone_name" },
+ "ringtone_uri = ?", new String[] { uri.toString() }, null));
+ if (title == null) {
+ title = stringForQuery(res.query(themes, new String[] { "notif_ringtone_name" },
+ "notif_ringtone_uri = ?", new String[] { uri.toString() }, null));
+ }
} else {
try {
if (DrmStore.AUTHORITY.equals(authority)) {
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 5e18bfa..a0ea993 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +23,9 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Activity;
import android.content.ContentUris;
+import android.app.ProfileGroup;
+import android.app.ProfileManager;
import android.content.Context;
-import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
@@ -55,29 +57,29 @@ public class RingtoneManager {
// Make sure these are in sync with attrs.xml:
// <attr name="ringtoneType">
-
+
/**
* Type that refers to sounds that are used for the phone ringer.
*/
public static final int TYPE_RINGTONE = 1;
-
+
/**
* Type that refers to sounds that are used for notifications.
*/
public static final int TYPE_NOTIFICATION = 2;
-
+
/**
* Type that refers to sounds that are used for the alarm.
*/
public static final int TYPE_ALARM = 4;
-
+
/**
* All types of sounds.
*/
public static final int TYPE_ALL = TYPE_RINGTONE | TYPE_NOTIFICATION | TYPE_ALARM;
// </attr>
-
+
/**
* Activity Action: Shows a ringtone picker.
* <p>
@@ -131,7 +133,7 @@ public class RingtoneManager {
*/
public static final String EXTRA_RINGTONE_EXISTING_URI =
"android.intent.extra.ringtone.EXISTING_URI";
-
+
/**
* Given to the ringtone picker as a {@link Uri}. The {@link Uri} of the
* ringtone to play when the user attempts to preview the "Default"
@@ -144,7 +146,7 @@ public class RingtoneManager {
*/
public static final String EXTRA_RINGTONE_DEFAULT_URI =
"android.intent.extra.ringtone.DEFAULT_URI";
-
+
/**
* Given to the ringtone picker as an int. Specifies which ringtone type(s) should be
* shown in the picker. One or more of {@link #TYPE_RINGTONE},
@@ -175,26 +177,31 @@ public class RingtoneManager {
public static final String EXTRA_RINGTONE_PICKED_URI =
"android.intent.extra.ringtone.PICKED_URI";
+ /**
+ * @hide
+ */
+ public static final String THEME_AUTHORITY = "com.tmobile.thememanager.packageresources";
+
// Make sure the column ordering and then ..._COLUMN_INDEX are in sync
private static final String[] INTERNAL_COLUMNS = new String[] {
MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
- "\"" + MediaStore.Audio.Media.INTERNAL_CONTENT_URI + "\"",
+ "\"" + MediaStore.Audio.Media.INTERNAL_CONTENT_URI + "/\" || " + MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE_KEY
};
private static final String[] DRM_COLUMNS = new String[] {
DrmStore.Audio._ID, DrmStore.Audio.TITLE,
- "\"" + DrmStore.Audio.CONTENT_URI + "\"",
+ "\"" + DrmStore.Audio.CONTENT_URI + "/\" || " + DrmStore.Audio._ID,
DrmStore.Audio.TITLE + " AS " + MediaStore.Audio.Media.TITLE_KEY
};
private static final String[] MEDIA_COLUMNS = new String[] {
MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
- "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"",
+ "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "/\" || " + MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE_KEY
};
-
+
/**
* The column index (in the cursor returned by {@link #getCursor()} for the
* row ID.
@@ -215,11 +222,11 @@ public class RingtoneManager {
private Activity mActivity;
private Context mContext;
-
+
private Cursor mCursor;
private int mType = TYPE_RINGTONE;
-
+
/**
* If a column (item from this list) exists in the Cursor, its value must
* be true (value of 1) for the row to be returned.
@@ -230,7 +237,7 @@ public class RingtoneManager {
private Ringtone mPreviousRingtone;
private boolean mIncludeDrm;
-
+
/**
* Constructs a RingtoneManager. This constructor is recommended as its
* constructed instance manages cursor(s).
@@ -322,7 +329,7 @@ public class RingtoneManager {
mPreviousRingtone.stop();
}
}
-
+
/**
* Returns whether DRM ringtones will be included.
*
@@ -365,8 +372,12 @@ public class RingtoneManager {
final Cursor internalCursor = getInternalRingtones();
final Cursor drmCursor = mIncludeDrm ? getDrmRingtones() : null;
final Cursor mediaCursor = getMediaRingtones();
-
- return mCursor = new SortCursor(new Cursor[] { internalCursor, drmCursor, mediaCursor },
+
+ final Cursor themeRegularCursor = getThemeRegularRingtones();
+ final Cursor themeNotifCursor = getThemeNotificationRingtones();
+
+ return mCursor = new SortCursor(new Cursor[] { internalCursor, drmCursor, mediaCursor,
+ themeRegularCursor, themeNotifCursor },
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
}
@@ -401,12 +412,11 @@ public class RingtoneManager {
return getUriFromCursor(mCursor);
}
-
+
private static Uri getUriFromCursor(Cursor cursor) {
- return ContentUris.withAppendedId(Uri.parse(cursor.getString(URI_COLUMN_INDEX)), cursor
- .getLong(ID_COLUMN_INDEX));
+ return Uri.parse(cursor.getString(URI_COLUMN_INDEX));
}
-
+
/**
* Gets the position of a {@link Uri} within this {@link RingtoneManager}.
*
@@ -424,23 +434,12 @@ public class RingtoneManager {
return -1;
}
- // Only create Uri objects when the actual URI changes
- Uri currentUri = null;
- String previousUriString = null;
for (int i = 0; i < cursorCount; i++) {
- String uriString = cursor.getString(URI_COLUMN_INDEX);
- if (currentUri == null || !uriString.equals(previousUriString)) {
- currentUri = Uri.parse(uriString);
- }
-
- if (ringtoneUri.equals(ContentUris.withAppendedId(currentUri, cursor
- .getLong(ID_COLUMN_INDEX)))) {
+ if (ringtoneUri.equals(getUriFromCursor(cursor))) {
return i;
}
cursor.move(1);
-
- previousUriString = uriString;
}
return -1;
@@ -466,6 +465,14 @@ public class RingtoneManager {
uri = getValidRingtoneUriFromCursorAndClose(context, rm.getDrmRingtones());
}
+ if (uri == null) {
+ uri = getValidRingtoneUriFromCursorAndClose(context, rm.getThemeRegularRingtones());
+ }
+
+ if (uri == null) {
+ uri = getValidRingtoneUriFromCursorAndClose(context, rm.getThemeNotificationRingtones());
+ }
+
return uri;
}
@@ -510,7 +517,39 @@ public class RingtoneManager {
MediaStore.Audio.Media.DEFAULT_SORT_ORDER)
: null;
}
-
+
+ private String getThemeWhereClause(String uriColumn) {
+ /* Filter out themes with no ringtone and the default theme (which has no package). */
+ String clause = uriColumn + " IS NOT NULL AND LENGTH(theme_package) > 0";
+ if (mIncludeDrm) {
+ return clause;
+ } else {
+ return clause + " AND " + uriColumn + " NOT LIKE '%/assets/%locked%'";
+ }
+ }
+
+ private Cursor getThemeRegularRingtones() {
+ if ((mType & TYPE_RINGTONE) != 0) {
+ return query(Uri.parse("content://com.tmobile.thememanager.themes/themes"),
+ new String[] { "_id", "ringtone_name AS " + MEDIA_COLUMNS[1], "ringtone_uri",
+ "ringtone_name_key AS " + MEDIA_COLUMNS[3] },
+ getThemeWhereClause("ringtone_uri"), null, MEDIA_COLUMNS[3]);
+ } else {
+ return null;
+ }
+ }
+
+ private Cursor getThemeNotificationRingtones() {
+ if ((mType & TYPE_NOTIFICATION) != 0) {
+ return query(Uri.parse("content://com.tmobile.thememanager.themes/themes"),
+ new String[] { "_id", "notif_ringtone_name AS " + MEDIA_COLUMNS[1], "notif_ringtone_uri",
+ "notif_ringtone_name_key AS " + MEDIA_COLUMNS[3] },
+ getThemeWhereClause("notif_ringtone_uri"), null, MEDIA_COLUMNS[3]);
+ } else {
+ return null;
+ }
+ }
+
private void setFilterColumnsList(int type) {
List<String> columns = mFilterColumns;
columns.clear();
@@ -527,7 +566,7 @@ public class RingtoneManager {
columns.add(MediaStore.Audio.AudioColumns.IS_ALARM);
}
}
-
+
/**
* Constructs a where clause that consists of at least one column being 1
* (true). This is used to find all matching sounds for the given sound
@@ -539,7 +578,7 @@ public class RingtoneManager {
private static String constructBooleanTrueWhereClause(List<String> columns, boolean includeDrm) {
if (columns == null) return null;
-
+
StringBuilder sb = new StringBuilder();
sb.append("(");
@@ -565,7 +604,7 @@ public class RingtoneManager {
return sb.toString();
}
-
+
private Cursor query(Uri uri,
String[] projection,
String selection,
@@ -578,7 +617,7 @@ public class RingtoneManager {
sortOrder);
}
}
-
+
/**
* Returns a {@link Ringtone} for a given sound URI.
* <p>
@@ -606,11 +645,26 @@ public class RingtoneManager {
* @see #getRingtone(Context, Uri)
*/
private static Ringtone getRingtone(final Context context, Uri ringtoneUri, int streamType) {
+ ProfileManager pm = (ProfileManager)context.getSystemService(context.PROFILE_SERVICE);
+ ProfileGroup profileGroup = pm.getActiveProfileGroup(context.getPackageName());
+
try {
- final Ringtone r = new Ringtone(context, true);
+ Ringtone r = new Ringtone(context, true);
if (streamType >= 0) {
r.setStreamType(streamType);
}
+
+ if (profileGroup != null) {
+ switch (profileGroup.getRingerMode()) {
+ case OVERRIDE :
+ r.setUri(profileGroup.getRingerOverride());
+ return r;
+ case SUPPRESS :
+ r = null;
+ return r;
+ }
+ }
+
r.setUri(ringtoneUri);
return r;
} catch (Exception ex) {
@@ -619,7 +673,7 @@ public class RingtoneManager {
return null;
}
-
+
/**
* Gets the current default sound's {@link Uri}. This will give the actual
* sound {@link Uri}, instead of using this, most clients can use
@@ -638,7 +692,7 @@ public class RingtoneManager {
final String uriString = Settings.System.getString(context.getContentResolver(), setting);
return uriString != null ? Uri.parse(uriString) : null;
}
-
+
/**
* Sets the {@link Uri} of the default sound for a given sound type.
*
@@ -655,7 +709,7 @@ public class RingtoneManager {
Settings.System.putString(context.getContentResolver(), setting,
ringtoneUri != null ? ringtoneUri.toString() : null);
}
-
+
private static String getSettingForType(int type) {
if ((type & TYPE_RINGTONE) != 0) {
return Settings.System.RINGTONE;
@@ -667,7 +721,7 @@ public class RingtoneManager {
return null;
}
}
-
+
/**
* Returns whether the given {@link Uri} is one of the default ringtones.
*
@@ -677,7 +731,7 @@ public class RingtoneManager {
public static boolean isDefault(Uri ringtoneUri) {
return getDefaultType(ringtoneUri) != -1;
}
-
+
/**
* Returns the type of a default {@link Uri}.
*
@@ -700,7 +754,7 @@ public class RingtoneManager {
return -1;
}
}
-
+
/**
* Returns the {@link Uri} for the default ringtone of a particular type.
* Rather than returning the actual ringtone's sound {@link Uri}, this will
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 040d2ab..461ab4e 100755
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -43,8 +43,13 @@ LOCAL_C_INCLUDES += \
$(TOP)/frameworks/av/libvideoeditor/vss/mcs/inc \
$(TOP)/frameworks/av/libvideoeditor/vss/stagefrightshells/inc \
$(TOP)/frameworks/av/libvideoeditor/lvpp \
- $(TOP)/frameworks/av/libvideoeditor/osal/inc \
- $(TOP)/frameworks/native/include/media/openmax
+ $(TOP)/frameworks/av/libvideoeditor/osal/inc
+
+ifneq ($(TI_CUSTOM_DOMX_PATH),)
+LOCAL_C_INCLUDES += $(TI_CUSTOM_DOMX_PATH)/omx_core/inc
+else
+LOCAL_C_INCLUDES += $(TOP)/frameworks/native/include/media/openmax
+endif
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java
index 05b498c..2abddd9 100644
--- a/obex/javax/obex/ClientOperation.java
+++ b/obex/javax/obex/ClientOperation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, Motorola, Inc.
*
* All rights reserved.
*
@@ -121,6 +121,12 @@ public final class ClientOperation implements Operation, BaseStream {
(header).mAuthResp.length);
}
+ if ((header).mConnectionID != null) {
+ mRequestHeader.mConnectionID = new byte[4];
+ System.arraycopy((header).mConnectionID, 0, mRequestHeader.mConnectionID, 0,
+ 4);
+
+ }
}
/**
@@ -723,4 +729,8 @@ public final class ClientOperation implements Operation, BaseStream {
}
}
}
+
+ public void noEndofBody() {
+
+ }
}
diff --git a/obex/javax/obex/Operation.java b/obex/javax/obex/Operation.java
index 25656ed..c827749 100644
--- a/obex/javax/obex/Operation.java
+++ b/obex/javax/obex/Operation.java
@@ -175,6 +175,8 @@ public interface Operation {
DataOutputStream openDataOutputStream() throws IOException;
+ void noEndofBody();
+
void close() throws IOException;
int getMaxPacketSize();
diff --git a/obex/javax/obex/ServerOperation.java b/obex/javax/obex/ServerOperation.java
index d1476d2..a17226d 100644
--- a/obex/javax/obex/ServerOperation.java
+++ b/obex/javax/obex/ServerOperation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, Motorola, Inc.
*
* All rights reserved.
*
@@ -88,6 +88,8 @@ public final class ServerOperation implements Operation, BaseStream {
private boolean mHasBody;
+ private boolean mEndofBody = true;
+
/**
* Creates new ServerOperation
* @param p the parent that created this object
@@ -364,24 +366,31 @@ public final class ServerOperation implements Operation, BaseStream {
* (End of Body) otherwise, we need to send 0x48 (Body)
*/
if ((finalBitSet) || (mPrivateOutput.isClosed())) {
- out.write(0x49);
+ if (mEndofBody) {
+ out.write((byte)0x49);
+ bodyLength += 3;
+ out.write((byte)(bodyLength >> 8));
+ out.write((byte)bodyLength);
+ out.write(body);
+ }
} else {
out.write(0x48);
+ bodyLength += 3;
+ out.write((byte)(bodyLength >> 8));
+ out.write((byte)bodyLength);
+ out.write(body);
}
- bodyLength += 3;
- out.write((byte)(bodyLength >> 8));
- out.write((byte)bodyLength);
- out.write(body);
}
}
if ((finalBitSet) && (type == ResponseCodes.OBEX_HTTP_OK) && (orginalBodyLength <= 0)) {
- out.write(0x49);
- orginalBodyLength = 3;
- out.write((byte)(orginalBodyLength >> 8));
- out.write((byte)orginalBodyLength);
-
+ if (mEndofBody) {
+ out.write(0x49);
+ orginalBodyLength = 3;
+ out.write((byte)(orginalBodyLength >> 8));
+ out.write((byte)orginalBodyLength);
+ }
}
mResponseSize = 3;
@@ -711,4 +720,9 @@ public final class ServerOperation implements Operation, BaseStream {
public void streamClosed(boolean inStream) throws IOException {
}
+
+ public void noEndofBody() {
+ mEndofBody = false;
+ }
+
}
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 54dcaaa..5b5cd52 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -169,6 +169,8 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
private final static boolean LOG_RENDERER = false;
private final static boolean LOG_RENDERER_DRAW_FRAME = false;
private final static boolean LOG_EGL = false;
+
+ private final static boolean RGB565 = SystemProperties.getBoolean("ro.opengles.surface.rgb565", false);
/**
* The renderer only renders
* when the surface is created, or when {@link #requestRender} is called.
@@ -974,7 +976,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
*/
private class SimpleEGLConfigChooser extends ComponentSizeChooser {
public SimpleEGLConfigChooser(boolean withDepthBuffer) {
- super(8, 8, 8, 0, withDepthBuffer ? 16 : 0, 0);
+ super(RGB565 ? 5 : 8, RGB565 ? 6 : 8, RGB565 ? 5 : 8, 0, withDepthBuffer ? 16 : 0, 0);
}
}
diff --git a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
index 0732cd8..69d8c6f 100644
--- a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="backup_confirm_title" msgid="827563724209303345">"Úplná záloha"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Úplné obnovení"</string>
- <string name="backup_confirm_text" msgid="1878021282758896593">"Obdrželi jsme požadavek na úplnou zálohu všech dat do připojeného počítače. Chcete tuto akci povolit? "\n\n"Pokud jste o zálohu nežádali, operaci nepovolujte."</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"Obdrželi jsme požadavek na úplnou zálohu všech dat do připojeného počítače. Chcete tuto akci povolit?"\n\n"Pokud jste o zálohu nežádali, operaci nepovolujte."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Zálohovat data"</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"Nezálohovat"</string>
<string name="restore_confirm_text" msgid="7499866728030461776">"Obdrželi jsme žádost o úplné obnovení všech dat z připojeného počítače. Chcete tuto akci povolit?"\n\n"Pokud jste o obnovení nepožádali, operaci nepovolujte. Tato akce nahradí veškerá data v zařízení."</string>
@@ -30,9 +30,9 @@
<string name="backup_enc_password_text" msgid="4981585714795233099">"Zadejte prosím heslo pro šifrování dat úplné zálohy. Pokud pole ponecháte prázdné, použije se aktuální heslo pro zálohy:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Chcete-li data úplné zálohy zašifrovat, zadejte heslo:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Pokud jsou obnovená data šifrována, zadejte prosím heslo níže:"</string>
- <string name="toast_backup_started" msgid="550354281452756121">"Spouští se zálohování..."</string>
+ <string name="toast_backup_started" msgid="550354281452756121">"Spouští se zálohování\u2026"</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Zálohování bylo dokončeno"</string>
- <string name="toast_restore_started" msgid="7881679218971277385">"Spouští se obnovení..."</string>
+ <string name="toast_restore_started" msgid="7881679218971277385">"Spouští se obnovení\u2026"</string>
<string name="toast_restore_ended" msgid="1764041639199696132">"Obnovení skončilo"</string>
<string name="toast_timeout" msgid="5276598587087626877">"Časový limit operace vypršel"</string>
</resources>
diff --git a/packages/DefaultContainerService/res/values-cs/strings.xml b/packages/DefaultContainerService/res/values-cs/strings.xml
index 216d715..d695913 100644
--- a/packages/DefaultContainerService/res/values-cs/strings.xml
+++ b/packages/DefaultContainerService/res/values-cs/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/*
**
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+ <string name="service_name" msgid="4841491635055379553">"Pomocník přístupu k balíčkům"</string>
</resources>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 731a09c..ffece02 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -38,6 +38,7 @@ import android.os.Environment;
import android.os.Environment.UserEnvironment;
import android.os.FileUtils;
import android.os.IBinder;
+import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
@@ -236,6 +237,40 @@ public class DefaultContainerService extends IntentService {
}
}
+ /**
+ * List content of the directory and return as marshalled Parcel.
+ * Used for calculating misc size in Settings -> Storage
+ */
+ @Override
+ public byte[] listDirectory(String path) throws RemoteException {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+ final File directory = new File(path);
+ final File[] files = directory.listFiles();
+ final Parcel out = Parcel.obtain();
+
+ if (files == null) {
+ out.writeInt(0);
+ }
+ else {
+ out.writeInt(files.length);
+ for (final File file : files) {
+ out.writeString(file.getAbsolutePath());
+ out.writeString(file.getName());
+ out.writeInt(file.isDirectory() ? 1 : 0);
+ if (file.isFile()) {
+ out.writeInt(1);
+ out.writeLong(file.length());
+ }
+ else {
+ out.writeInt(0);
+ }
+ }
+ }
+
+ return out.marshall();
+ }
+
@Override
public long[] getFileSystemStats(String path) {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
@@ -260,6 +295,17 @@ public class DefaultContainerService extends IntentService {
}
}
+ // Same as clearDirectory, but also work for files
+ @Override
+ public void deleteFile(String path) throws RemoteException {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+ final File file = new File(path);
+ if (file.exists()) {
+ eraseFiles(file);
+ }
+ }
+
@Override
public long calculateInstalledSize(String packagePath, boolean isForwardLocked)
throws RemoteException {
diff --git a/packages/FusedLocation/res/values-cs/strings.xml b/packages/FusedLocation/res/values-cs/strings.xml
new file mode 100644
index 0000000..76b83d7
--- /dev/null
+++ b/packages/FusedLocation/res/values-cs/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+ <string name="app_label">Sloučení polohy</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-es/strings.xml b/packages/FusedLocation/res/values-es/strings.xml
new file mode 100644
index 0000000..5c6048e
--- /dev/null
+++ b/packages/FusedLocation/res/values-es/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+<resources>
+ <string name="app_label">Compartir ubicación</string>
+</resources>
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm
new file mode 100644
index 0000000..6d9c2e5
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_uk.kcm
@@ -0,0 +1,331 @@
+# 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.
+
+#
+# English (UK) keyboard layout.
+#
+
+type OVERLAY
+
+map key 43 POUND
+
+### ROW 1
+
+key GRAVE {
+ label: '`'
+ base: '`'
+ shift: '\u00AC'
+ ralt: '\u00A6'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '\u00A3'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+ ralt: '\u20AC'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '^'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ ralt: '\u00e9'
+ shift+ralt: '\u00c9'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+ ralt: '\u00fa'
+ shift+ralt: '\u00da'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+ ralt: '\u00ed'
+ shift+ralt: '\u00cd'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+ ralt: '\u00f3'
+ shift+ralt: '\u00d3'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '['
+ base: '['
+ shift: '{'
+}
+
+key RIGHT_BRACKET {
+ label: ']'
+ base: ']'
+ shift: '}'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+ ralt: '\u00e1'
+ shift+ralt: '\u00c1'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: ';'
+ base: ';'
+ shift: ':'
+}
+
+key APOSTROPHE {
+ label: '\''
+ base: '\''
+ shift: '@'
+}
+
+key POUND {
+ label: '#'
+ base: '#'
+ shift: '~'
+ ralt: '\\'
+ shift+ralt: '|'
+}
+
+### ROW 4
+
+key BACKSLASH {
+ label: '\\'
+ base: '\\'
+ shift: '|'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '<'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: '>'
+}
+
+key SLASH {
+ label: '/'
+ base: '/'
+ shift: '?'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm
new file mode 100644
index 0000000..a143d55
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us_colemak.kcm
@@ -0,0 +1,329 @@
+# 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.
+
+#
+# English (US), Colemak keyboard layout.
+# Unlike the default (generic) keyboard layout, English (US) does not contain any
+# special ALT characters.
+#
+
+type OVERLAY
+
+map key 18 F
+map key 19 P
+map key 20 G
+map key 21 J
+map key 22 L
+map key 23 U
+map key 24 Y
+map key 25 SEMICOLON
+map key 31 R
+map key 32 S
+map key 33 T
+map key 34 D
+map key 36 N
+map key 37 E
+map key 38 I
+map key 39 O
+map key 49 K
+
+### ROW 1
+
+key GRAVE {
+ label: '`'
+ base: '`'
+ shift: '~'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '^'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key SEMICOLON {
+ label: ';'
+ base: ';'
+ shift, capslock: ':'
+}
+
+key LEFT_BRACKET {
+ label: '['
+ base: '['
+ shift: '{'
+}
+
+key RIGHT_BRACKET {
+ label: ']'
+ base: ']'
+ shift: '}'
+}
+
+key BACKSLASH {
+ label: '\\'
+ base: '\\'
+ shift: '|'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift: 'O'
+}
+
+key APOSTROPHE {
+ label: '\''
+ base: '\''
+ shift: '"'
+}
+
+### ROW 4
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '<'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: '>'
+}
+
+key SLASH {
+ label: '/'
+ base: '/'
+ shift: '?'
+}
diff --git a/packages/InputDevices/res/values-cs/strings.xml b/packages/InputDevices/res/values-cs/strings.xml
new file mode 100644
index 0000000..f43a150
--- /dev/null
+++ b/packages/InputDevices/res/values-cs/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_label">Vstupní zařízení</string>
+ <string name="keyboard_layouts_label">Klávesnice Android</string>
+ <string name="keyboard_layout_english_us_label">Anglická (US)</string>
+ <string name="keyboard_layout_english_us_colemak_label">Anglická (US), Colemak</string>
+ <string name="keyboard_layout_english_us_dvorak_label">Anglická (US), Dvorak</string>
+ <string name="keyboard_layout_german_label">Německá</string>
+ <string name="keyboard_layout_french_label">Francouzská</string>
+ <string name="keyboard_layout_french_ca_label">Francouzská (Kanada)</string>
+ <string name="keyboard_layout_russian_label">Ruská</string>
+ <string name="keyboard_layout_russian_mac_label">Ruská, Mac</string>
+ <string name="keyboard_layout_spanish_label">Španělská</string>
+ <string name="keyboard_layout_swiss_french_label">Švýcarská franština</string>
+ <string name="keyboard_layout_swiss_german_label">Švýcarská němčina</string>
+ <string name="keyboard_layout_belgian">Belgická</string>
+ <string name="keyboard_layout_bulgarian">Bulharská</string>
+ <string name="keyboard_layout_italian">Italská</string>
+ <string name="keyboard_layout_danish">Dánská</string>
+ <string name="keyboard_layout_norwegian">Norská</string>
+ <string name="keyboard_layout_swedish">Švédská</string>
+ <string name="keyboard_layout_finnish">Finská</string>
+ <string name="keyboard_layout_croatian">Chorvatská</string>
+ <string name="keyboard_layout_czech">Česká</string>
+ <string name="keyboard_layout_estonian">Estonská</string>
+ <string name="keyboard_layout_hungarian">Maďarská</string>
+ <string name="keyboard_layout_icelandic">Islandská</string>
+ <string name="keyboard_layout_portuguese">Portugalská</string>
+ <string name="keyboard_layout_slovak">Slovenská</string>
+ <string name="keyboard_layout_slovenian">Slovinská</string>
+ <string name="keyboard_layout_turkish">Turecká</string>
+ <string name="keyboard_layout_ukrainian">Ukrajinská</string>
+</resources>
diff --git a/packages/InputDevices/res/values-es/strings.xml b/packages/InputDevices/res/values-es/strings.xml
new file mode 100644
index 0000000..0b092e0
--- /dev/null
+++ b/packages/InputDevices/res/values-es/strings.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+<resources>
+ <string name="app_label">Dispositivos de entrada</string>
+ <string name="keyboard_layouts_label">Teclado Android</string>
+ <string name="keyboard_layout_english_uk_label">Inglés (Reino Unido)</string>
+ <string name="keyboard_layout_english_us_label">Inglés (Estados Unidos)</string>
+ <string name="keyboard_layout_english_us_colemak_label">Inglés (Estados Unidos), Colemak</string>
+ <string name="keyboard_layout_english_us_dvorak_label">Inglés (Estados Unidos), Dvorak</string>
+ <string name="keyboard_layout_german_label">Alemán</string>
+ <string name="keyboard_layout_french_label">Francés</string>
+ <string name="keyboard_layout_french_ca_label">Francés (Canadá)</string>
+ <string name="keyboard_layout_russian_label">Ruso</string>
+ <string name="keyboard_layout_russian_mac_label">Ruso, Mac</string>
+ <string name="keyboard_layout_spanish_label">Español</string>
+ <string name="keyboard_layout_swiss_french_label">Suizo (Francés)</string>
+ <string name="keyboard_layout_swiss_german_label">Suizo (Alemán)</string>
+ <string name="keyboard_layout_belgian">Belga</string>
+ <string name="keyboard_layout_bulgarian">Búlgaro</string>
+ <string name="keyboard_layout_italian">Italiano</string>
+ <string name="keyboard_layout_danish">Danés</string>
+ <string name="keyboard_layout_norwegian">Noruego</string>
+ <string name="keyboard_layout_swedish">Sueco</string>
+ <string name="keyboard_layout_finnish">Finlandés</string>
+ <string name="keyboard_layout_croatian">Croata</string>
+ <string name="keyboard_layout_czech">Checo</string>
+ <string name="keyboard_layout_estonian">Estonio</string>
+ <string name="keyboard_layout_hungarian">Húngaro</string>
+ <string name="keyboard_layout_icelandic">Islandés</string>
+ <string name="keyboard_layout_portuguese">Portugués</string>
+ <string name="keyboard_layout_slovak">Eslovaco</string>
+ <string name="keyboard_layout_slovenian">Esloveno</string>
+ <string name="keyboard_layout_turkish">Turco</string>
+ <string name="keyboard_layout_ukrainian">Ucraniano</string>
+</resources>
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index c13e606..d198af9 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -6,9 +6,15 @@
<!-- Keyboard layouts label, used to describe the set of all built-in layouts in the UI. [CHAR LIMIT=35] -->
<string name="keyboard_layouts_label">Android keyboard</string>
+ <!-- UK English keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_english_uk_label">English (UK)</string>
+
<!-- US English keyboard layout label. [CHAR LIMIT=35] -->
<string name="keyboard_layout_english_us_label">English (US)</string>
+ <!-- US English (Colemak style) keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_english_us_colemak_label">English (US), Colemak style</string>
+
<!-- US English (Dvorak style) keyboard layout label. [CHAR LIMIT=35] -->
<string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak style</string>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index c2a2ecc..7917122 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -1,9 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
+ <keyboard-layout android:name="keyboard_layout_english_uk"
+ android:label="@string/keyboard_layout_english_uk_label"
+ android:keyboardLayout="@raw/keyboard_layout_english_uk" />
+
<keyboard-layout android:name="keyboard_layout_english_us"
android:label="@string/keyboard_layout_english_us_label"
android:keyboardLayout="@raw/keyboard_layout_english_us" />
+ <keyboard-layout android:name="keyboard_layout_english_us_colemak"
+ android:label="@string/keyboard_layout_english_us_colemak_label"
+ android:keyboardLayout="@raw/keyboard_layout_english_us_colemak" />
+
<keyboard-layout android:name="keyboard_layout_english_us_dvorak"
android:label="@string/keyboard_layout_english_us_dvorak_label"
android:keyboardLayout="@raw/keyboard_layout_english_us_dvorak" />
diff --git a/packages/SettingsProvider/res/values-cs/strings.xml b/packages/SettingsProvider/res/values-cs/strings.xml
index a28ffa1..cc635cf 100644
--- a/packages/SettingsProvider/res/values-cs/strings.xml
+++ b/packages/SettingsProvider/res/values-cs/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4567566098528588863">"Paměť pro nastavení"</string>
+ <string name="app_label" msgid="4567566098528588863">"Úložiště nastavení"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 2b02049..b8c1761 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -169,4 +169,7 @@
<!-- Default for Settings.Secure.USER_SETUP_COMPLETE -->
<bool name="def_user_setup_complete">false</bool>
+
+ <!-- Default for Settings.System.STATUS_BAR_BATTERY -->
+ <integer name="def_battery_style">0</integer>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 2454fb0..c4eab14 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1639,7 +1639,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
try {
LockPatternUtils lpu = new LockPatternUtils(mContext);
List<LockPatternView.Cell> cellPattern =
- LockPatternUtils.stringToPattern(lockPattern);
+ lpu.stringToPattern(lockPattern);
lpu.saveLockPattern(cellPattern);
} catch (IllegalArgumentException e) {
// Don't want corrupted lock pattern to hang the reboot process
@@ -1946,6 +1946,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
// Set default tty mode
loadSetting(stmt, Settings.System.TTY_MODE, 0);
+ // Set default noise suppression value
+ loadSetting(stmt, Settings.System.NOISE_SUPPRESSION, 0);
+
loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
R.integer.def_screen_brightness);
@@ -1966,6 +1969,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
R.integer.def_pointer_speed);
+
+ loadIntegerSetting(stmt, Settings.System.STATUS_BAR_BATTERY,
+ R.integer.def_battery_style);
} finally {
if (stmt != null) stmt.close();
}
@@ -2225,12 +2231,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
// Set the preferred network mode to 0 = Global, CDMA default
int type;
- if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
- type = Phone.NT_MODE_GLOBAL;
- } else {
type = SystemProperties.getInt("ro.telephony.default_network",
RILConstants.PREFERRED_NETWORK_MODE);
- }
loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
// --- New global settings start here
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index f18338a..2c1b13c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -974,7 +975,8 @@ public class SettingsProvider extends ContentProvider {
// Only proxy the openFile call to drm or media providers
String authority = soundUri.getAuthority();
boolean isDrmAuthority = authority.equals(DrmStore.AUTHORITY);
- if (isDrmAuthority || authority.equals(MediaStore.AUTHORITY)) {
+ if (isDrmAuthority || authority.equals(MediaStore.AUTHORITY) ||
+ authority.equals(RingtoneManager.THEME_AUTHORITY)) {
if (isDrmAuthority) {
try {
@@ -1015,7 +1017,8 @@ public class SettingsProvider extends ContentProvider {
// Only proxy the openFile call to drm or media providers
String authority = soundUri.getAuthority();
boolean isDrmAuthority = authority.equals(DrmStore.AUTHORITY);
- if (isDrmAuthority || authority.equals(MediaStore.AUTHORITY)) {
+ if (isDrmAuthority || authority.equals(MediaStore.AUTHORITY) ||
+ authority.equals(RingtoneManager.THEME_AUTHORITY)) {
if (isDrmAuthority) {
try {
@@ -1028,10 +1031,8 @@ public class SettingsProvider extends ContentProvider {
}
}
- ParcelFileDescriptor pfd = null;
try {
- pfd = context.getContentResolver().openFileDescriptor(soundUri, mode);
- return new AssetFileDescriptor(pfd, 0, -1);
+ return context.getContentResolver().openAssetFileDescriptor(soundUri, mode);
} catch (FileNotFoundException ex) {
// fall through and open the fallback ringtone below
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index cfe70dc..9e19e28 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -16,6 +16,7 @@
<uses-permission android:name="android.permission.STATUS_BAR" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK" />
+ <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
@@ -31,6 +32,11 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_4G_RADIO_DISABLE" />
+ <uses-permission android:name="android.permission.ACCESS_4G_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_4G_STATE" />
+ <uses-permission android:name="com.android.phone.CHANGE_NETWORK_MODE" />
<!-- Physical hardware -->
<uses-permission android:name="android.permission.MANAGE_USB" />
@@ -62,6 +68,11 @@
<uses-permission android:name="android.permission.READ_DREAM_STATE" />
<uses-permission android:name="android.permission.WRITE_DREAM_STATE" />
+ <!-- Power widget -->
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+
<application
android:persistent="true"
android:allowClearUserData="false"
@@ -210,8 +221,20 @@
<action android:name="android.service.dreams.DreamService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
+ <meta-data
+ android:name="android.service.dream"
+ android:resource="@xml/dream_info" />
</service>
+ <activity android:name=".BeanBagDreamSettings"
+ android:taskAffinity=""
+ android:excludeFromRecents="true"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".Somnambulator"
android:label="@string/start_dreams"
android:icon="@mipmap/ic_launcher_dreams"
diff --git a/packages/SystemUI/res/color/clock_view_color.xml b/packages/SystemUI/res/color/clock_view_color.xml
new file mode 100644
index 0000000..a4ea509
--- /dev/null
+++ b/packages/SystemUI/res/color/clock_view_color.xml
@@ -0,0 +1,9 @@
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item android:state_pressed="true"
+ android:color="@android:color/holo_blue_light"/> <!-- pressed -->
+ <item android:state_focused="true"
+ android:color="@android:color/holo_blue_light"/> <!-- focused -->
+ <item android:color="#ffffff"/> <!--default -->
+
+</selector>
diff --git a/packages/SystemUI/res/color/date_view_color.xml b/packages/SystemUI/res/color/date_view_color.xml
new file mode 100644
index 0000000..22d6da8
--- /dev/null
+++ b/packages/SystemUI/res/color/date_view_color.xml
@@ -0,0 +1,9 @@
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item android:state_pressed="true"
+ android:color="@android:color/holo_blue_light"/> <!-- pressed -->
+ <item android:state_focused="true"
+ android:color="@android:color/holo_blue_light"/> <!-- focused -->
+ <item android:color="#cccccc"/> <!--default -->
+
+</selector>
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
index fd33ef3..cf18e33 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_2g3g_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_2g3g_on.png
new file mode 100644
index 0000000..3d57482
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_2g3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_2g_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_2g_on.png
new file mode 100644
index 0000000..79472ad
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_2g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_3g_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_3g_on.png
new file mode 100644
index 0000000..a41d9f2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_neutral.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_neutral.png
new file mode 100644
index 0000000..a78ce71
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_neutral.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_neutral.png
new file mode 100644
index 0000000..3ae9f2e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_neutral.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_neutral.png
new file mode 100644
index 0000000..cc32054
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_off.png
new file mode 100644
index 0000000..48eb6c0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_on.png
new file mode 100644
index 0000000..12d4985
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_gps_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_off.png
new file mode 100644
index 0000000..5e2a5f2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_on.png
new file mode 100644
index 0000000..4cf28b5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_lock_screen_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_off.png
new file mode 100644
index 0000000..9f5ad63
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_on.png
new file mode 100644
index 0000000..1ff664f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_nfc_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_profiles.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_profiles.png
new file mode 100644
index 0000000..0fce1d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_profiles.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_off.png
new file mode 100644
index 0000000..fc97682
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_on.png
new file mode 100644
index 0000000..36a7075
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_quiet_hours_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_off.png
new file mode 100644
index 0000000..be065da
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_on.png
new file mode 100644
index 0000000..2e4b577
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_vibrate_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_vibrate_on.png
new file mode 100644
index 0000000..64c942b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_ring_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_off.png
new file mode 100644
index 0000000..5b63f32
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_on.png
new file mode 100644
index 0000000..227d485
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_screen_timeout_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_data_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_data_off.png
new file mode 100644
index 0000000..3c4cd4e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_data_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_sleep.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_sleep.png
new file mode 100644
index 0000000..171e403
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_sleep.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_sync_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_sync_off.png
new file mode 100644
index 0000000..85cd2d9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_sync_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_sync_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_sync_on.png
new file mode 100644
index 0000000..1ab8307
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_sync_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_torch_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_torch_off.png
new file mode 100644
index 0000000..14f3c85
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_torch_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_torch_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_torch_on.png
new file mode 100644
index 0000000..5d01f2d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_torch_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_unexpected_network.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_unexpected_network.png
new file mode 100644
index 0000000..5a2f132
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_unexpected_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_connected.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_connected.png
new file mode 100644
index 0000000..769e391
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_off.png
new file mode 100644
index 0000000..7bf074a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_on.png
new file mode 100644
index 0000000..faf7963
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_tether_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_off.png
new file mode 100644
index 0000000..87b119a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_on.png
new file mode 100644
index 0000000..298feff
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_neutral.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_neutral.png
new file mode 100644
index 0000000..49347f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_off.png
new file mode 100644
index 0000000..4b8c68b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_on.png
new file mode 100644
index 0000000..c91b118
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_ap_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_recents_clear_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_recents_clear_normal.png
new file mode 100644
index 0000000..ead184d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_recents_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_recents_clear_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_recents_clear_pressed.png
new file mode 100644
index 0000000..203e232
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_recents_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add.png
new file mode 100644
index 0000000..83d42e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_land.png
new file mode 100644
index 0000000..714546b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_side.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_side.png
new file mode 100644
index 0000000..956ebe4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_add_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 84e6bc8..873e284 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..192610b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index 782d214..07989e6 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_side.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_side.png
new file mode 100644
index 0000000..0d12637
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big.png
new file mode 100644
index 0000000..3a44e09
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big_land.png
new file mode 100644
index 0000000..8630823
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_big_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_side.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_side.png
new file mode 100644
index 0000000..24ad426
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search.png
new file mode 100644
index 0000000..096e775
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_land.png
new file mode 100644
index 0000000..8c82c44
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_side.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_side.png
new file mode 100644
index 0000000..f8e9b08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_search_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_2g3g_off.png b/packages/SystemUI/res/drawable-hdpi/stat_2g3g_off.png
new file mode 100644
index 0000000..ff310a6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_2g3g_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_2g3g_on.png b/packages/SystemUI/res/drawable-hdpi/stat_2g3g_on.png
new file mode 100644
index 0000000..8a3ea40
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_2g3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_3g_on.png b/packages/SystemUI/res/drawable-hdpi/stat_3g_on.png
new file mode 100644
index 0000000..0f03f7f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_airplane_off.png b/packages/SystemUI/res/drawable-hdpi/stat_airplane_off.png
new file mode 100644
index 0000000..af84d66
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_airplane_on.png b/packages/SystemUI/res/drawable-hdpi/stat_airplane_on.png
new file mode 100644
index 0000000..18dcd88
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_bgoff.9.png b/packages/SystemUI/res/drawable-hdpi/stat_bgoff.9.png
new file mode 100644
index 0000000..e288cb2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_bgoff.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_bgon.9.png b/packages/SystemUI/res/drawable-hdpi/stat_bgon.9.png
new file mode 100644
index 0000000..b27a5cb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_bgon.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_bgon_custom.9.png b/packages/SystemUI/res/drawable-hdpi/stat_bgon_custom.9.png
new file mode 100644
index 0000000..47ecbee
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_bgon_custom.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_bluetooth_off.png b/packages/SystemUI/res/drawable-hdpi/stat_bluetooth_off.png
new file mode 100644
index 0000000..a45c3ea
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_bluetooth_on.png b/packages/SystemUI/res/drawable-hdpi/stat_bluetooth_on.png
new file mode 100644
index 0000000..102a50e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_brightness_auto.png b/packages/SystemUI/res/drawable-hdpi/stat_brightness_auto.png
new file mode 100644
index 0000000..9c82636
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_brightness_auto.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_brightness_mid.png b/packages/SystemUI/res/drawable-hdpi/stat_brightness_mid.png
new file mode 100644
index 0000000..3a5a043
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_brightness_mid.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_brightness_off.png b/packages/SystemUI/res/drawable-hdpi/stat_brightness_off.png
new file mode 100644
index 0000000..0f25e1f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_brightness_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_brightness_on.png b/packages/SystemUI/res/drawable-hdpi/stat_brightness_on.png
new file mode 100644
index 0000000..80a0980
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_brightness_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_data_off.png b/packages/SystemUI/res/drawable-hdpi/stat_data_off.png
new file mode 100644
index 0000000..94de93f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_data_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_data_on.png b/packages/SystemUI/res/drawable-hdpi/stat_data_on.png
new file mode 100644
index 0000000..ff60716
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_data_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_flashlight_off.png b/packages/SystemUI/res/drawable-hdpi/stat_flashlight_off.png
new file mode 100644
index 0000000..b9011a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_flashlight_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_flashlight_on.png b/packages/SystemUI/res/drawable-hdpi/stat_flashlight_on.png
new file mode 100644
index 0000000..6df2dd4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_flashlight_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_gps_off.png b/packages/SystemUI/res/drawable-hdpi/stat_gps_off.png
new file mode 100644
index 0000000..cd3c61e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_gps_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_gps_on.png b/packages/SystemUI/res/drawable-hdpi/stat_gps_on.png
new file mode 100644
index 0000000..5138b70
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_gps_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_inner_focus.9.png b/packages/SystemUI/res/drawable-hdpi/stat_inner_focus.9.png
new file mode 100644
index 0000000..ed79969
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_inner_focus.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_inner_press.9.png b/packages/SystemUI/res/drawable-hdpi/stat_inner_press.9.png
new file mode 100644
index 0000000..b1b6cab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_inner_press.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_lock_screen_off.png b/packages/SystemUI/res/drawable-hdpi/stat_lock_screen_off.png
new file mode 100644
index 0000000..01fa6a5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_lock_screen_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_lock_screen_on.png b/packages/SystemUI/res/drawable-hdpi/stat_lock_screen_on.png
new file mode 100644
index 0000000..b579033
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_lock_screen_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_lte_off.png b/packages/SystemUI/res/drawable-hdpi/stat_lte_off.png
new file mode 100644
index 0000000..1e94c27
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_lte_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_lte_on.png b/packages/SystemUI/res/drawable-hdpi/stat_lte_on.png
new file mode 100644
index 0000000..60426ad
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_lte_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_media_next.png b/packages/SystemUI/res/drawable-hdpi/stat_media_next.png
new file mode 100644
index 0000000..b73e36c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_media_next.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_media_pause.png b/packages/SystemUI/res/drawable-hdpi/stat_media_pause.png
new file mode 100644
index 0000000..5e69ed4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_media_pause.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_media_play.png b/packages/SystemUI/res/drawable-hdpi/stat_media_play.png
new file mode 100644
index 0000000..cd6d28c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_media_play.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_media_previous.png b/packages/SystemUI/res/drawable-hdpi/stat_media_previous.png
new file mode 100644
index 0000000..06caccc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_media_previous.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_orientation_off.png b/packages/SystemUI/res/drawable-hdpi/stat_orientation_off.png
new file mode 100644
index 0000000..bf7e4fb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_orientation_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_orientation_on.png b/packages/SystemUI/res/drawable-hdpi/stat_orientation_on.png
new file mode 100644
index 0000000..8670a96
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_orientation_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_ring_off.png b/packages/SystemUI/res/drawable-hdpi/stat_ring_off.png
new file mode 100644
index 0000000..78b2e8a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_ring_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_ring_on.png b/packages/SystemUI/res/drawable-hdpi/stat_ring_on.png
new file mode 100644
index 0000000..4eb5d38
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_ring_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_ring_vibrate_on.png b/packages/SystemUI/res/drawable-hdpi/stat_ring_vibrate_on.png
new file mode 100644
index 0000000..e7ff566
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_ring_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_off.png b/packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_off.png
new file mode 100644
index 0000000..7003d38
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_on.png b/packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_on.png
new file mode 100644
index 0000000..6ef4255
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_screen_timeout_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_silent.png b/packages/SystemUI/res/drawable-hdpi/stat_silent.png
new file mode 100644
index 0000000..dfa2888
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sleep.png b/packages/SystemUI/res/drawable-hdpi/stat_sleep.png
new file mode 100644
index 0000000..7252a12
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sleep.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sync_off.png b/packages/SystemUI/res/drawable-hdpi/stat_sync_off.png
new file mode 100644
index 0000000..1c9079e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sync_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sync_on.png b/packages/SystemUI/res/drawable-hdpi/stat_sync_on.png
new file mode 100644
index 0000000..daddd54
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sync_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim0.png
new file mode 100644
index 0000000..a9dc546
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim100.png
new file mode 100644
index 0000000..ea49dd7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim15.png
new file mode 100644
index 0000000..f1b97e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim28.png
new file mode 100644
index 0000000..7a9123e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim43.png
new file mode 100644
index 0000000..1b2d22c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim57.png
new file mode 100644
index 0000000..e4a3457
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim71.png
new file mode 100644
index 0000000..6ce4554
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim85.png
new file mode 100644
index 0000000..5685685
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_0.png
new file mode 100644
index 0000000..bdfe108
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_100.png
new file mode 100644
index 0000000..9fdaf23
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_15.png
new file mode 100644
index 0000000..f424636
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_28.png
new file mode 100644
index 0000000..3237b05
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_43.png
new file mode 100644
index 0000000..6d72129
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_57.png
new file mode 100644
index 0000000..6e10476
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_71.png
new file mode 100644
index 0000000..fe0c8b3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_85.png
new file mode 100644
index 0000000..172e00c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_hp.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_hp.png
new file mode 100644
index 0000000..8e17067
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_hp.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_hp.png
new file mode 100644
index 0000000..ddc99d4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_0.png
new file mode 100644
index 0000000..2ecdadf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_100.png
new file mode 100644
index 0000000..dd86fa1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_15.png
new file mode 100644
index 0000000..97cd573
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_28.png
new file mode 100644
index 0000000..105c6e5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_43.png
new file mode 100644
index 0000000..60436e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_57.png
new file mode 100644
index 0000000..8771cd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_71.png
new file mode 100644
index 0000000..9fbc757
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_85.png
new file mode 100644
index 0000000..c12d887
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim0.png
new file mode 100644
index 0000000..9a90c63
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim100.png
new file mode 100644
index 0000000..acecf08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim15.png
new file mode 100644
index 0000000..ab6cc29
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim28.png
new file mode 100644
index 0000000..9bd1aed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim43.png
new file mode 100644
index 0000000..d9a1c60
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim57.png
new file mode 100644
index 0000000..d8ff597
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim71.png
new file mode 100644
index 0000000..eec2e77
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim85.png
new file mode 100644
index 0000000..c34cbdf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim0.png
new file mode 100644
index 0000000..51f8f2f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim100.png
new file mode 100644
index 0000000..d43e7c9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim15.png
new file mode 100644
index 0000000..8827ae8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim28.png
new file mode 100644
index 0000000..26a0b2e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim43.png
new file mode 100644
index 0000000..519437b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim57.png
new file mode 100644
index 0000000..8f44b53
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim71.png
new file mode 100644
index 0000000..52c55af
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim85.png
new file mode 100644
index 0000000..70fa203
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_icon.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_icon.png
new file mode 100644
index 0000000..0405006
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_icon.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_0.png
new file mode 100644
index 0000000..8315123
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_100.png
new file mode 100644
index 0000000..1be1d88
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_15.png
new file mode 100644
index 0000000..49583cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_28.png
new file mode 100644
index 0000000..8dfeb7f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_43.png
new file mode 100644
index 0000000..f172005
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_57.png
new file mode 100644
index 0000000..49f733f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_71.png
new file mode 100644
index 0000000..d1b94a6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_85.png
new file mode 100644
index 0000000..0a99fe2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_unknown.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_unknown.png
new file mode 100644
index 0000000..2fe4b3c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_kb_battery_unknown.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_min.png
new file mode 100644
index 0000000..c3f79ce
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_min.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_vibrate_off.png b/packages/SystemUI/res/drawable-hdpi/stat_vibrate_off.png
new file mode 100644
index 0000000..4199106
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_vibrate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_vibrate_on.png b/packages/SystemUI/res/drawable-hdpi/stat_vibrate_on.png
new file mode 100644
index 0000000..4199106
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_off.png b/packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_off.png
new file mode 100644
index 0000000..5e24ba2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_on.png b/packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_on.png
new file mode 100644
index 0000000..34eaa75
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_wifi_ap_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_wifi_off.png b/packages/SystemUI/res/drawable-hdpi/stat_wifi_off.png
new file mode 100644
index 0000000..0e0ccda
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_wifi_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_wifi_on.png b/packages/SystemUI/res/drawable-hdpi/stat_wifi_on.png
new file mode 100644
index 0000000..e095cf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_wimax_off.png b/packages/SystemUI/res/drawable-hdpi/stat_wimax_off.png
new file mode 100644
index 0000000..7270cb5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_wimax_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_wimax_on.png b/packages/SystemUI/res/drawable-hdpi/stat_wimax_on.png
new file mode 100644
index 0000000..01a75a4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_wimax_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
index 667b13d..8d0233f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_2g3g_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_2g3g_on.png
new file mode 100644
index 0000000..e89bc93
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_2g3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_2g_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_2g_on.png
new file mode 100644
index 0000000..7cb32bc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_2g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_3g_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_3g_on.png
new file mode 100644
index 0000000..c018779
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_neutral.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_neutral.png
new file mode 100644
index 0000000..568e4af
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_neutral.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_neutral.png
new file mode 100644
index 0000000..6689696
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_neutral.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_neutral.png
new file mode 100644
index 0000000..db28b73
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_off.png
new file mode 100644
index 0000000..a846980
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_on.png
new file mode 100644
index 0000000..38b6919
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_gps_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_off.png
new file mode 100644
index 0000000..ec5db53
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_on.png
new file mode 100644
index 0000000..ed1bbaf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_lock_screen_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_off.png
new file mode 100644
index 0000000..0e2bea8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_on.png
new file mode 100644
index 0000000..e728ab1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_nfc_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_profiles.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_profiles.png
new file mode 100644
index 0000000..270c127
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_profiles.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_off.png
new file mode 100644
index 0000000..fd7b341
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_on.png
new file mode 100644
index 0000000..4b702a7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_quiet_hours_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_off.png
new file mode 100644
index 0000000..c78a05d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_on.png
new file mode 100644
index 0000000..a78f01f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_vibrate_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_vibrate_on.png
new file mode 100644
index 0000000..4a971c6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_ring_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_off.png
new file mode 100644
index 0000000..69cc168
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_on.png
new file mode 100644
index 0000000..3bd38f8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_screen_timeout_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_data_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_data_off.png
new file mode 100644
index 0000000..8e41109
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_data_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_sleep.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_sleep.png
new file mode 100644
index 0000000..8e0e03c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_sleep.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_sync_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_sync_off.png
new file mode 100644
index 0000000..dfab353
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_sync_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_sync_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_sync_on.png
new file mode 100644
index 0000000..9c5b694
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_sync_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_torch_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_torch_off.png
new file mode 100644
index 0000000..0d262c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_torch_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_torch_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_torch_on.png
new file mode 100644
index 0000000..b796ed3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_torch_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_unexpected_network.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_unexpected_network.png
new file mode 100644
index 0000000..06e6982
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_unexpected_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_connected.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_connected.png
new file mode 100644
index 0000000..4b3f67b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_off.png
new file mode 100644
index 0000000..1c072fe
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_on.png
new file mode 100644
index 0000000..b37d9b8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_tether_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_off.png
new file mode 100644
index 0000000..9ac387e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_on.png
new file mode 100644
index 0000000..fcf86a0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_neutral.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_neutral.png
new file mode 100644
index 0000000..cd82da9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_off.png
new file mode 100644
index 0000000..c170445
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_on.png
new file mode 100644
index 0000000..cdf95fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_ap_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_recents_clear_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_recents_clear_normal.png
new file mode 100644
index 0000000..5dacccb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_recents_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_recents_clear_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_recents_clear_pressed.png
new file mode 100644
index 0000000..f1f6b00
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_recents_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add.png
new file mode 100644
index 0000000..459cf56
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_land.png
new file mode 100644
index 0000000..e0adcd0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_side.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_side.png
new file mode 100644
index 0000000..6231b21
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_add_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..6ae472e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_side.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_side.png
new file mode 100644
index 0000000..5854b38
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big.png
new file mode 100644
index 0000000..f21a8e8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big_land.png
new file mode 100644
index 0000000..6e07b03
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_big_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_side.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_side.png
new file mode 100644
index 0000000..286bd00
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search.png
new file mode 100644
index 0000000..59e6572c8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_land.png
new file mode 100644
index 0000000..e76fc91
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_side.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_side.png
new file mode 100644
index 0000000..0ff41f5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_search_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_2g3g_off.png b/packages/SystemUI/res/drawable-mdpi/stat_2g3g_off.png
new file mode 100644
index 0000000..9651082
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_2g3g_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_2g3g_on.png b/packages/SystemUI/res/drawable-mdpi/stat_2g3g_on.png
new file mode 100644
index 0000000..a3b8821
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_2g3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_3g_on.png b/packages/SystemUI/res/drawable-mdpi/stat_3g_on.png
new file mode 100644
index 0000000..dbf8fb6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_airplane_off.png b/packages/SystemUI/res/drawable-mdpi/stat_airplane_off.png
new file mode 100644
index 0000000..c09e18f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_airplane_on.png b/packages/SystemUI/res/drawable-mdpi/stat_airplane_on.png
new file mode 100644
index 0000000..de8b787
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_bgoff.9.png b/packages/SystemUI/res/drawable-mdpi/stat_bgoff.9.png
new file mode 100644
index 0000000..e288cb2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_bgoff.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_bgon.9.png b/packages/SystemUI/res/drawable-mdpi/stat_bgon.9.png
new file mode 100644
index 0000000..b27a5cb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_bgon.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_bgon_custom.9.png b/packages/SystemUI/res/drawable-mdpi/stat_bgon_custom.9.png
new file mode 100644
index 0000000..47ecbee
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_bgon_custom.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_bluetooth_off.png b/packages/SystemUI/res/drawable-mdpi/stat_bluetooth_off.png
new file mode 100644
index 0000000..3583063
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_bluetooth_on.png b/packages/SystemUI/res/drawable-mdpi/stat_bluetooth_on.png
new file mode 100644
index 0000000..c01ffb2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_brightness_auto.png b/packages/SystemUI/res/drawable-mdpi/stat_brightness_auto.png
new file mode 100644
index 0000000..9cebeb3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_brightness_auto.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_brightness_mid.png b/packages/SystemUI/res/drawable-mdpi/stat_brightness_mid.png
new file mode 100644
index 0000000..fe043f5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_brightness_mid.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_brightness_off.png b/packages/SystemUI/res/drawable-mdpi/stat_brightness_off.png
new file mode 100644
index 0000000..c073ebe
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_brightness_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_brightness_on.png b/packages/SystemUI/res/drawable-mdpi/stat_brightness_on.png
new file mode 100644
index 0000000..b0bbb26
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_brightness_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_data_off.png b/packages/SystemUI/res/drawable-mdpi/stat_data_off.png
new file mode 100644
index 0000000..6334dab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_data_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_data_on.png b/packages/SystemUI/res/drawable-mdpi/stat_data_on.png
new file mode 100644
index 0000000..24cb929
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_data_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_flashlight_off.png b/packages/SystemUI/res/drawable-mdpi/stat_flashlight_off.png
new file mode 100644
index 0000000..03040bd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_flashlight_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_flashlight_on.png b/packages/SystemUI/res/drawable-mdpi/stat_flashlight_on.png
new file mode 100644
index 0000000..8f461e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_flashlight_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_gps_off.png b/packages/SystemUI/res/drawable-mdpi/stat_gps_off.png
new file mode 100644
index 0000000..6442720
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_gps_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_gps_on.png b/packages/SystemUI/res/drawable-mdpi/stat_gps_on.png
new file mode 100644
index 0000000..9e98ad9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_gps_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_inner_focus.9.png b/packages/SystemUI/res/drawable-mdpi/stat_inner_focus.9.png
new file mode 100644
index 0000000..ed79969
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_inner_focus.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_inner_press.9.png b/packages/SystemUI/res/drawable-mdpi/stat_inner_press.9.png
new file mode 100644
index 0000000..b1b6cab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_inner_press.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_lock_screen_off.png b/packages/SystemUI/res/drawable-mdpi/stat_lock_screen_off.png
new file mode 100644
index 0000000..16d973b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_lock_screen_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_lock_screen_on.png b/packages/SystemUI/res/drawable-mdpi/stat_lock_screen_on.png
new file mode 100644
index 0000000..7ba6d3d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_lock_screen_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_lte_off.png b/packages/SystemUI/res/drawable-mdpi/stat_lte_off.png
new file mode 100644
index 0000000..d07e3e4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_lte_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_lte_on.png b/packages/SystemUI/res/drawable-mdpi/stat_lte_on.png
new file mode 100644
index 0000000..de86014
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_lte_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_media_next.png b/packages/SystemUI/res/drawable-mdpi/stat_media_next.png
new file mode 100644
index 0000000..83489c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_media_next.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_media_pause.png b/packages/SystemUI/res/drawable-mdpi/stat_media_pause.png
new file mode 100644
index 0000000..74c3ac1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_media_pause.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_media_play.png b/packages/SystemUI/res/drawable-mdpi/stat_media_play.png
new file mode 100644
index 0000000..c01b6fd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_media_play.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_media_previous.png b/packages/SystemUI/res/drawable-mdpi/stat_media_previous.png
new file mode 100644
index 0000000..643cecd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_media_previous.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_orientation_off.png b/packages/SystemUI/res/drawable-mdpi/stat_orientation_off.png
new file mode 100644
index 0000000..991317c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_orientation_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_orientation_on.png b/packages/SystemUI/res/drawable-mdpi/stat_orientation_on.png
new file mode 100644
index 0000000..2e573eb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_orientation_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_ring_off.png b/packages/SystemUI/res/drawable-mdpi/stat_ring_off.png
new file mode 100644
index 0000000..e727fa2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_ring_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_ring_on.png b/packages/SystemUI/res/drawable-mdpi/stat_ring_on.png
new file mode 100644
index 0000000..bc93785
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_ring_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_ring_vibrate_on.png b/packages/SystemUI/res/drawable-mdpi/stat_ring_vibrate_on.png
new file mode 100644
index 0000000..0714ff3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_ring_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_off.png b/packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_off.png
new file mode 100644
index 0000000..5250f42
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_on.png b/packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_on.png
new file mode 100644
index 0000000..4771bca
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_screen_timeout_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_silent.png b/packages/SystemUI/res/drawable-mdpi/stat_silent.png
new file mode 100644
index 0000000..b7c7663
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sleep.png b/packages/SystemUI/res/drawable-mdpi/stat_sleep.png
new file mode 100644
index 0000000..eb3aaed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sleep.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sync_off.png b/packages/SystemUI/res/drawable-mdpi/stat_sync_off.png
new file mode 100644
index 0000000..ddef24c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sync_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sync_on.png b/packages/SystemUI/res/drawable-mdpi/stat_sync_on.png
new file mode 100644
index 0000000..f7ba24a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sync_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim0.png
new file mode 100644
index 0000000..78d2384
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim100.png
new file mode 100644
index 0000000..5aca171
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim15.png
new file mode 100644
index 0000000..7c06ef7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim28.png
new file mode 100644
index 0000000..1fce2fc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim43.png
new file mode 100644
index 0000000..28294dd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim57.png
new file mode 100644
index 0000000..c905ddc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim71.png
new file mode 100644
index 0000000..dc5184b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim85.png
new file mode 100644
index 0000000..3af272c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_0.png
new file mode 100644
index 0000000..cd042a7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_100.png
new file mode 100644
index 0000000..1d506b2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_15.png
new file mode 100644
index 0000000..cc3a01a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_28.png
new file mode 100644
index 0000000..937e384
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_43.png
new file mode 100644
index 0000000..41d02db
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_57.png
new file mode 100644
index 0000000..ed90158
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_71.png
new file mode 100644
index 0000000..a195b26
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_85.png
new file mode 100644
index 0000000..690979d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_hp.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_hp.png
new file mode 100644
index 0000000..e7fefc5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_hp.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_hp.png
new file mode 100644
index 0000000..13ec481
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_0.png
new file mode 100644
index 0000000..2ecdadf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_100.png
new file mode 100644
index 0000000..dd86fa1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_15.png
new file mode 100644
index 0000000..97cd573
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_28.png
new file mode 100644
index 0000000..105c6e5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_43.png
new file mode 100644
index 0000000..60436e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_57.png
new file mode 100644
index 0000000..8771cd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_71.png
new file mode 100644
index 0000000..9fbc757
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_85.png
new file mode 100644
index 0000000..c12d887
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim0.png
new file mode 100644
index 0000000..9a90c63
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim100.png
new file mode 100644
index 0000000..acecf08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim15.png
new file mode 100644
index 0000000..ab6cc29
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim28.png
new file mode 100644
index 0000000..9bd1aed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim43.png
new file mode 100644
index 0000000..d9a1c60
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim57.png
new file mode 100644
index 0000000..d8ff597
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim71.png
new file mode 100644
index 0000000..eec2e77
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim85.png
new file mode 100644
index 0000000..c34cbdf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim0.png
new file mode 100644
index 0000000..47d9077
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim100.png
new file mode 100644
index 0000000..45b8f52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim15.png
new file mode 100644
index 0000000..01328dd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim28.png
new file mode 100644
index 0000000..2fcfc5c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim43.png
new file mode 100644
index 0000000..b4a86bb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim57.png
new file mode 100644
index 0000000..dc600d5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim71.png
new file mode 100644
index 0000000..e1a4f49
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim85.png
new file mode 100644
index 0000000..1389c50
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_icon.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_icon.png
new file mode 100644
index 0000000..ba8d71b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_icon.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_0.png
new file mode 100644
index 0000000..50c91e9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_100.png
new file mode 100644
index 0000000..9fadfe8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_15.png
new file mode 100644
index 0000000..f9879a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_28.png
new file mode 100644
index 0000000..5f780ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_43.png
new file mode 100644
index 0000000..534043e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_57.png
new file mode 100644
index 0000000..047a2b5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_71.png
new file mode 100644
index 0000000..8d64d3e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_85.png
new file mode 100644
index 0000000..bc4652e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_unknown.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_unknown.png
new file mode 100644
index 0000000..2fe4b3c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_kb_battery_unknown.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_min.png
new file mode 100644
index 0000000..51a4c4c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_min.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_vibrate_off.png b/packages/SystemUI/res/drawable-mdpi/stat_vibrate_off.png
new file mode 100644
index 0000000..2d99b76
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_vibrate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_vibrate_on.png b/packages/SystemUI/res/drawable-mdpi/stat_vibrate_on.png
new file mode 100644
index 0000000..2d99b76
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_off.png b/packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_off.png
new file mode 100644
index 0000000..d826266
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_on.png b/packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_on.png
new file mode 100644
index 0000000..2244bde
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_wifi_ap_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_wifi_off.png b/packages/SystemUI/res/drawable-mdpi/stat_wifi_off.png
new file mode 100644
index 0000000..6edec54
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_wifi_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_wifi_on.png b/packages/SystemUI/res/drawable-mdpi/stat_wifi_on.png
new file mode 100644
index 0000000..1fa295b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_wimax_off.png b/packages/SystemUI/res/drawable-mdpi/stat_wimax_off.png
new file mode 100644
index 0000000..756126d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_wimax_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_wimax_on.png b/packages/SystemUI/res/drawable-mdpi/stat_wimax_on.png
new file mode 100644
index 0000000..a917c9f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_wimax_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/cid_angry.png b/packages/SystemUI/res/drawable-nodpi/cid_angry.png
new file mode 100644
index 0000000..008d279
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/cid_angry.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/cid_confused.png b/packages/SystemUI/res/drawable-nodpi/cid_confused.png
new file mode 100644
index 0000000..4c51d18
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/cid_confused.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/cid_normal.png b/packages/SystemUI/res/drawable-nodpi/cid_normal.png
new file mode 100644
index 0000000..6425389
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/cid_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/cidlogo.png b/packages/SystemUI/res/drawable-nodpi/cidlogo.png
new file mode 100644
index 0000000..ceb2246
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/cidlogo.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/cidlogo_alt.png b/packages/SystemUI/res/drawable-nodpi/cidlogo_alt.png
new file mode 100644
index 0000000..e5c03ed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/cidlogo_alt.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
index 38bd0cd..b6ba3f5 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
index baeb49e..12ae791 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
index 0c12c16..0ea62e5 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
index 23f976c..2300b86 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
index 477df5f..6adcfd8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
index 27b7ace..21b9a6c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim0.png
new file mode 100644
index 0000000..24bb1e0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim100.png
new file mode 100644
index 0000000..8115db1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim15.png
new file mode 100644
index 0000000..b90f5e3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim28.png
new file mode 100644
index 0000000..c0d3204
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim43.png
new file mode 100644
index 0000000..adc37d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim57.png
new file mode 100644
index 0000000..7c771c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim71.png
new file mode 100644
index 0000000..8f32043
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim85.png
new file mode 100644
index 0000000..42b71b2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_0.png
new file mode 100644
index 0000000..f3f1a19
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_100.png
new file mode 100644
index 0000000..23be933
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_15.png
new file mode 100644
index 0000000..9cb4909
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_28.png
new file mode 100644
index 0000000..80ec7c7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_43.png
new file mode 100644
index 0000000..c892bd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_57.png
new file mode 100644
index 0000000..45822b0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_71.png
new file mode 100644
index 0000000..465db1e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_85.png
new file mode 100644
index 0000000..b3f08d4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_hp.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_hp.png
new file mode 100644
index 0000000..2ef8d75
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_hp.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_hp.png
new file mode 100644
index 0000000..d88202c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_data_fully_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim0.png
new file mode 100644
index 0000000..7c2856d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim100.png
new file mode 100644
index 0000000..401f534
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim15.png
new file mode 100644
index 0000000..7437da0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim28.png
new file mode 100644
index 0000000..0cbc359
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim43.png
new file mode 100644
index 0000000..537de4b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim57.png
new file mode 100644
index 0000000..1c5fc18
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim71.png
new file mode 100644
index 0000000..ebf6a34
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim85.png
new file mode 100644
index 0000000..253ad48
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_0.png
new file mode 100644
index 0000000..cee09ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_100.png
new file mode 100644
index 0000000..3bd6fc2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_15.png
new file mode 100644
index 0000000..3ead40a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_28.png
new file mode 100644
index 0000000..4ce926b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_43.png
new file mode 100644
index 0000000..f01f6b8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_57.png
new file mode 100644
index 0000000..73f0d54
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_71.png
new file mode 100644
index 0000000..a2074dd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_85.png
new file mode 100644
index 0000000..30e19c9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_kb_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_min.png
new file mode 100644
index 0000000..5f17531
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/stat_sys_signal_min.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim0.png
new file mode 100644
index 0000000..24bb1e0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim100.png
new file mode 100644
index 0000000..8115db1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim15.png
new file mode 100644
index 0000000..b90f5e3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim28.png
new file mode 100644
index 0000000..c0d3204
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim43.png
new file mode 100644
index 0000000..adc37d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim57.png
new file mode 100644
index 0000000..7c771c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim71.png
new file mode 100644
index 0000000..8f32043
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim85.png
new file mode 100644
index 0000000..42b71b2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_0.png
new file mode 100644
index 0000000..f3f1a19
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_100.png
new file mode 100644
index 0000000..23be933
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_15.png
new file mode 100644
index 0000000..9cb4909
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_28.png
new file mode 100644
index 0000000..80ec7c7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_43.png
new file mode 100644
index 0000000..c892bd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_57.png
new file mode 100644
index 0000000..45822b0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_71.png
new file mode 100644
index 0000000..465db1e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_85.png
new file mode 100644
index 0000000..b3f08d4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_hp.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_hp.png
new file mode 100644
index 0000000..250e32a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_hp.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_hp.png
new file mode 100644
index 0000000..f494068
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_data_fully_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_min.png
new file mode 100644
index 0000000..fd0f879
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/stat_sys_signal_min.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim0.png
new file mode 100644
index 0000000..979b733
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim100.png
new file mode 100644
index 0000000..599bd42
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim15.png
new file mode 100644
index 0000000..ed4dd8a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim28.png
new file mode 100644
index 0000000..d4e1b5d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim43.png
new file mode 100644
index 0000000..763eb3f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim57.png
new file mode 100644
index 0000000..f2294d4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim71.png
new file mode 100644
index 0000000..4fa3cea
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim85.png
new file mode 100644
index 0000000..1ed832f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_0.png
new file mode 100644
index 0000000..1b3d49e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_100.png
new file mode 100644
index 0000000..a73398a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_15.png
new file mode 100644
index 0000000..37cc5a2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_28.png
new file mode 100644
index 0000000..f3b35d8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_43.png
new file mode 100644
index 0000000..abdbec2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_57.png
new file mode 100644
index 0000000..68da4b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_71.png
new file mode 100644
index 0000000..c0d35cb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_85.png
new file mode 100644
index 0000000..72976dd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_hp.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_hp.png
new file mode 100644
index 0000000..19bcae5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_hp.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_hp.png
new file mode 100644
index 0000000..b2e4adb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_data_fully_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim0.png
new file mode 100644
index 0000000..7791c7e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim100.png
new file mode 100644
index 0000000..0aaa70a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim15.png
new file mode 100644
index 0000000..614601d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim28.png
new file mode 100644
index 0000000..8690413
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim43.png
new file mode 100644
index 0000000..81835f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim57.png
new file mode 100644
index 0000000..4c62c02
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim71.png
new file mode 100644
index 0000000..f58c769
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim85.png
new file mode 100644
index 0000000..93398a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_0.png
new file mode 100644
index 0000000..3d78fb7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_100.png
new file mode 100644
index 0000000..db00469
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_15.png
new file mode 100644
index 0000000..baa9099
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_28.png
new file mode 100644
index 0000000..e45f245
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_43.png
new file mode 100644
index 0000000..3847faf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_57.png
new file mode 100644
index 0000000..5a0f1a1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_71.png
new file mode 100644
index 0000000..2f1c574
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_85.png
new file mode 100644
index 0000000..04d3ab9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_kb_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_min.png
new file mode 100644
index 0000000..cd7d4db
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/stat_sys_signal_min.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png
index 8758b02..71c84ef 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_2g3g_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_2g3g_on.png
new file mode 100644
index 0000000..fbfdfa0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_2g3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_2g_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_2g_on.png
new file mode 100644
index 0000000..253e135
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_2g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_3g_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_3g_on.png
new file mode 100644
index 0000000..919286a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_neutral.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_neutral.png
new file mode 100644
index 0000000..19da4b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_neutral.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_neutral.png
new file mode 100644
index 0000000..4142ca1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_neutral.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_neutral.png
new file mode 100644
index 0000000..663db3e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_off.png
new file mode 100644
index 0000000..912ea4a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_on.png
new file mode 100644
index 0000000..b23c9f8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_gps_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_off.png
new file mode 100644
index 0000000..2393896
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_on.png
new file mode 100644
index 0000000..9b8d531
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_lock_screen_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_off.png
new file mode 100644
index 0000000..d660b87
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_on.png
new file mode 100644
index 0000000..fc1093c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_nfc_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_profiles.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_profiles.png
new file mode 100644
index 0000000..ffcd8fb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_profiles.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_off.png
new file mode 100644
index 0000000..fd7c669
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_on.png
new file mode 100644
index 0000000..f722db1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_quiet_hours_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_off.png
new file mode 100644
index 0000000..fbfc09b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_on.png
new file mode 100644
index 0000000..53e2cf8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_vibrate_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_vibrate_on.png
new file mode 100644
index 0000000..f4ad71b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ring_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_off.png
new file mode 100644
index 0000000..7583d28
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_on.png
new file mode 100644
index 0000000..ffa371a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_screen_timeout_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_data_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_data_off.png
new file mode 100644
index 0000000..75898c6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_data_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_sleep.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_sleep.png
new file mode 100644
index 0000000..13a68b2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_sleep.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_off.png
new file mode 100644
index 0000000..44844ac
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_on.png
new file mode 100644
index 0000000..c1a51f4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_sync_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_off.png
new file mode 100644
index 0000000..77d5726
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_on.png
new file mode 100644
index 0000000..1a5dda7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_torch_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_unexpected_network.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_unexpected_network.png
new file mode 100644
index 0000000..870f721
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_unexpected_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_connected.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_connected.png
new file mode 100644
index 0000000..e42e338
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_off.png
new file mode 100644
index 0000000..a9c453a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_on.png
new file mode 100644
index 0000000..e428b4e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_tether_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_off.png
new file mode 100644
index 0000000..cb443a6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_on.png
new file mode 100644
index 0000000..adb7db6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_neutral.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_neutral.png
new file mode 100644
index 0000000..96918df
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_neutral.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_off.png
new file mode 100644
index 0000000..2b0355e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_on.png
new file mode 100644
index 0000000..518b0d9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_ap_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_normal.png
new file mode 100644
index 0000000..c882e9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_pressed.png
new file mode 100644
index 0000000..992b50d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_recents_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add.png
new file mode 100644
index 0000000..4c205e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_land.png
new file mode 100644
index 0000000..bf08774
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_side.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_side.png
new file mode 100644
index 0000000..916fe9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_add_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index bd60cd6..4e1c069 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..efc2389
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index 5272c91..b91ef65 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_side.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_side.png
new file mode 100644
index 0000000..7504d32
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big.png
new file mode 100644
index 0000000..c264e08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big_land.png
new file mode 100644
index 0000000..eeeb372
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_big_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_side.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_side.png
new file mode 100644
index 0000000..db596cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search.png
new file mode 100644
index 0000000..205a571
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_land.png
new file mode 100644
index 0000000..a3a87af
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_side.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_side.png
new file mode 100644
index 0000000..69f1a0b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_search_side.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_2g3g_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_2g3g_off.png
new file mode 100644
index 0000000..dc8f7dd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_2g3g_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_2g3g_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_2g3g_on.png
new file mode 100644
index 0000000..b99c438
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_2g3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_3g_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_3g_on.png
new file mode 100644
index 0000000..e340d36
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_3g_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_airplane_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_airplane_off.png
new file mode 100644
index 0000000..ba1efa6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_airplane_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_airplane_on.png
new file mode 100644
index 0000000..32d58e5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_off.png
new file mode 100644
index 0000000..bea478e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_on.png
new file mode 100644
index 0000000..70aca2d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_brightness_auto.png b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_auto.png
new file mode 100644
index 0000000..709c25a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_auto.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_brightness_mid.png b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_mid.png
new file mode 100644
index 0000000..b6d238b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_mid.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_brightness_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_off.png
new file mode 100644
index 0000000..54d40d6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_brightness_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_on.png
new file mode 100644
index 0000000..dd13c09
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_brightness_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_data_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_data_off.png
new file mode 100644
index 0000000..d71463d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_data_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_data_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_data_on.png
new file mode 100644
index 0000000..dce699f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_data_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_flashlight_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_flashlight_off.png
new file mode 100644
index 0000000..88f5dda
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_flashlight_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_flashlight_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_flashlight_on.png
new file mode 100644
index 0000000..d1d46b0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_flashlight_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_gps_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_gps_off.png
new file mode 100644
index 0000000..0548274
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_gps_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_gps_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_gps_on.png
new file mode 100644
index 0000000..d1d9768
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_gps_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_off.png
new file mode 100644
index 0000000..aa6bfdd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_on.png
new file mode 100644
index 0000000..f272d3f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_lock_screen_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_lte_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_lte_off.png
new file mode 100644
index 0000000..a4b2c2a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_lte_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_lte_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_lte_on.png
new file mode 100644
index 0000000..29e0b10
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_lte_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_media_next.png b/packages/SystemUI/res/drawable-xhdpi/stat_media_next.png
new file mode 100644
index 0000000..2ac7422
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_media_next.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_media_pause.png b/packages/SystemUI/res/drawable-xhdpi/stat_media_pause.png
new file mode 100644
index 0000000..1a7fb18
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_media_pause.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_media_play.png b/packages/SystemUI/res/drawable-xhdpi/stat_media_play.png
new file mode 100644
index 0000000..82930fc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_media_play.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_media_previous.png b/packages/SystemUI/res/drawable-xhdpi/stat_media_previous.png
new file mode 100644
index 0000000..be5c932
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_media_previous.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_orientation_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_orientation_off.png
new file mode 100644
index 0000000..94acc83
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_orientation_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_orientation_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_orientation_on.png
new file mode 100644
index 0000000..fd55baa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_orientation_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_ring_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_ring_off.png
new file mode 100644
index 0000000..70526c6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_ring_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_ring_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_ring_on.png
new file mode 100644
index 0000000..5e9413a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_ring_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_ring_vibrate_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_ring_vibrate_on.png
new file mode 100644
index 0000000..2d66704
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_ring_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_off.png
new file mode 100644
index 0000000..497c489
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_on.png
new file mode 100644
index 0000000..e0f2918
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_screen_timeout_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_silent.png b/packages/SystemUI/res/drawable-xhdpi/stat_silent.png
new file mode 100644
index 0000000..458cd42
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sleep.png b/packages/SystemUI/res/drawable-xhdpi/stat_sleep.png
new file mode 100644
index 0000000..562ee34
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sleep.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sync_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_sync_off.png
new file mode 100644
index 0000000..11925bd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sync_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sync_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_sync_on.png
new file mode 100644
index 0000000..17b5946
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sync_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim0.png
new file mode 100644
index 0000000..223c4d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim100.png
new file mode 100644
index 0000000..1a518c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim15.png
new file mode 100644
index 0000000..e32069a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim28.png
new file mode 100644
index 0000000..7eef777
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim43.png
new file mode 100644
index 0000000..359a020
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim57.png
new file mode 100644
index 0000000..15225e2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim71.png
new file mode 100644
index 0000000..e401d01
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim85.png
new file mode 100644
index 0000000..147c51c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_0.png
new file mode 100644
index 0000000..3389306
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_100.png
new file mode 100644
index 0000000..2176d9b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_15.png
new file mode 100644
index 0000000..f34033d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_28.png
new file mode 100644
index 0000000..fff6b28
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_43.png
new file mode 100644
index 0000000..17e4937
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_57.png
new file mode 100644
index 0000000..acc555f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_71.png
new file mode 100644
index 0000000..82127eb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_85.png
new file mode 100644
index 0000000..2ccba10
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_hp.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_hp.png
new file mode 100644
index 0000000..335423b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_hp.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_hp.png
new file mode 100644
index 0000000..9348fda
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_hp.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim0.png
new file mode 100644
index 0000000..c3ef421
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim100.png
new file mode 100644
index 0000000..133e238
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim15.png
new file mode 100644
index 0000000..41d1eb2e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim28.png
new file mode 100644
index 0000000..255939d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim43.png
new file mode 100644
index 0000000..4b7a183
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim57.png
new file mode 100644
index 0000000..04312d0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim71.png
new file mode 100644
index 0000000..63ceeb8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim85.png
new file mode 100644
index 0000000..07e1fb4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_charge_min_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_icon.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_icon.png
new file mode 100644
index 0000000..4bfdd0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_icon.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_0.png
new file mode 100644
index 0000000..e638da9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_100.png
new file mode 100644
index 0000000..65bd4fe
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_15.png
new file mode 100644
index 0000000..c97af71
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_28.png
new file mode 100644
index 0000000..1a138f3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_43.png
new file mode 100644
index 0000000..92e1b7c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_57.png
new file mode 100644
index 0000000..c4700d6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_71.png
new file mode 100644
index 0000000..13871fd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_85.png
new file mode 100644
index 0000000..100dac9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_kb_battery_min_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_min.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_min.png
new file mode 100644
index 0000000..1203d7e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_min.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_vibrate_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_vibrate_off.png
new file mode 100644
index 0000000..122c708
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_vibrate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_vibrate_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_vibrate_on.png
new file mode 100644
index 0000000..122c708
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_vibrate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_off.png
new file mode 100644
index 0000000..afe1997
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_on.png
new file mode 100644
index 0000000..de9f55d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_ap_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_wifi_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_off.png
new file mode 100644
index 0000000..53b4566
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_wifi_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_on.png
new file mode 100644
index 0000000..bdf9918
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_wimax_off.png b/packages/SystemUI/res/drawable-xhdpi/stat_wimax_off.png
new file mode 100644
index 0000000..36ed0a2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_wimax_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_wimax_on.png b/packages/SystemUI/res/drawable-xhdpi/stat_wimax_on.png
new file mode 100644
index 0000000..947fadc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_wimax_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_notifications.xml b/packages/SystemUI/res/drawable/ic_notifications.xml
index 97a7623..358fea8 100644
--- a/packages/SystemUI/res/drawable/ic_notifications.xml
+++ b/packages/SystemUI/res/drawable/ic_notifications.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/ic_notify_open_normal" />
+ android:drawable="@drawable/ic_notify_open_pressed" />
<item
android:drawable="@drawable/ic_notify_open_normal" />
</selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_clear.xml b/packages/SystemUI/res/drawable/ic_notify_clear.xml
index 2163198..9c432b2 100644
--- a/packages/SystemUI/res/drawable/ic_notify_clear.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_clear.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/ic_notify_clear_normal" />
+ android:drawable="@drawable/ic_notify_clear_pressed" />
<item android:drawable="@drawable/ic_notify_clear_normal" />
</selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
index 7cf3175..d8ea524 100644
--- a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/ic_notify_quicksettings_normal" />
+ android:drawable="@drawable/ic_notify_quicksettings_pressed" />
<item
android:drawable="@drawable/ic_notify_quicksettings_normal" />
</selector>
diff --git a/packages/SystemUI/res/drawable/ic_recents_clear.xml b/packages/SystemUI/res/drawable/ic_recents_clear.xml
new file mode 100644
index 0000000..024c7df
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_recents_clear.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/ic_recents_clear_pressed" />
+ <item android:drawable="@drawable/ic_recents_clear_normal" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/stat_power_background.xml b/packages/SystemUI/res/drawable/stat_power_background.xml
new file mode 100644
index 0000000..51b6ff2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_power_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+ <item android:state_pressed="true" android:drawable="@*android:drawable/notification_item_background_color_pressed" />
+
+</selector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_battery_charge_min.xml b/packages/SystemUI/res/drawable/stat_sys_battery_charge_min.xml
new file mode 100644
index 0000000..92ede09
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_battery_charge_min.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="4" android:drawable="@drawable/stat_sys_battery_charge_min_anim0" />
+ <item android:maxLevel="15" android:drawable="@drawable/stat_sys_battery_charge_min_anim15" />
+ <item android:maxLevel="35" android:drawable="@drawable/stat_sys_battery_charge_min_anim28" />
+ <item android:maxLevel="49" android:drawable="@drawable/stat_sys_battery_charge_min_anim43" />
+ <item android:maxLevel="60" android:drawable="@drawable/stat_sys_battery_charge_min_anim57" />
+ <item android:maxLevel="75" android:drawable="@drawable/stat_sys_battery_charge_min_anim71" />
+ <item android:maxLevel="90" android:drawable="@drawable/stat_sys_battery_charge_min_anim85" />
+ <item android:maxLevel="100" android:drawable="@drawable/stat_sys_battery_charge_min_anim100" />
+</level-list>
diff --git a/packages/SystemUI/res/drawable/stat_sys_battery_min.xml b/packages/SystemUI/res/drawable/stat_sys_battery_min.xml
new file mode 100644
index 0000000..1717e1e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_battery_min.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="4" android:drawable="@drawable/stat_sys_battery_min_0" />
+ <item android:maxLevel="15" android:drawable="@drawable/stat_sys_battery_min_15" />
+ <item android:maxLevel="35" android:drawable="@drawable/stat_sys_battery_min_28" />
+ <item android:maxLevel="49" android:drawable="@drawable/stat_sys_battery_min_43" />
+ <item android:maxLevel="60" android:drawable="@drawable/stat_sys_battery_min_57" />
+ <item android:maxLevel="75" android:drawable="@drawable/stat_sys_battery_min_71" />
+ <item android:maxLevel="90" android:drawable="@drawable/stat_sys_battery_min_85" />
+ <item android:maxLevel="100" android:drawable="@drawable/stat_sys_battery_min_100" />
+</level-list>
diff --git a/packages/SystemUI/res/drawable/stat_sys_kb_battery.xml b/packages/SystemUI/res/drawable/stat_sys_kb_battery.xml
new file mode 100644
index 0000000..832bc3a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_kb_battery.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="4" android:drawable="@drawable/stat_sys_kb_battery_0" />
+ <item android:maxLevel="15" android:drawable="@drawable/stat_sys_kb_battery_15" />
+ <item android:maxLevel="35" android:drawable="@drawable/stat_sys_kb_battery_28" />
+ <item android:maxLevel="49" android:drawable="@drawable/stat_sys_kb_battery_43" />
+ <item android:maxLevel="60" android:drawable="@drawable/stat_sys_kb_battery_57" />
+ <item android:maxLevel="75" android:drawable="@drawable/stat_sys_kb_battery_71" />
+ <item android:maxLevel="90" android:drawable="@drawable/stat_sys_kb_battery_85" />
+ <item android:maxLevel="100" android:drawable="@drawable/stat_sys_kb_battery_100" />
+</level-list>
+
diff --git a/packages/SystemUI/res/drawable/stat_sys_kb_battery_charge.xml b/packages/SystemUI/res/drawable/stat_sys_kb_battery_charge.xml
new file mode 100644
index 0000000..300657b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_kb_battery_charge.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+ Copyright (C) 2013 The CyanogenMod 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.
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="4" android:drawable="@drawable/stat_sys_kb_battery_charge_anim0" />
+ <item android:maxLevel="15" android:drawable="@drawable/stat_sys_kb_battery_charge_anim15" />
+ <item android:maxLevel="35" android:drawable="@drawable/stat_sys_kb_battery_charge_anim28" />
+ <item android:maxLevel="49" android:drawable="@drawable/stat_sys_kb_battery_charge_anim43" />
+ <item android:maxLevel="60" android:drawable="@drawable/stat_sys_kb_battery_charge_anim57" />
+ <item android:maxLevel="75" android:drawable="@drawable/stat_sys_kb_battery_charge_anim71" />
+ <item android:maxLevel="90" android:drawable="@drawable/stat_sys_kb_battery_charge_anim85" />
+ <item android:maxLevel="100" android:drawable="@drawable/stat_sys_kb_battery_charge_anim100" />
+</level-list>
+
+
diff --git a/packages/SystemUI/res/drawable/stat_sys_kb_battery_charge_min.xml b/packages/SystemUI/res/drawable/stat_sys_kb_battery_charge_min.xml
new file mode 100644
index 0000000..d13c4ad
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_kb_battery_charge_min.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+ Copyright (C) 2013 The CyanogenMod 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.
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="4" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim0" />
+ <item android:maxLevel="15" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim15" />
+ <item android:maxLevel="35" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim28" />
+ <item android:maxLevel="49" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim43" />
+ <item android:maxLevel="60" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim57" />
+ <item android:maxLevel="75" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim71" />
+ <item android:maxLevel="90" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim85" />
+ <item android:maxLevel="100" android:drawable="@drawable/stat_sys_kb_battery_charge_min_anim100" />
+</level-list>
diff --git a/packages/SystemUI/res/drawable/stat_sys_kb_battery_min.xml b/packages/SystemUI/res/drawable/stat_sys_kb_battery_min.xml
new file mode 100644
index 0000000..68d363a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_kb_battery_min.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="4" android:drawable="@drawable/stat_sys_kb_battery_min_0" />
+ <item android:maxLevel="15" android:drawable="@drawable/stat_sys_kb_battery_min_15" />
+ <item android:maxLevel="35" android:drawable="@drawable/stat_sys_kb_battery_min_28" />
+ <item android:maxLevel="49" android:drawable="@drawable/stat_sys_kb_battery_min_43" />
+ <item android:maxLevel="60" android:drawable="@drawable/stat_sys_kb_battery_min_57" />
+ <item android:maxLevel="75" android:drawable="@drawable/stat_sys_kb_battery_min_71" />
+ <item android:maxLevel="90" android:drawable="@drawable/stat_sys_kb_battery_min_85" />
+ <item android:maxLevel="100" android:drawable="@drawable/stat_sys_kb_battery_min_100" />
+</level-list>
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index 8fdde92..360ea9b 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -51,6 +51,15 @@
</com.android.systemui.recent.RecentsHorizontalScrollView>
+ <ImageView
+ android:id="@+id/recents_clear"
+ android:clickable="true"
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ android:scaleType="center"
+ android:layout_gravity="top|right"
+ android:src="@drawable/ic_recents_clear" />
+
</FrameLayout>
<include layout="@layout/status_bar_no_recent_apps"
diff --git a/packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_land.xml b/packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_land.xml
new file mode 100644
index 0000000..40f922b
--- /dev/null
+++ b/packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_land.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/one"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="fitCenter"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_weight="1"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/mid_nav_buttons"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_horizontal"
+ android:animateLayoutChanges="true">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/two"
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/three"
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/four"
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/five"
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ </LinearLayout>
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/six"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="fitCenter"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_port.xml b/packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_port.xml
new file mode 100644
index 0000000..3145018
--- /dev/null
+++ b/packages/SystemUI/res/layout-sw600dp/mid_navigation_bar_port.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/one"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="fitCenter"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_weight="1"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/mid_nav_buttons"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_horizontal"
+ android:animateLayoutChanges="true">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/two"
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/three"
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/four"
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/five"
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ </LinearLayout>
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/six"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="fitCenter"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
index b1104cc..c6c56d2 100644
--- a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
@@ -36,109 +36,63 @@
android:orientation="horizontal"
android:clipChildren="false"
android:clipToPadding="false"
- android:id="@+id/nav_buttons"
- android:animateLayoutChanges="true"
+ android:id="@+id/container"
>
-
- <!-- navigation controls -->
- <View
- android:layout_width="48dp"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:layout_marginLeft="2dp"
- android:visibility="invisible"
- />
- <Space
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_back"
- systemui:keyCode="4"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_back"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_home"
- systemui:keyCode="3"
- systemui:keyRepeat="true"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_home"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_recent"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_recent"
- />
- <Space
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_width="48dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_menu"
- android:layout_marginRight="2dp"
- systemui:keyCode="82"
- android:layout_weight="0"
- android:visibility="invisible"
- android:contentDescription="@string/accessibility_menu"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- />
+ <include layout="@layout/mid_navigation_bar_port"/>
</LinearLayout>
- <!-- lights out layout to match exactly -->
- <LinearLayout
+ <LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
- android:id="@+id/lights_out"
- android:visibility="gone"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_horizontal"
>
- <Space
- android:layout_width="match_parent"
+ <View
+ android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <ImageView
- android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_weight="1" />
+ <!-- lights out layout to match exactly -->
+ <LinearLayout
android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:gravity="center_horizontal"
android:layout_marginLeft="40dp"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
- android:scaleType="center"
- android:layout_weight="0"
- />
- <ImageView
- android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_lights_out_dot_large"
- android:scaleType="center"
- android:layout_weight="0"
- />
- <ImageView
- android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
android:layout_marginRight="40dp"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/lights_out"
+ android:visibility="gone">
+ <ImageView
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <ImageView
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <ImageView
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <ImageView
+ android:layout_width="128dp" android:paddingLeft="25dp" android:paddingRight="25dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ </LinearLayout>
+ <View
+ android:layout_width="0dp"
android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
- android:scaleType="center"
- android:layout_weight="0"
- />
- <Space
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
+ android:layout_weight="1" />
</LinearLayout>
<com.android.systemui.statusbar.policy.KeyButtonView
@@ -175,111 +129,70 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_horizontal"
android:clipChildren="false"
android:clipToPadding="false"
- android:id="@+id/nav_buttons"
- android:animateLayoutChanges="true"
+ android:id="@+id/container"
>
-
- <!-- navigation controls -->
- <View
- android:layout_width="48dp"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:layout_marginLeft="2dp"
- android:visibility="invisible"
- />
- <Space
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_back"
- systemui:keyCode="4"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_back"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_home"
- systemui:keyCode="3"
- systemui:keyRepeat="true"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_home"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_recent"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_recent"
- />
- <Space
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_width="48dp"
- android:layout_height="match_parent"
- android:layout_marginRight="2dp"
- android:src="@drawable/ic_sysbar_menu"
- systemui:keyCode="82"
- android:layout_weight="0"
- android:visibility="invisible"
- android:contentDescription="@string/accessibility_menu"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- />
+ <include layout="@layout/mid_navigation_bar_land"/>
</LinearLayout>
- <!-- lights out layout to match exactly -->
+ <!-- lights out layout to match exactly -->
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
- android:id="@+id/lights_out"
- android:visibility="gone"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_horizontal"
+ android:visibility="visible"
>
- <Space
- android:layout_width="match_parent"
+ <View
+ android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="1"
- />
- <ImageView
- android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_weight="1" />
+ <!-- lights out layout to match exactly -->
+ <LinearLayout
android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_horizontal"
android:layout_marginLeft="40dp"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
- android:scaleType="center"
- android:layout_weight="0"
- />
- <ImageView
- android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_lights_out_dot_large"
- android:scaleType="center"
- android:layout_weight="0"
- />
- <ImageView
- android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
android:layout_marginRight="40dp"
+ android:id="@+id/lights_out"
+ android:visibility="gone"
+ >
+ <ImageView
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <ImageView
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <ImageView
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <ImageView
+ android:layout_width="162dp" android:paddingLeft="42dp" android:paddingRight="42dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ </LinearLayout>
+ <View
+ android:layout_width="0dp"
android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
- android:scaleType="center"
- android:layout_weight="0"
- />
- <Space
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- />
+ android:layout_weight="1" />
</LinearLayout>
<com.android.systemui.statusbar.policy.KeyButtonView
diff --git a/packages/SystemUI/res/layout/mid_navigation_bar_land.xml b/packages/SystemUI/res/layout/mid_navigation_bar_land.xml
new file mode 100644
index 0000000..fde84e2
--- /dev/null
+++ b/packages/SystemUI/res/layout/mid_navigation_bar_land.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/one"
+ android:layout_height="40dp"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:clipChildren="false"
+ android:gravity="center_vertical"
+ android:id="@+id/mid_nav_buttons"
+ android:layout_gravity="center_vertical"
+ android:clipToPadding="false"
+ android:animateLayoutChanges="true">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/two"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
+ <View
+ android:layout_height="0dp"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/three"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
+ <View
+ android:layout_height="0dp"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/four"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
+ <View
+ android:layout_height="0dp"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/five"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
+ </LinearLayout>
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/six"
+ android:layout_height="40dp"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/mid_navigation_bar_port.xml b/packages/SystemUI/res/layout/mid_navigation_bar_port.xml
new file mode 100644
index 0000000..1778fa6
--- /dev/null
+++ b/packages/SystemUI/res/layout/mid_navigation_bar_port.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/one"
+ android:layout_width="40dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="fitCenter"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/mid_nav_buttons"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_horizontal"
+ android:animateLayoutChanges="true">
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/two"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/three"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ systemui:keyRepeat="true"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/four"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/five"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ systemui:keyRepeat="true"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ </LinearLayout>
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/six"
+ android:layout_width="40dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="fitCenter"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index da52d89..f9a4c4d 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -37,67 +37,9 @@
android:orientation="horizontal"
android:clipChildren="false"
android:clipToPadding="false"
- android:id="@+id/nav_buttons"
- android:animateLayoutChanges="true"
+ android:id="@+id/container"
>
-
- <!-- navigation controls -->
- <View
- android:layout_width="40dp"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:visibility="invisible"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="@dimen/navigation_key_width"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_back"
- systemui:keyCode="4"
- android:layout_weight="0"
- android:scaleType="center"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_back"
- />
- <View
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:visibility="invisible"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_width="@dimen/navigation_key_width"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_home"
- systemui:keyCode="3"
- systemui:keyRepeat="false"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_home"
- />
- <View
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:visibility="invisible"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_width="@dimen/navigation_key_width"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_recent"
- android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- android:contentDescription="@string/accessibility_recent"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_width="@dimen/navigation_menu_key_width"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_menu"
- systemui:keyCode="82"
- android:layout_weight="0"
- android:visibility="invisible"
- android:contentDescription="@string/accessibility_menu"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- />
+ <include layout="@layout/mid_navigation_bar_port"/>
</LinearLayout>
<!-- lights out layout to match exactly -->
@@ -105,19 +47,21 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
+ android:gravity="center_horizontal"
+ android:layout_marginLeft="40dp"
+ android:layout_marginRight="40dp"
+ android:layout_gravity="center_horizontal"
android:id="@+id/lights_out"
android:visibility="gone"
>
<ImageView
android:layout_width="80dp"
android:layout_height="match_parent"
- android:layout_marginLeft="40dp"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
android:scaleType="center"
- android:layout_weight="0"
/>
- <View
- android:layout_width="match_parent"
+ <View
+ android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:visibility="invisible"
@@ -127,21 +71,30 @@
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_lights_out_dot_large"
android:scaleType="center"
- android:layout_weight="0"
/>
- <View
- android:layout_width="match_parent"
+ <View
+ android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:visibility="invisible"
/>
<ImageView
android:layout_width="80dp"
- android:layout_marginRight="40dp"
android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ android:layout_weight="1"
+ />
+ <ImageView
+ android:layout_width="80dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
android:scaleType="center"
- android:layout_weight="0"
/>
</LinearLayout>
@@ -179,69 +132,13 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:layout_gravity="center_vertical"
android:clipChildren="false"
android:clipToPadding="false"
- android:id="@+id/nav_buttons"
- android:animateLayoutChanges="true"
+ android:id="@+id/container"
>
-
- <!-- navigation controls -->
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_height="40dp"
- android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_menu_land"
- systemui:keyCode="82"
- android:layout_weight="0"
- android:visibility="invisible"
- android:contentDescription="@string/accessibility_menu"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_height="80dp"
- android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_recent_land"
- android:layout_weight="0"
- android:contentDescription="@string/accessibility_recent"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
- />
- <View
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_weight="1"
- android:visibility="invisible"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_height="80dp"
- android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_home_land"
- systemui:keyCode="3"
- systemui:keyRepeat="false"
- android:layout_weight="0"
- android:contentDescription="@string/accessibility_home"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
- />
- <View
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_weight="1"
- android:visibility="invisible"
- />
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_height="80dp"
- android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_back_land"
- android:scaleType="center"
- systemui:keyCode="4"
- android:layout_weight="0"
- android:contentDescription="@string/accessibility_back"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
- />
- <View
- android:layout_height="40dp"
- android:layout_width="match_parent"
- android:layout_weight="0"
- android:visibility="invisible"
- />
+ <include layout="@layout/mid_navigation_bar_land"/>
</LinearLayout>
<!-- lights out layout to match exactly -->
@@ -249,19 +146,21 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:layout_gravity="center_vertical"
+ android:layout_marginTop="40dp"
+ android:layout_marginBottom="40dp"
android:id="@+id/lights_out"
android:visibility="gone"
>
<ImageView
android:layout_height="80dp"
- android:layout_marginTop="40dp"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
android:scaleType="center"
- android:layout_weight="0"
/>
- <View
- android:layout_height="match_parent"
+ <View
+ android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:visibility="invisible"
@@ -271,21 +170,30 @@
android:layout_width="match_parent"
android:src="@drawable/ic_sysbar_lights_out_dot_large"
android:scaleType="center"
- android:layout_weight="0"
/>
- <View
- android:layout_height="match_parent"
+ <View
+ android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:visibility="invisible"
/>
<ImageView
android:layout_height="80dp"
- android:layout_marginBottom="40dp"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:visibility="invisible"
+ android:layout_weight="1"
+ />
+ <ImageView
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
android:scaleType="center"
- android:layout_weight="0"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/power_widget_button.xml b/packages/SystemUI/res/layout/power_widget_button.xml
new file mode 100644
index 0000000..4b1d5bd1
--- /dev/null
+++ b/packages/SystemUI/res/layout/power_widget_button.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/power_widget_button"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:background="@drawable/stat_power_background">
+
+ <ImageView
+ android:id="@+id/power_widget_button_image"
+ android:layout_width="match_parent"
+ android:layout_height="48dip"
+ android:layout_weight="1"
+ android:scaleType="center" />
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_generic.xml b/packages/SystemUI/res/layout/quick_settings_tile_generic.xml
new file mode 100644
index 0000000..374660d
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings_tile_generic.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/TextAppearance.QuickSettings.TileView"
+ android:id="@+id/tile_textview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center"
+ /> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/signal_cluster_text_view.xml b/packages/SystemUI/res/layout/signal_cluster_text_view.xml
new file mode 100644
index 0000000..44c94fb
--- /dev/null
+++ b/packages/SystemUI/res/layout/signal_cluster_text_view.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.systemui.statusbar.SignalClusterTextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="horizontal"
+ >
+ <LinearLayout
+ android:id="@+id/mobile_signal_text_combo"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:layout_marginRight="-3dip"
+ >
+ <TextView
+ android:id="@+id/mobile_signal_text"
+ android:textAppearance="@style/TextAppearance.StatusBar.Signal"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:layout_marginRight="-3dip"
+ android:gravity="center_vertical|left"
+ />
+ <ImageView
+ android:id="@+id/mobile_signal_text_icon"
+ android:src="@drawable/stat_sys_signal_min"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginLeft="1dip"
+ android:paddingRight="2dip"
+ />
+ </LinearLayout>
+</com.android.systemui.statusbar.SignalClusterTextView> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index bf20e9d..deada5d 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -24,7 +24,8 @@
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/status_bar"
android:background="@drawable/status_bar_background"
- android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:focusable="true"
android:descendantFocusability="afterDescendants"
android:fitsSystemWindows="true"
@@ -76,7 +77,7 @@
android:layout_height="match_parent"
android:orientation="horizontal">
- <LinearLayout android:id="@+id/statusIcons"
+ <LinearLayout android:id="@+id/statusIcons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
@@ -95,14 +96,63 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
+ <include layout="@layout/signal_cluster_text_view"
+ android:id="@+id/signal_cluster_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
+ <TextView
+ android:id="@+id/dock_battery_text"
+ android:textAppearance="@style/TextAppearance.StatusBar.Battery"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:paddingLeft="@dimen/status_bar_battery_cluster_padding"
+ android:layout_marginRight="@dimen/status_bar_battery_cluster_text_margin"
+ android:gravity="center_vertical|left"
+ />
+ <ImageView
+ android:id="@+id/dock_battery"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:paddingLeft="@dimen/status_bar_battery_cluster_padding"
+ />
+ <com.android.systemui.statusbar.policy.CircleDockBattery
+ android:id="@+id/circle_dock_battery"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.StatusBar.Battery"
+ android:singleLine="true"
+ android:gravity="bottom"
+ android:paddingLeft="@dimen/status_bar_battery_cluster_padding"
+ />
+ <TextView
+ android:id="@+id/battery_text"
+ android:textAppearance="@style/TextAppearance.StatusBar.Battery"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:paddingLeft="@dimen/status_bar_battery_cluster_padding"
+ android:layout_marginRight="@dimen/status_bar_battery_cluster_text_margin"
+ android:gravity="left|center_vertical"
+ />
<ImageView
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:paddingLeft="4dip"
+ android:paddingLeft="@dimen/status_bar_battery_cluster_padding"
+ />
+ <com.android.systemui.statusbar.policy.CircleBattery
+ android:id="@+id/circle_battery"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.StatusBar.Battery"
+ android:singleLine="true"
+ android:gravity="bottom"
+ android:paddingLeft="@dimen/status_bar_battery_cluster_padding"
/>
</LinearLayout>
-
+
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
@@ -111,10 +161,11 @@
android:singleLine="true"
android:paddingLeft="6dip"
android:gravity="center_vertical|left"
+ android:clickable="false"
/>
</LinearLayout>
</LinearLayout>
-
+
<LinearLayout android:id="@+id/ticker"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index b71025e..06e7bd4 100644..100755
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -58,6 +58,14 @@
android:layout_height="@dimen/notification_panel_header_height"
/>
+ <com.android.systemui.statusbar.powerwidget.PowerWidget
+ android:id="@+id/exp_power_stat"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_panel_widget_height"
+ android:layout_marginTop="2dip"
+ android:visibility="gone"
+ />
+
<TextView
android:id="@+id/emergency_calls_only"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 556210e..e8ceeed 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -43,15 +43,15 @@
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
android:layout_centerVertical="true"
+ android:clickable="true"
/>
<com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
android:layout_toRightOf="@id/clock"
- android:layout_alignBaseline="@id/clock"
+ android:layout_centerVertical="true"
/>
</RelativeLayout>
@@ -79,7 +79,6 @@
android:layout_height="50dp"
android:scaleType="center"
android:src="@drawable/ic_notify_clear"
- android:background="@drawable/ic_notify_button_bg"
android:contentDescription="@string/accessibility_clear_all"
/>
@@ -93,7 +92,6 @@
android:layout_height="50dp"
android:scaleType="center"
android:src="@drawable/ic_notify_settings"
- android:background="@drawable/ic_notify_button_bg"
android:contentDescription="@string/accessibility_desc_quick_settings"
/>
<ImageView android:id="@+id/notification_button"
@@ -101,7 +99,6 @@
android:layout_height="50dp"
android:scaleType="center"
android:src="@drawable/ic_notifications"
- android:background="@drawable/ic_notify_button_bg"
android:visibility="gone"
android:contentDescription="@string/accessibility_notifications_button"
/>
diff --git a/packages/SystemUI/res/layout/status_bar_recent_panel.xml b/packages/SystemUI/res/layout/status_bar_recent_panel.xml
index 7335f86..8832fc8 100644
--- a/packages/SystemUI/res/layout/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout/status_bar_recent_panel.xml
@@ -57,6 +57,15 @@
</com.android.systemui.recent.RecentsVerticalScrollView>
+ <ImageView
+ android:id="@+id/recents_clear"
+ android:clickable="true"
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ android:scaleType="center"
+ android:layout_gravity="top|right"
+ android:src="@drawable/ic_recents_clear" />
+
</FrameLayout>
<include layout="@layout/status_bar_no_recent_apps"
diff --git a/packages/SystemUI/res/layout/system_bar_notification_area.xml b/packages/SystemUI/res/layout/system_bar_notification_area.xml
index a59dad2..6bbf9c1 100644
--- a/packages/SystemUI/res/layout/system_bar_notification_area.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_area.xml
@@ -87,6 +87,7 @@
android:paddingLeft="6dip"
android:layout_marginRight="8dip"
android:gravity="center_vertical|left"
+ android:clickable="false"
/>
<TextView
@@ -122,6 +123,14 @@
android:paddingLeft="4dip"
android:visibility="gone"
/>
+ <com.android.systemui.statusbar.policy.CircleBattery
+ android:id="@+id/dock_circle_battery"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:paddingLeft="4dip"
+ android:gravity="center_vertical|left"
+ />
<ImageView
android:id="@+id/battery"
android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
index 59544f4..9768ca9 100644
--- a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
@@ -153,6 +153,15 @@
android:text="@string/status_bar_settings_settings_button"
/>
+ <com.android.systemui.statusbar.policy.CircleBattery
+ android:id="@+id/panel_circle_battery"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:paddingLeft="6dp"
+ android:layout_gravity="center_vertical"
+ />
+
<!-- this will stretch to eat up available space -->
<View
android:layout_width="0dp"
@@ -202,7 +211,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:textAppearance="@style/TextAppearance.SystemBar.Expanded.Clock"
+ android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
+ android:clickable="true"
/>
<com.android.systemui.statusbar.policy.DateView
diff --git a/packages/SystemUI/res/layout/system_bar_recent_panel.xml b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
index 3951bba..b3626b9 100644
--- a/packages/SystemUI/res/layout/system_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
@@ -61,6 +61,15 @@
</com.android.systemui.recent.RecentsVerticalScrollView>
+ <ImageView
+ android:id="@+id/recents_clear"
+ android:clickable="true"
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ android:scaleType="center"
+ android:layout_gravity="bottom|left"
+ android:src="@drawable/ic_recents_clear" />
+
<include layout="@layout/system_bar_no_recent_apps"
android:id="@+id/recents_no_apps"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index a623612..d22f3c7 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright (c) 2009, The Android Open Source Project
@@ -17,20 +17,23 @@
*/
-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="7164937344850004466">"UI systému"</string>
+
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Vymazat"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Nerušit"</string>
- <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Zobrazit upozornění"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Zobrazit oznámení"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Odebrat ze seznamu"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informace o aplikaci"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Žádné nové aplikace"</string>
<string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Zavřít nové aplikace"</string>
- <plurals name="status_bar_accessibility_recent_apps">
- <item quantity="one" msgid="5854176083865845541">"1 nová aplikace"</item>
- <item quantity="other" msgid="1040784359794890744">"nové aplikace: %d"</item>
- </plurals>
+
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 nová aplikace"</item>
+ <item quantity="few">"%d nové aplikace"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d nových aplikací"</item>
+ </plurals>
+
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žádná oznámení"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Probíhající"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Oznámení"</string>
@@ -39,50 +42,60 @@
<string name="battery_low_percent_format" msgid="1077244949318261761">"Zbývá <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Nabíjení pomocí rozhraní USB není podporováno."\n"Používejte pouze nabíječku, která byla dodána se zařízením."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Využití baterie"</string>
+
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavení"</string>
- <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WiFi"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"Režim V letadle"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Autom. otočení obrazovky"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ZTLUM."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Oznámení"</string>
+
<string name="bluetooth_tethered" msgid="7094101612161133267">"Datové připojení Bluetooth se sdílí"</string>
+
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavit metody zadávání"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fyzická klávesnice"</string>
- <string name="usb_device_permission_prompt" msgid="834698001271562057">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k perifernímu zařízení USB?"</string>
+
+ <string name="usb_device_permission_prompt" msgid="834698001271562057">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přistupovat k zařízení USB?"</string>
+ <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístupovat k perifernímu zařízení USB?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete při připojení tohoto zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Chcete při připojení tohoto periferního zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
- <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Žádná nainstalovaná aplikace s tímto zařízením USB nepracuje. Info. najdete na <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Žádná nainstalovaná aplikace s tímto zařízením USB nepracuje. Více na <xliff:g id="URL">%1$s</xliff:g>"</string>
+
<string name="title_usb_accessory" msgid="4966265263465181372">"Periferní zařízení USB"</string>
<string name="label_view" msgid="6304565553218192990">"Zobrazit"</string>
<string name="always_use_device" msgid="1450287437017315906">"Pro toto zařízení USB použít jako výchozí"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Pro toto periferní zařízení USB použít jako výchozí"</string>
+
<string name="usb_debugging_title" msgid="4513918393387141949">"Povolit ladění USB?"</string>
<string name="usb_debugging_message" msgid="2220143855912376496">"Digitální otisk RSA počítače je:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Vždy povolit z tohoto počítače"</string>
+
<string name="compat_mode_on" msgid="6623839244840638213">"Přiblížit na celou obrazovku"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Na celou obrazovku"</string>
<string name="compat_mode_help_header" msgid="7969493989397529910">"Úprava velikosti z důvodu kompatibility"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Pokud je aplikace navržena pro menší obrazovku, zobrazí se vedle hodin ovládací prvek přiblížení."</string>
- <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Ukládání snímku obrazovky..."</string>
- <string name="screenshot_saving_title" msgid="8242282144535555697">"Ukládání snímku obrazovky..."</string>
+
+ <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Ukládání snímku obrazovky\u2026"</string>
+ <string name="screenshot_saving_title" msgid="8242282144535555697">"Ukládání snímku obrazovky\u2026"</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"Probíhá ukládání snímku obrazovky."</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímek obrazovky zachycen."</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímek obrazovky uložen."</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Snímek obrazovky zobrazíte dotykem."</string>
- <string name="screenshot_failed_title" msgid="705781116746922771">"Snímek obrazovky se nepodařilo zachytit."</string>
- <string name="screenshot_failed_text" msgid="8134011269572415402">"Snímek obrazovky se nepodařilo uložit. Je možné, že je externí úložiště právě používáno."</string>
+ <string name="screenshot_failed_title" msgid="705781116746922771">"Snímek obrazovky se nepodařilo uložit."</string>
+ <string name="screenshot_failed_text" msgid="8134011269572415402">"Snímek obrazovky se nepodařilo uložit. Je možné, že je úložiště právě používáno."</string>
+
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti přenosu souborů pomocí rozhraní USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Připojit jako přehrávač médií (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Připojit jako fotoaparát (PTP)"</string>
<string name="installer_cd_button_title" msgid="2312667578562201583">"Instalovat aplikaci Android File Transfer pro Mac"</string>
+
<string name="accessibility_back" msgid="567011538994429120">"Zpět"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Domů"</string>
- <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Nabídka"</string>
<string name="accessibility_recent" msgid="8571350598987952883">"Nové aplikace"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačítko přepnutí metody zadávání"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačítko úpravy velikosti z důvodu kompatibility"</string>
- <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zvětšit menší obrázek na větší obrazovku."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zvětšit menší obraz na větší obrazovku."</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Rozhraní Bluetooth je připojeno."</string>
<string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Rozhraní Bluetooth je odpojeno."</string>
<string name="accessibility_no_battery" msgid="358343022352820946">"Chybí baterie."</string>
@@ -100,12 +113,12 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dvě čárky signálu datové sítě."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tři čárky signálu datové sítě."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Plný signál datové sítě."</string>
- <string name="accessibility_wifi_off" msgid="3177380296697933627">"Síť Wi-Fi je vypnuta."</string>
- <string name="accessibility_no_wifi" msgid="1425476551827924474">"Síť Wi-Fi odpojena."</string>
- <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Jedna čárka signálu sítě Wi-Fi."</string>
- <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Dvě čárky signálu sítě Wi-Fi."</string>
- <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Tři čárky signálu sítě Wi-Fi."</string>
- <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Plný signál sítě Wi-Fi."</string>
+ <string name="accessibility_wifi_off" msgid="3177380296697933627">"Síť WiFi je vypnuta."</string>
+ <string name="accessibility_no_wifi" msgid="1425476551827924474">"Síť WiFi odpojena."</string>
+ <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Jedna čárka signálu sítě WiFi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Dvě čárky signálu sítě WiFi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Tři čárky signálu sítě WiFi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Plný signál sítě WiFi."</string>
<string name="accessibility_no_wimax" msgid="4329180129727630368">"Žádný signál sítě WiMAX."</string>
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Jedna čárka signálu sítě WiMAX."</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Dvě čárky signálu sítě WiMAX."</string>
@@ -130,13 +143,11 @@
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Roaming"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
+ <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Žádná SIM karta."</string>
- <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering přes Bluetooth."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Sdílené připojení Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim V letadle."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level">Baterie: <xliff:g id="number">%d</xliff:g> procent.</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Systémová nastavení."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Oznámení."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Vymazat oznámení."</string>
@@ -146,7 +157,7 @@
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibrační vyzvánění."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tiché vyzvánění."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikace <xliff:g id="APP">%s</xliff:g> byla odebrána."</string>
- <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Oznámení je zavřeno."</string>
+ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Oznámení odstraněno."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Panel oznámení."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Rychlé nastavení."</string>
<string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Naposledy použité aplikace"</string>
@@ -157,27 +168,41 @@
<string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Režim V letadle: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Budík je nastaven na <xliff:g id="TIME">%s</xliff:g>."</string>
+
+ <string name="accessibility_quick_settings_ringer">Zvuk <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Vibrace <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datové přenosy 2G a 3G jsou zakázány"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datové přenosy 4G jsou zakázány"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilní data jsou zakázána"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Přenos dat vypnut"</string>
<string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosáhli jste stanoveného limitu využití dat."\n\n"Chcete-li datové připojení znovu zapnout, operátor vám může účtovat poplatky."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Znovu povolit data"</string>
+
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Žádné přip. k internetu"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: připojeno"</string>
+ <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WiFi: připojeno"</string>
+
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhledávání satelitů GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavena pomocí systému GPS"</string>
- <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazat všechna oznámení."</string>
+
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Odstranit všechna oznámení."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informace o aplikaci"</string>
<string name="close_universe" msgid="3736513750241754348">"Zavřít"</string>
+
<string name="notifications_off_title" msgid="8936620513608443224">"Oznámení jsou vypnuta"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Chcete-li oznámení znovu zapnout, klepněte sem."</string>
+
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka se automaticky otočí."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Obrazovka je uzamčena v orientaci na šířku."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Obrazovka je uzamčena v orientaci na výšku."</string>
+
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
- <string name="start_dreams" msgid="7219575858348719790">"Spořič obrazovky"</string>
+ <string name="bean_dream_settings_cid_title">Použít hlavu CIDa</string>
+ <string name="bean_dream_settings_cid_summary">Použít hlavu CIDa místo sladkých želé fazolí</string>
+ <string name="start_dreams" msgid="7219575858348719790">"Spustit spořič"</string>
+
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Režim V letadle"</string>
<string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Nabíjení, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Nabito"</string>
@@ -195,14 +220,52 @@
<string name="quick_settings_settings_label" msgid="5326556592578065401">"Nastavení"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"Doba"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"Já"</string>
- <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+ <string name="quick_settings_wifi_label" msgid="9135344704899546041">"WiFi"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nepřipojeno"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Žádná síť"</string>
- <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi vypnuta"</string>
- <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Displej přes Wi-Fi"</string>
- <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrátový displej"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WiFi vypnuté"</string>
+ <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Zobrazení přes WiFi"</string>
+ <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrátové zobrazování"</string>
+ <string name="quick_settings_profile_label">Profil</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
+
<string name="status_bar_help_title" msgid="1199237744086469217">"Zde se zobrazují oznámení"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Můžete je kdykoli zobrazit tím, že přejedete prstem dolů."\n"Přejedete-li prstem dolů ještě jednou, zobrazí se ovládací prvky systému."</string>
+
+ <string name="powerwidget_screen_timeout_toast">Vypnutí obrazovky nastaveno na: %1$d %2$s</string>
+
+ <string name="quick_settings_gps_off">GPS vyp.</string>
+ <string name="quick_settings_screen_sleep">Uspat</string>
+ <string name="quick_settings_ringer_on">Zvuk zap.</string>
+ <string name="quick_settings_ringer_off">Zvuk vyp.</string>
+ <string name="quick_settings_vibration_on">Vibrace zap.</string>
+ <string name="quick_settings_vibration_off">Vibrace vyp.</string>
+ <string name="quick_settings_label_enabled">Zap.</string>
+ <string name="quick_settings_label_disabled">Vyp.</string>
+ <string name="quick_settings_ringer_normal">Zvuk</string>
+ <string name="quick_settings_lockscreen">Zámek obrazovky</string>
+ <string name="quick_settings_network_type">Režim sítě</string>
+ <string name="quick_settings_report_bug">Ohlásit chybu</string>
+ <string name="quick_settings_sync">Synch.</string>
+ <string name="quick_settings_torch">Svítilna</string>
+ <string name="quick_settings_torch_off">Svítilna zap.</string>
+ <string name="quick_settings_screen_timeout">Režim spánku</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+ <string name="quick_settings_usb_tether_off_label">Odpojeno</string>
+ <string name="quick_settings_usb_tether_connected_label">USB sdíl. vyp.</string>
+ <string name="quick_settings_usb_tether_on_label">USB sdíl.</string>
+ <string name="quick_settings_wifiap">WiFi AP</string>
+ <string name="quick_settings_wifiap_off">WiFi AP vyp.</string>
+
+ <string name="navbar_dialog_title">Vybrat akci k přiřazení</string>
+ <string name="navbar_home_button">Tlačítko Domů</string>
+ <string name="navbar_recent_button">Tlačítko Nedávné</string>
+ <string name="navbar_search_button">Tlačítko Hledat</string>
+ <string name="navbar_back_button">Tlačítko Zpět</string>
+ <string name="navbar_empty_button">Prázdné tlačítko</string>
+ <string name="navbar_menu_conditional_button">Tlačítko (skrývat) Nabídka</string>
+ <string name="navbar_menu_always_button">Tlačítko (vždy zobrazit) Nabídka</string>
+ <string name="navbar_menu_big_button">Tlačítko Nabídka</string>
+
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 7f7a51c..1eabcb7 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -203,4 +203,53 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Underretninger vises her"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Få adgang til dem når som helst ved at stryge ned."\n"Stryg ned igen for at komme til systemindstillingerne."</string>
+
+ <!-- CYANOGENMOD ADDITIONS -->
+ <string name="accessibility_quick_settings_ringer">Lyd <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Vibration <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+
+ <string name="bean_dream_settings_cid_title">Brug CID-hoved</string>
+ <string name="bean_dream_settings_cid_summary">Brug CID-hoved i stedet for jellybean inden i drømmen</string>
+
+ <!-- QuickSettings: Profile [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_profile_label">Profil</string>
+
+ <string name="powerwidget_screen_timeout_toast">Skærm-timeout sat til: %1$d %2$s</string>
+
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS slået fra</string>
+ <string name="quick_settings_screen_sleep">Gå i dvale</string>
+ <string name="quick_settings_ringer_on">Lyd slået til</string>
+ <string name="quick_settings_ringer_off">Lyd slået fra</string>
+ <string name="quick_settings_vibration_on">Vibration slået til</string>
+ <string name="quick_settings_vibration_off">Vibration slået fra</string>
+ <string name="quick_settings_label_enabled">Slået til</string>
+ <string name="quick_settings_label_disabled">Slået fra</string>
+ <string name="quick_settings_ringer_normal">Lyd</string>
+ <string name="quick_settings_lockscreen">Skærmlås</string>
+ <string name="quick_settings_network_type">Netværkstilstand</string>
+ <string name="quick_settings_report_bug">Rapportér fejl</string>
+ <string name="quick_settings_sync">Synkr.</string>
+ <string name="quick_settings_torch">Lommelygte</string>
+ <string name="quick_settings_torch_off">Lommelygte slået fra</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_screen_timeout">Timeout</string>
+ <string name="quick_settings_usb_tether_off_label">Afbrudt</string>
+ <string name="quick_settings_usb_tether_connected_label">Tethering slået fra</string>
+ <string name="quick_settings_usb_tether_on_label">Tethering</string>
+ <string name="quick_settings_wifiap">Wi-Fi AP</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi AP slået fra</string>
+
+ <!-- Dialog title for navigation bar button selection -->
+ <string name="navbar_dialog_title">Vælg handling at tildele</string>
+ <string name="navbar_home_button">Startknap</string>
+ <string name="navbar_recent_button">Seneste-knap</string>
+ <string name="navbar_search_button">Søgeknap</string>
+ <string name="navbar_back_button">Tilbageknap</string>
+ <string name="navbar_empty_button">Tom knap</string>
+ <string name="navbar_menu_conditional_button">Menuknap (auto-skjul)</string>
+ <string name="navbar_menu_always_button">Menuknap (vis altid)</string>
+ <string name="navbar_menu_big_button">Menuknap</string>
+
+ <!-- CYANOGENMOD ADDITIONS END -->
</resources>
diff --git a/packages/SystemUI/res/values-de-large/strings.xml b/packages/SystemUI/res/values-de-large/strings.xml
index 68d80a6..f52e1cb 100644
--- a/packages/SystemUI/res/values-de-large/strings.xml
+++ b/packages/SystemUI/res/values-de-large/strings.xml
@@ -1,25 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- -->
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Löschen"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Benachrichtigungen aus"</string>
- <string name="notifications_off_text" msgid="1439152806320786912">"Tippen Sie hier, um die Benachrichtigungen wieder zu aktivieren."</string>
+ <string name="notifications_off_text" msgid="1439152806320786912">"Tippen, um die Benachrichtigungen wieder zu aktivieren."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 2b226b6..4d07d50 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1,21 +1,19 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/**
- * Copyright (c) 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- -->
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+ Copyright (C) 2013 The CyanogenMod 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 xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
@@ -27,10 +25,10 @@
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-Info"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Keine kürzlich geöffneten Apps"</string>
<string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Kürzlich geöffnete Apps schließen"</string>
- <plurals name="status_bar_accessibility_recent_apps">
- <item quantity="one" msgid="5854176083865845541">"1 kürzlich geöffnete App"</item>
- <item quantity="other" msgid="1040784359794890744">"%d kürzlich geöffnete Apps"</item>
- </plurals>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 kürzlich geöffnete App"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d kürzlich geöffnete Apps"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Keine Benachrichtigungen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktuell"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Benachrichtigungen"</string>
@@ -65,9 +63,9 @@
<string name="compat_mode_off" msgid="4434467572461327898">"Auf Bildschirmgröße anpassen"</string>
<string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitätszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Wenn eine App für einen kleineren Bildschirm ausgelegt ist, wird ein Zoom-Steuerelement neben der Uhr angezeigt."</string>
- <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Screenshot wird gespeichert..."</string>
- <string name="screenshot_saving_title" msgid="8242282144535555697">"Screenshot wird gespeichert..."</string>
- <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot wird gespeichert..."</string>
+ <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Screenshot wird gespeichert\u2026"</string>
+ <string name="screenshot_saving_title" msgid="8242282144535555697">"Screenshot wird gespeichert\u2026"</string>
+ <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot wird gespeichert\u2026"</string>
<string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot aufgenommen"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Zum Ansehen berühren"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot konnte nicht aufgenommen werden."</string>
@@ -185,8 +183,8 @@
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> Geräte)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth aus"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"Helligkeit"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Autom. drehen"</string>
- <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Drehung gesperrt"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatisch"</string>
+ <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Gesperrt"</string>
<string name="quick_settings_ime_label" msgid="7073463064369468429">"Eingabemethode"</string>
<string name="quick_settings_location_label" msgid="3292451598267467545">"Verwendeter Standort"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Mediengerät"</string>
@@ -201,8 +199,52 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WLAN aus"</string>
<string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"WLAN-Display"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Kabellose Übertragung"</string>
+ <!-- QuickSettings: Profile [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_profile_label">Profile</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helligkeit"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Benachrichtigungen erscheinen hier"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Greifen Sie jederzeit auf sie zu, indem Sie nach unten wischen."\n"Wischen Sie für Systemeinstellungen erneut nach unten."</string>
+
+ <!-- **** CYANOGENMOD ADDITIONS START **** -->
+
+ <!-- Screen timeout toast -->
+ <string name="powerwidget_screen_timeout_toast">Bildschirmsperre nach: %1$d %2$s</string>
+
+ <!-- Quick settings -->
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS aus</string>
+ <string name="quick_settings_screen_sleep">Standby</string>
+ <string name="quick_settings_label_enabled">An</string>
+ <string name="quick_settings_label_disabled">Aus</string>
+ <string name="quick_settings_ringer_normal">Klingelmodus</string>
+ <string name="quick_settings_lockscreen">Sperren</string>
+ <string name="quick_settings_network_type">Netzmodus</string>
+ <string name="quick_settings_report_bug">Fehlerprotokollierung</string>
+ <string name="quick_settings_sync">Sync</string>
+ <string name="quick_settings_sync_off">Sync aus</string>
+ <string name="quick_settings_torch">Lampe</string>
+ <string name="quick_settings_torch_off">Lampe aus</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_nfc_off">NFC aus</string>
+ <string name="quick_settings_screen_timeout">Timeout</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+ <string name="quick_settings_usb_tether_off_label">Getrennt</string>
+ <string name="quick_settings_usb_tether_connected_label">Tethering aus</string>
+ <string name="quick_settings_usb_tether_on_label">Tethering</string>
+ <string name="quick_settings_wifiap">Hotspot</string>
+ <string name="quick_settings_wifiap_off">Hotspot aus</string>
+
+ <!-- Dialog title for navigation bar button selection -->
+ <string name="navbar_dialog_title">Funktion zuweisen</string>
+ <string name="navbar_home_button">Home</string>
+ <string name="navbar_recent_button">Zuletzt verwendet</string>
+ <string name="navbar_search_button">Suche</string>
+ <string name="navbar_back_button">Zurück</string>
+ <string name="navbar_empty_button">Nicht belegt</string>
+ <string name="navbar_menu_conditional_button">Menü (automatisch ausblenden)</string>
+ <string name="navbar_menu_always_button">Menü (immer sichtbar)</string>
+ <string name="navbar_menu_big_button">Menü</string>
+
+ <!-- **** CYANOGENMOD ADDITIONS END **** -->
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index dae50a3..e2800b8 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -65,8 +65,8 @@
<string name="compat_mode_off" msgid="4434467572461327898">"Προβoλή σε πλήρη οθ."</string>
<string name="compat_mode_help_header" msgid="7969493989397529910">"Ζουμ για συμβατότητα"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Όταν μια εφαρμογή έχει σχεδιαστεί για προβολή σε μικρότερη οθόνη, δίπλα από το ρολόι θα εμφανιστεί ένα στοιχείο ελέγχου ζουμ."</string>
- <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Αποθήκ. στιγμιότυπου οθόνης..."</string>
- <string name="screenshot_saving_title" msgid="8242282144535555697">"Αποθήκευση στιγμιότυπου οθόνης..."</string>
+ <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Αποθήκ. στιγμιότυπου οθόνης\u2026"</string>
+ <string name="screenshot_saving_title" msgid="8242282144535555697">"Αποθήκευση στιγμιότυπου οθόνης\u2026"</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"Γίνεται αποθήκευση του στιγμιότυπου οθόνης."</string>
<string name="screenshot_saved_title" msgid="6461865960961414961">"Λήφθηκε το στιγμιότυπο οθόνης ."</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Αγγίξτε για να δείτε το στιγμιότυπο οθόνης σας"</string>
@@ -134,9 +134,6 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Δεν υπάρχει SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Πρόσδεση Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Λειτουργία πτήσης."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Ρυθμίσεις συστήματος."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Ειδοποιήσεις."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Εκκαθάριση ειδοποίησης."</string>
@@ -205,4 +202,32 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ΑΥΤΟΜΑΤΗ"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Οι ειδοποιήσεις εμφανίζονται εδώ"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Μεταβείτε σε αυτές ανά πάσα στιγμή σύροντας προς τα κάτω."\n"Σύρετε ξανά προς τα κάτω για τα στοιχεία ελέγχου συστήματος."</string>
+
+ <string name="powerwidget_screen_timeout_toast">Λήξη χρον. ορίου οθόνης: %1$d %2$s</string>
+
+ <string name="accessibility_quick_settings_ringer">Ήχος <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Δόνηση <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_screen_sleep">Αναστολή λειτουργίας</string>
+ <string name="quick_settings_ringer_on">Ήχος ενεργός</string>
+ <string name="quick_settings_ringer_off">Ήχος ανενεργός</string>
+ <string name="quick_settings_vibration_on">Δόνηση ενεργή</string>
+ <string name="quick_settings_vibration_off">Δόνηση ανενεργή</string>
+ <string name="quick_settings_label_enabled">Ενεργό</string>
+ <string name="quick_settings_label_disabled">Ανενεργό</string>
+ <string name="quick_settings_ringer_normal">Ήχος</string>
+ <string name="quick_settings_lockscreen">Οθόνη κλειδώματος</string>
+ <string name="quick_settings_network_type">Δίκτυο</string>
+ <string name="quick_settings_report_bug">Αναφορά σφάλματος</string>
+ <string name="quick_settings_sync">Συγχρονισμός</string>
+ <string name="quick_settings_torch">Φακός</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_screen_timeout">Χρ. όριο οθόνης</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+
+ <string name="quick_settings_profile_label">Προφίλ</string>
+
+ <string name="bean_dream_settings_cid_title">Χρήση κεφαλιού CID</string>
+ <string name="bean_dream_settings_cid_summary">Χρήση του κεφαλιού CID αντί για το jellybean στο dream</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 19de9b6..7a024ff 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<!--
/**
* Copyright (c) 2009, The Android Open Source Project
@@ -65,8 +65,8 @@
<string name="compat_mode_off" msgid="4434467572461327898">"Expandir para ajustar"</string>
<string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilidad"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Si la aplicación se ha diseñado para una pantalla más pequeña, aparecerá un control de zoom junto al reloj."</string>
- <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Guardando captura..."</string>
- <string name="screenshot_saving_title" msgid="8242282144535555697">"Guardando captura..."</string>
+ <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Guardando captura\u2026"</string>
+ <string name="screenshot_saving_title" msgid="8242282144535555697">"Guardando captura\u2026"</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"La captura de pantalla se está guardando."</string>
<string name="screenshot_saved_title" msgid="6461865960961414961">"Captura guardada"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver la captura de pantalla"</string>
@@ -139,7 +139,7 @@
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Borrar notificación"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS habilitado"</string>
- <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Obteniendo ubicación..."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Obteniendo ubicación\u2026"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Teletipo habilitado"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Modo vibración"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Modo silencio"</string>
@@ -181,10 +181,10 @@
<string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Cargada"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> dispositivos)"</string>
- <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth desactivado"</string>
+ <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brillo"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Girar automáticamente"</string>
- <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotación bloqueada"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automático"</string>
+ <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Bloqueado"</string>
<string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</string>
<string name="quick_settings_location_label" msgid="3292451598267467545">"Ubicación en uso"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo multimedia"</string>
@@ -196,11 +196,58 @@
<string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"No conectado"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No hay red."</string>
- <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desactivado"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi"</string>
<string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Pantalla Wi-Fi"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla inalámbrica"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido."\n"Vuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
+
+ <!-- CYANOGENMOD ADDITIONS START -->
+
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS</string>
+ <string name="quick_settings_label_enabled">Activado</string>
+ <string name="quick_settings_label_disabled">Desactivado</string>
+ <string name="quick_settings_lockscreen">Bloqueo</string>
+ <string name="quick_settings_network_type">Red móvil</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_nfc_off">NFC</string>
+ <string name="quick_settings_profile_label">Perfil</string>
+ <string name="quick_settings_quiethours">Modo tranq.</string>
+ <string name="quick_settings_quiethours_off">Modo tranq.</string>
+ <string name="quick_settings_report_bug">Notificar error</string>
+ <string name="quick_settings_ringer_normal">Sonido</string>
+ <string name="quick_settings_ringer_on">Sonido</string>
+ <string name="quick_settings_ringer_off">Silencio</string>
+ <string name="quick_settings_screen_sleep">Bloquear</string>
+ <string name="quick_settings_screen_timeout">Tiempo espera</string>
+ <string name="quick_settings_sync">Sincronizar</string>
+ <string name="quick_settings_sync_off">Sincronizar</string>
+ <string name="quick_settings_torch">Linterna</string>
+ <string name="quick_settings_torch_off">Linterna</string>
+ <string name="quick_settings_usb_tether_off_label">Desconectado</string>
+ <string name="quick_settings_usb_tether_connected_label">Anclaje USB</string>
+ <string name="quick_settings_usb_tether_on_label">Anclaje USB</string>
+ <string name="quick_settings_vibration_on">Vibración</string>
+ <string name="quick_settings_vibration_off">Vibración</string>
+ <string name="quick_settings_wifiap">Wi-Fi AP</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi AP</string>
+ <string name="accessibility_quick_settings_ringer">Sonido <xliff:g id="state" example="Apagado">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Vibración <xliff:g id="state" example="Apagada">%s</xliff:g>.</string>
+ <string name="bean_dream_settings_cid_title">Usar a CID</string>
+ <string name="bean_dream_settings_cid_summary">Usar el icono CID para el salvapantallas en vez del icono Jellybean</string>
+ <string name="powerwidget_screen_timeout_toast">Tiempo de pantalla establecido a: %1$d %2$s</string>
+ <string name="navbar_dialog_title">Seleccionar botón a mostrar</string>
+ <string name="navbar_home_button">Botón Inicio</string>
+ <string name="navbar_recent_button">Botón Recientes</string>
+ <string name="navbar_search_button">Botón Búsqueda</string>
+ <string name="navbar_back_button">Botón Atrás</string>
+ <string name="navbar_empty_button">Sin botón</string>
+ <string name="navbar_menu_conditional_button">Botón Menú (auto-ocultar)</string>
+ <string name="navbar_menu_always_button">Botón Menú (siempre visible)</string>
+ <string name="navbar_menu_big_button">Botón Menú</string>
+
+ <!-- CYANOGENMOD ADDITIONS END -->
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 27bf2f5..89d5277 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -155,6 +155,8 @@
<string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Repülős üzemmód <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Ébresztés időpontja: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_ringer">Hang <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Rezgés <xliff:g id="state" example="Off">%s</xliff:g>.</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G adatforgalom letiltva"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G adatforgalom letiltva"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil adatforgalom letiltva"</string>
@@ -174,6 +176,8 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A képernyő zárolva van fekvő tájolásban."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A képernyő zárolva van álló tájolásban."</string>
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+ <string name="bean_dream_settings_cid_title">CID fej használata</string>
+ <string name="bean_dream_settings_cid_summary">A képernyővédőn űrlényfejek jelennek meg a zselés cukorkák helyett</string>
<string name="start_dreams" msgid="7219575858348719790">"Álmodozás"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Repülőgép üzemmód"</string>
@@ -196,11 +200,53 @@
<string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nincs kapcsolat"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nincs hálózat"</string>
- <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi kikapcsolva"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ki"</string>
<string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi kijelző"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Vezeték nélküli kijelző"</string>
+ <string name="quick_settings_profile_label">Profil</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Fényerő"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"automatikus"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Az értesítések itt jelennek meg."</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Bármikor elérheti őket, ha lefelé húzza az ujját."\n"Húzza le az ujját még egyszer a rendszerbeállítások eléréséhez."</string>
+ <string name="powerwidget_screen_timeout_toast">Képernyő időkorlátja: %1$d %2$s</string>
+
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS ki</string>
+ <string name="quick_settings_screen_sleep">Alvó mód</string>
+ <string name="quick_settings_ringer_on">Hang</string>
+ <string name="quick_settings_ringer_off">Hang ki</string>
+ <string name="quick_settings_vibration_on">Rezgés</string>
+ <string name="quick_settings_vibration_off">Rezgés ki</string>
+ <string name="quick_settings_label_enabled">Be</string>
+ <string name="quick_settings_label_disabled">Ki</string>
+ <string name="quick_settings_ringer_normal">Hang</string>
+ <string name="quick_settings_lockscreen">Képernyőzár</string>
+ <string name="quick_settings_network_type">Hálózat típusa</string>
+ <string name="quick_settings_report_bug">Hibajelentés</string>
+ <string name="quick_settings_sync">Szinkronizálás</string>
+ <string name="quick_settings_sync_off">Szinkronizálás ki</string>
+ <string name="quick_settings_torch">Zseblámpa</string>
+ <string name="quick_settings_torch_off">Zseblámpa ki</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_nfc_off">NFC ki</string>
+ <string name="quick_settings_screen_timeout">Időkorlát: </string>
+ <string name="quick_settings_usb_tether_off_label">Lecsatlakoztatva</string>
+ <string name="quick_settings_usb_tether_connected_label">Megosztás ki</string>
+ <string name="quick_settings_usb_tether_on_label">Megosztás</string>
+ <string name="quick_settings_wifiap">Wi-Fi AP</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi AP ki</string>
+ <string name="quick_settings_quiethours">Csendes órák</string>
+ <string name="quick_settings_quiethours_off">Csendes órák ki</string>
+
+ <!-- Dialog title for navigation bar button selection -->
+ <string name="navbar_dialog_title">Válasszon eseményt</string>
+ <string name="navbar_home_button">Kezdőgomb</string>
+ <string name="navbar_recent_button">Alkalmazás előzmények gomb</string>
+ <string name="navbar_search_button">Keresés gomb</string>
+ <string name="navbar_back_button">Vissza gomb</string>
+ <string name="navbar_empty_button">Gomb törlése</string>
+ <string name="navbar_menu_conditional_button">Menü (auto elrejtés)</string>
+ <string name="navbar_menu_always_button">Menü (mindig látszik)</string>
+ <string name="navbar_menu_big_button">Menü gomb</string>
+
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 812d1ac..361ab29 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -126,6 +126,7 @@
<string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_HP">HSPA+</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Roaming"</string>
@@ -134,8 +135,7 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Nessuna SIM presente."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modalità aereo."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <string name="accessibility_battery_level">Batteria <xliff:g id="number">%d</xliff:g> percento.</string>
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Impostazioni di sistema."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifiche."</string>
@@ -157,6 +157,8 @@
<string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modalità aereo: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Allarme impostato per: <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_ringer">Suoneria <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Vibrazione <xliff:g id="state" example="Off">%s</xliff:g>.</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dati 2G-3G disattivati"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dati 4G disattivati"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dati mobili disattivati"</string>
@@ -176,6 +178,8 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Lo schermo è bloccato in orientamento orizzontale."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Lo schermo è bloccato in orientamento verticale."</string>
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+ <string name="bean_dream_settings_cid_title">Utilizza testa CID</string>
+ <string name="bean_dream_settings_cid_summary">Utilizza la testa di CID al posto dei jellybean all\'interno di Daydream</string>
<string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modalità aereo"</string>
@@ -201,8 +205,45 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi disattivato"</string>
<string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Display Wi-Fi"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Visualizzazione wireless"</string>
+ <string name="quick_settings_profile_label">Profilo</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosità"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Le notifiche vengono visualizzate qui"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Puoi accedervi in qualsiasi momento scorrendo verso il basso."\n"Fai scorrere di nuovo verso il basso per visualizzare i controlli del sistema."</string>
+ <string name="powerwidget_screen_timeout_toast">Timeout impostato a: %1$d %2$s</string>
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS disattivato</string>
+ <string name="quick_settings_screen_sleep">Blocca telefono</string>
+ <string name="quick_settings_ringer_on">Suoneria attiva</string>
+ <string name="quick_settings_ringer_off">Suoneria disattivata</string>
+ <string name="quick_settings_vibration_on">Vibrazione attiva</string>
+ <string name="quick_settings_vibration_off">Vibrazione disattivata</string>
+ <string name="quick_settings_label_enabled">Attivo</string>
+ <string name="quick_settings_label_disabled">Disattivato</string>
+ <string name="quick_settings_ringer_normal">Suoneria</string>
+ <string name="quick_settings_lockscreen">Blocco schermo</string>
+ <string name="quick_settings_network_type">Modalità rete</string>
+ <string name="quick_settings_report_bug">Segnalazione bug</string>
+ <string name="quick_settings_sync">Sincronia attiva</string>
+ <string name="quick_settings_sync_off">Sincronia disattivata</string>
+ <string name="quick_settings_torch">Torcia</string>
+ <string name="quick_settings_torch_off">Torcia disattivata</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_nfc_off">NFC disattivato</string>
+ <string name="quick_settings_screen_timeout">Timeout</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+ <string name="quick_settings_usb_tether_off_label">Disconnesso</string>
+ <string name="quick_settings_usb_tether_connected_label">Tethering disattivato</string>
+ <string name="quick_settings_usb_tether_on_label">Tethering</string>
+ <string name="quick_settings_wifiap">Wi-Fi AP</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi AP disattivato</string>
+ <string name="navbar_dialog_title">Azione da associare</string>
+ <string name="navbar_home_button">Pulsante Home</string>
+ <string name="navbar_recent_button">Pulsante Recenti</string>
+ <string name="navbar_search_button">Pulsante Cerca</string>
+ <string name="navbar_back_button">Pulsante Indietro</string>
+ <string name="navbar_empty_button">Pulsante vuoto</string>
+ <string name="navbar_menu_conditional_button">Pulsante Menu (automatico)</string>
+ <string name="navbar_menu_always_button">Pulsante Menu (fisso)</string>
+ <string name="navbar_menu_big_button">Pulsante Menu</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 150375d..e1e6008 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -181,7 +181,7 @@
<string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"מלאה"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth ‏(<xliff:g id="NUMBER">%d</xliff:g> מכשירים)"</string>
- <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth מופסק"</string>
+ <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth כבוי"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"בהירות"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"סיבוב אוטומטי"</string>
<string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"סיבוב נעול"</string>
@@ -203,4 +203,52 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"אוטומטי"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"הודעות מופיעות כאן"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"גש אליהם בכל עת על ידי החלקה למטה."\n"החלק למטה שוב למעבר למרכז הבקרה של המערכת."</string>
+
+<!-- **** CYANOGENMOD ADDITIONS START **** -->
+
+<!-- QuickSettings -->
+ <string name="accessibility_quick_settings_ringer">צליל <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">רטט <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <!-- QuickSettings: Profile [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_profile_label">פרופיל</string>
+ <string name="powerwidget_screen_timeout_toast">כיבוי מסך אוטומטי מוגדר ל: %1$d %2$s</string>
+
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_screen_sleep">לך לישון</string>
+ <string name="quick_settings_ringer_on">קול פועל</string>
+ <string name="quick_settings_ringer_off">קול מושתק</string>
+ <string name="quick_settings_vibration_on">רטט פועל</string>
+ <string name="quick_settings_vibration_off">רטט כבוי</string>
+ <string name="quick_settings_label_enabled">פועל</string>
+ <string name="quick_settings_label_disabled">כבוי</string>
+ <string name="quick_settings_ringer_normal">צליל</string>
+ <string name="quick_settings_lockscreen">מסך נעילה</string>
+ <string name="quick_settings_network_type">מצב רשת</string>
+ <string name="quick_settings_report_bug">דיווח על באג</string>
+ <string name="quick_settings_sync">סינכרון</string>
+ <string name="quick_settings_torch">פנס</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_screen_timeout">כיבוי מסך</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+ <string name="quick_settings_usb_tether_off_label">מנותק</string>
+ <string name="quick_settings_usb_tether_connected_label">קשירה כבויה</string>
+ <string name="quick_settings_usb_tether_on_label">קשירה</string>
+
+<!-- CID DayDream -->
+ <string name="bean_dream_settings_cid_title">השתמש בראשו של סיד</string>
+ <string name="bean_dream_settings_cid_summary">השתמש בראשו של סיד במקום בסוכריות הגומי</string>
+
+ <!-- Dialog title for navigation bar button selection -->
+ <string name="navbar_dialog_title">בחר פעולה שברצונך לשייך</string>
+ <string name="navbar_home_button">כפתור בית</string>
+ <string name="navbar_recent_button">כפתור יישומים אחרונים</string>
+ <string name="navbar_search_button">כפתור חיפוש</string>
+ <string name="navbar_back_button">כפתור חזרה</string>
+ <string name="navbar_empty_button">כפתור ריק</string>
+ <string name="navbar_menu_conditional_button">כפתור תפריט (הסתרה אוטומטית)</string>
+ <string name="navbar_menu_always_button">כפתור תפריט (הצג תמיד)</string>
+ <string name="navbar_menu_big_button">כפתור תפריט</string>
+
+ <!-- **** CYANOGENMOD ADDITIONS END **** -->
+
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index c055aec..14950aa 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -203,4 +203,47 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATISCH"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Meldingen worden hier weergegeven"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"U kunt de meldingen op elk gewenst moment openen door met uw vinger omlaag te vegen."\n"Veeg nogmaals met uw vinger omlaag om de systeembesturingselementen weer te geven."</string>
+
+ <!-- CYANOGENMOD ADDITIONS -->
+ <string name="accessibility_data_connection_HP">HSPA+</string>
+ <string name="accessibility_quick_settings_ringer">Geluid <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Trillen <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="bean_dream_settings_cid_title">Hoofd van Cid gebruiken</string>
+ <string name="bean_dream_settings_cid_summary">Het hoofd van de mascotte van CyanogenMod gebruiken i.p.v. jellybeans</string>
+ <string name="quick_settings_profile_label">Profiel</string>
+ <string name="powerwidget_screen_timeout_toast">Schermtime-out ingesteld op: %1$d %2$s</string>
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS uit</string>
+ <string name="quick_settings_screen_sleep">Slaapstand</string>
+ <string name="quick_settings_ringer_on">Geluid aan</string>
+ <string name="quick_settings_ringer_off">Geluid uit</string>
+ <string name="quick_settings_vibration_on">Trillen aan</string>
+ <string name="quick_settings_vibration_off">Trillen uit</string>
+ <string name="quick_settings_label_enabled">Aan</string>
+ <string name="quick_settings_label_disabled">Uit</string>
+ <string name="quick_settings_ringer_normal">Geluid</string>
+ <string name="quick_settings_lockscreen">Vergrendelscherm</string>
+ <string name="quick_settings_network_type">Netwerkstand</string>
+ <string name="quick_settings_report_bug">Fout melden</string>
+ <string name="quick_settings_sync">Synchr.</string>
+ <string name="quick_settings_sync_off">Synchr. uit</string>
+ <string name="quick_settings_torch">Zaklamp</string>
+ <string name="quick_settings_torch_off">Zaklamp uit</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_nfc_off">NFC uit</string>
+ <string name="quick_settings_screen_timeout">Time-out</string>
+ <string name="quick_settings_usb_tether_off_label">Losgekoppeld</string>
+ <string name="quick_settings_usb_tether_connected_label">Tethering uit</string>
+ <string name="quick_settings_usb_tether_on_label">Tethering</string>
+ <string name="quick_settings_wifiap">Hotspot</string>
+ <string name="quick_settings_wifiap_off">Hotspot uit</string>
+ <string name="navbar_dialog_title">Kies de toe te wijzen functie</string>
+ <string name="navbar_home_button">Thuisknop</string>
+ <string name="navbar_recent_button">Recentknop</string>
+ <string name="navbar_search_button">Zoekknop</string>
+ <string name="navbar_back_button">Terugknop</string>
+ <string name="navbar_empty_button">Functieloze knop</string>
+ <string name="navbar_menu_conditional_button">Menuknop (altijd verbergen)</string>
+ <string name="navbar_menu_always_button">Menuknop (altijd tonen)</string>
+ <string name="navbar_menu_big_button">Menuknop</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1b8370b..679c401 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -139,10 +139,10 @@
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificações"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ativado."</string>
- <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Adquirir GPS."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"A adquirir GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Teletipo ativado."</string>
- <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Campainha em vibração."</string>
- <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha em silêncio."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibração activada."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Em silêncio."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ignorado."</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação ignorada."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Painel de notificações."</string>
@@ -175,7 +175,7 @@
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"O ecrã está bloqueado na orientação vertical."</string>
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
<string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
- <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+ <string name="ethernet_label" msgid="7967563676324087464">"Rede"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modo de avião"</string>
<string name="quick_settings_battery_charging_label" msgid="490074774465309209">"A carregar, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Carregada"</string>
@@ -203,4 +203,44 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"As notificações são apresentadas aqui"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Pode aceder em qualquer altura, deslizando rapidamente para baixo com o dedo."\n"Deslize novamente para baixo para aceder aos controlos do sistema."</string>
+ <string name="powerwidget_screen_timeout_toast">Tempo de suspensão do ecrã ajustado para: %1$d %2$s</string>
+ <string name="quick_settings_profile_label">Perfil</string>
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS desligado</string>
+ <string name="quick_settings_screen_sleep">Bloquear ecrã</string>
+ <string name="quick_settings_ringer_on">Som ligado</string>
+ <string name="quick_settings_ringer_off">Som desligado</string>
+ <string name="quick_settings_vibration_on">Vibração ligada</string>
+ <string name="quick_settings_vibration_off">Vibração desligada</string>
+ <string name="quick_settings_label_enabled">Ligado</string>
+ <string name="quick_settings_label_disabled">Desligado</string>
+ <string name="quick_settings_ringer_normal">Som</string>
+ <string name="quick_settings_lockscreen">Ecrã de bloqueio</string>
+ <string name="quick_settings_network_type">Modo de rede</string>
+ <string name="quick_settings_report_bug">Reportar problema</string>
+ <string name="accessibility_quick_settings_ringer">Som <xliff:g id="state" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Vibração <xliff:g id="state" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g>.</string>
+ <string name="bean_dream_settings_cid_title">Utilizar a cabeça do CID</string>
+ <string name="bean_dream_settings_cid_summary">Utilizar a cabeça do CID em vez do Jelly Bean</string>
+ <string name="accessibility_data_connection_HP">HSPA+</string>
+ <string name="quick_settings_sync">Sincronização</string>
+ <string name="quick_settings_torch">Lanterna</string>
+ <string name="quick_settings_torch_off">Lanterna desligada</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_screen_timeout">Tempo excedido</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+ <string name="quick_settings_usb_tether_off_label">Desligado</string>
+ <string name="quick_settings_usb_tether_connected_label">Tethering ligado</string>
+ <string name="quick_settings_usb_tether_on_label">Tethering</string>
+ <string name="quick_settings_wifiap">Wi-Fi AP</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi AP desligado</string>
+ <string name="navbar_dialog_title">Escolha um local para criar um atalho</string>
+ <string name="navbar_home_button">Botão de Início</string>
+ <string name="navbar_recent_button">Botão de Recentes</string>
+ <string name="navbar_search_button">Botão de Pesquisa</string>
+ <string name="navbar_back_button">Botão de Voltar</string>
+ <string name="navbar_empty_button">Espaço Vazio</string>
+ <string name="navbar_menu_conditional_button">Botão Menu (auto-ocultar)</string>
+ <string name="navbar_menu_always_button">Botão Menu (sempre visível)</string>
+ <string name="navbar_menu_big_button">Botão de Menu</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a14ee38..5c58a03 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -205,4 +205,45 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"As notificações aparecem aqui"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Acesse a qualquer momento deslizando para baixo."\n"Deslize para baixo novamente para acessar os controles do sistema."</string>
-</resources>
+ <string name="accessibility_battery_level">%d porcentos de bateria.</string>
+ <string name="powerwidget_screen_timeout_toast">Tempo limite da tela ajustado para: %1$d %2$s</string>
+ <string name="quick_settings_profile_label">Perfil</string>
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_screen_sleep">Dormir</string>
+ <string name="quick_settings_ringer_on">Som ligado</string>
+ <string name="quick_settings_ringer_off">Som desligado</string>
+ <string name="quick_settings_vibration_on">Vibração ligada</string>
+ <string name="quick_settings_vibration_off">Vibração desligada</string>
+ <string name="quick_settings_label_enabled">Ligado</string>
+ <string name="quick_settings_label_disabled">Desligado</string>
+ <string name="quick_settings_ringer_normal">Som</string>
+ <string name="quick_settings_lockscreen">Tela de Bloqueio</string>
+ <string name="quick_settings_network_type">Tipo de Rede</string>
+ <string name="quick_settings_report_bug">Reportar Problema</string>
+ <string name="accessibility_quick_settings_ringer">Sound <xliff:g id="state" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Vibração <xliff:g id="state" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g>.</string>
+ <string name="bean_dream_settings_cid_title">Usar cabeça CID</string>
+ <string name="bean_dream_settings_cid_summary">Usar cabeça CID em vez de jujuba dentro do sonho</string>
+ <string name="accessibility_data_connection_HP">HSPA+</string>
+ <string name="quick_settings_sync">Sincronização</string>
+ <string name="quick_settings_torch">Tocha</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_screen_timeout">Tempo limite</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+ <string name="navbar_dialog_title">Escolha uma ação para atribuir</string>
+ <string name="navbar_home_button">Botão de início</string>
+ <string name="navbar_recent_button">Botão de recentes</string>
+ <string name="navbar_search_button">Botão de buscar</string>
+ <string name="navbar_back_button">Botão de voltar</string>
+ <string name="navbar_empty_button">Botão vazio</string>
+ <string name="navbar_menu_conditional_button">Botão menu (esconder auto.)</string>
+ <string name="navbar_menu_always_button">Botão menu (sempre visível)</string>
+ <string name="navbar_menu_big_button">Botão menu</string>
+ <string name="quick_settings_usb_tether_off_label">Disconectado</string>
+ <string name="quick_settings_usb_tether_connected_label">Tethering desl.</string>
+ <string name="quick_settings_usb_tether_on_label">Tethering</string>
+ <string name="quick_settings_sync_off">Sinc. desl.</string>
+ <string name="quick_settings_torch_off">Tocha desl.</string>
+ <string name="quick_settings_nfc_off">NFC desl.</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi AP desl.</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 4618559..f150d51 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -203,4 +203,18 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAT"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Notificările se afişează aici"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Accesaţi-le oricând glisând în jos."\n"Glisaţi în jos din nou pentru comenzile sistemului."</string>
+
+ <string name="quick_settings_gps">"GPS"</string>
+ <string name="quick_settings_screen_sleep">"Adormire"</string>
+ <string name="quick_settings_ringer_on">"Sunet activat"</string>
+ <string name="quick_settings_ringer_off">"Sunet dezactivat"</string>
+ <string name="quick_settings_vibration_on">"Vibrare activată"</string>
+ <string name="quick_settings_vibration_off">"Vibrare dezactivată"</string>
+ <string name="quick_settings_label_enabled">"Activat"</string>
+ <string name="quick_settings_label_disabled">"Dezactivat"</string>
+ <string name="quick_settings_ringer_normal">"Sunet"</string>
+ <string name="quick_settings_lockscreen">"Ecran Blocare"</string>
+ <string name="quick_settings_network_type">"Mod Reţea"</string>
+ <string name="quick_settings_report_bug">"Raport Erori"</string>
+ <string name="quick_settings_sync">Sincronizare</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 28fe0d2..d5081bd 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1,18 +1,18 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
/**
* Copyright (c) 2009, The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * 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
+ * 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
+ * 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.
*/
-->
@@ -41,7 +41,7 @@
<string name="battery_low_why" msgid="7279169609518386372">"Подробнее"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
- <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим полета"</string>
+ <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим полёта"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Автоповорот экрана"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ВЫКЛ."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"АВТО"</string>
@@ -68,7 +68,7 @@
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"Сохранение..."</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"Сохранение..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"Сохранение..."</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"Скриншот сохранен"</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"Скриншот сохранён"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Нажмите, чтобы просмотреть"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Не удалось сохранить скриншот."</string>
<string name="screenshot_failed_text" msgid="8134011269572415402">"Не удалось сохранить скриншот. Возможно, накопители заняты."</string>
@@ -133,7 +133,7 @@
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-карта отсутствует."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-модем"</string>
- <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полета."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полёта"</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
@@ -154,9 +154,11 @@
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="NETWORK">%2$s</xliff:g>: <xliff:g id="SIGNAL">%1$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобильная сеть: <xliff:g id="NETWORK">%3$s</xliff:g> (<xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="SIGNAL">%1$s</xliff:g>)"</string>
<string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Батарея: <xliff:g id="STATE">%s</xliff:g>"</string>
- <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Режим полета <xliff:g id="STATE">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Режим полёта <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Будильник установлен на <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_ringer">Звук <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Вибрация <xliff:g id="state" example="Off">%s</xliff:g>.</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Передача данных по каналам 2G и 3G отключена"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Передача данных по каналу 4G отключена"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Моб. Интернет отключен"</string>
@@ -176,12 +178,13 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Выбрана только альбомная ориентация экрана."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Выбрана только книжная ориентация экрана."</string>
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+ <string name="bean_dream_settings_cid_title">Голова CID\'а</string>
+ <string name="bean_dream_settings_cid_summary">Заменить желейные конфеты на голову CID\'а</string>
<string name="start_dreams" msgid="7219575858348719790">"Заставка"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
- <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Режим полета"</string>
+ <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Режим полёта"</string>
<string name="quick_settings_battery_charging_label" msgid="490074774465309209">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for quick_settings_battery_charged_label (8865413079414246081) -->
+ <string name="quick_settings_battery_charged_label">Заряжено</string>
<skip />
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -203,8 +206,45 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi выкл."</string>
<string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Проектор Wi-Fi"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Беспроводной проектор"</string>
+ <string name="quick_settings_profile_label">Профиль</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркость"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Это панель уведомлений"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Ее можно открыть, пролистнув экран вниз."\n"Чтобы открыть настройки, проведите пальцем вниз ещё раз."</string>
+
+ <string name="quick_settings_gps_off">GPS выкл.</string>
+ <string name="quick_settings_screen_sleep">Сон</string>
+ <string name="quick_settings_ringer_on">Вкл. звук</string>
+ <string name="quick_settings_ringer_off">Выкл. звук</string>
+ <string name="quick_settings_vibration_on">Вкл. вибро</string>
+ <string name="quick_settings_vibration_off">Выкл. вибро</string>
+ <string name="quick_settings_label_enabled">Вкл.</string>
+ <string name="quick_settings_label_disabled">Выкл.</string>
+ <string name="quick_settings_ringer_normal">Звук</string>
+ <string name="quick_settings_lockscreen">Экран блокировки</string>
+ <string name="quick_settings_network_type">Тип сети</string>
+ <string name="quick_settings_report_bug">Отчёт об ошибке</string>
+ <string name="quick_settings_sync">Синхронизация</string>
+ <string name="quick_settings_sync_off">Синхронизация выкл.</string>
+ <string name="quick_settings_torch">Фонарь</string>
+ <string name="quick_settings_torch_off">Фонарь выкл.</string>
+ <string name="quick_settings_nfc_off">NFC выкл.</string>
+ <string name="quick_settings_screen_timeout">Тайм-аут</string>
+ <string name="quick_settings_usb_tether_off_label">Отключено</string>
+ <string name="quick_settings_usb_tether_connected_label">Выключен</string>
+ <string name="quick_settings_usb_tether_on_label">Включён</string>
+ <string name="quick_settings_wifiap">Wi-Fi модем</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi модем выкл.</string>
+ <string name="quick_settings_quiethours">Тихие часы</string>
+
+ <!-- Dialog title for navigation bar button selection -->
+ <string name="navbar_dialog_title">Выберите действие</string>
+ <string name="navbar_home_button">Домой</string>
+ <string name="navbar_recent_button">Запущ. приложения</string>
+ <string name="navbar_search_button">Поиск</string>
+ <string name="navbar_back_button">Назад</string>
+ <string name="navbar_empty_button">Пустая кнопка</string>
+ <string name="navbar_menu_conditional_button">Меню (скрывающ.)</string>
+ <string name="navbar_menu_always_button">Меню (не скрывающ.)</string>
+ <string name="navbar_menu_big_button">Меню</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 91214d1..8a7fd64 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -196,8 +196,8 @@
<string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ej ansluten"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Inget nätverk"</string>
- <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi är inaktiverat"</string>
- <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi visas"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Av"</string>
+ <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi Display"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös visning"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ljusstyrka"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index fc80f5c..1b9518a 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -51,4 +51,9 @@
<!-- How far to slide the panel out when you touch it -->
<!-- On tablets this is just the close_handle_height -->
<dimen name="peek_height">@dimen/close_handle_height</dimen>
+
+ <!-- The padding of the items of the battery cluster -->
+ <dimen name="status_bar_battery_cluster_padding">4dip</dimen>
+ <!-- The margin adjusment of the text items of the battery cluster -->
+ <dimen name="status_bar_battery_cluster_text_margin">-3dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 33d1f6d..1fe5b54 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -126,6 +126,8 @@
<string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <!-- Content description of the data connection type HSPA+ for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_HP">HSPA+</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"漫游中"</string>
@@ -157,6 +159,10 @@
<string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"飞行模式:<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"蓝牙:<xliff:g id="STATE">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"闹钟已设置为:<xliff:g id="TIME">%s</xliff:g>。"</string>
+
+ <string name="accessibility_quick_settings_ringer">声音 <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">震动 <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G 数据网络已停用"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G 数据网络已停用"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"移动数据已停用"</string>
@@ -176,6 +182,8 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"屏幕锁定为横向模式。"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"屏幕锁定为纵向模式。"</string>
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"果冻豆大乱舞"</string>
+ <string name="bean_dream_settings_cid_title">使用 CID 头像</string>
+ <string name="bean_dream_settings_cid_summary">在大乱舞内使用 CID 的头像代替果冻豆</string>
<string name="start_dreams" msgid="7219575858348719790">"互动屏保"</string>
<string name="ethernet_label" msgid="7967563676324087464">"以太网"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"飞行模式"</string>
@@ -201,8 +209,49 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 已关闭"</string>
<string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi 显示设备"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"无线显示"</string>
+ <!-- QuickSettings: Profile [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_profile_label">情景模式</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"通知会显示在这里"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"向下滑动可随时查看通知。"\n"再次向下滑动可使用系统控制功能。"</string>
+ <string name="powerwidget_screen_timeout_toast">屏幕超时设为: %1$d %2$s</string>
+
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS 已关闭</string>
+ <string name="quick_settings_screen_sleep">进入睡眠</string>
+ <string name="quick_settings_ringer_on">声音开启</string>
+ <string name="quick_settings_ringer_off">声音关闭</string>
+ <string name="quick_settings_vibration_on">震动已开启</string>
+ <string name="quick_settings_vibration_off">震动已关闭</string>
+ <string name="quick_settings_label_enabled">已开启</string>
+ <string name="quick_settings_label_disabled">已关闭</string>
+ <string name="quick_settings_ringer_normal">声音</string>
+ <string name="quick_settings_lockscreen">锁屏</string>
+ <string name="quick_settings_network_type">网络模式</string>
+ <string name="quick_settings_report_bug">报告错误</string>
+ <string name="quick_settings_sync">同步</string>
+ <string name="quick_settings_sync_off">同步已关闭</string>
+ <string name="quick_settings_torch">手电筒</string>
+ <string name="quick_settings_torch_off">手电筒已关闭</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_nfc_off">NFC 已关闭</string>
+ <string name="quick_settings_screen_timeout">超时</string>
+ <string name="quick_settings_usb_tether_off_label">已断开</string>
+ <string name="quick_settings_usb_tether_connected_label">网络共享已关闭</string>
+ <string name="quick_settings_usb_tether_on_label">网络共享</string>
+ <string name="quick_settings_wifiap">Wi-Fi 热点</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi 热点已关闭</string>
+
+ <!-- Dialog title for navigation bar button selection -->
+ <string name="navbar_dialog_title">选择指定的行为</string>
+ <string name="navbar_home_button">Home 键</string>
+ <string name="navbar_recent_button">最近应用键</string>
+ <string name="navbar_search_button">搜索键</string>
+ <string name="navbar_back_button">后退键</string>
+ <string name="navbar_empty_button">空白按键</string>
+ <string name="navbar_menu_conditional_button">菜单键 (自动隐藏)</string>
+ <string name="navbar_menu_always_button">菜单键 (总是显示)</string>
+ <string name="navbar_menu_big_button">菜单键</string>
+
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index acb192d..d04d84fe 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -17,7 +17,7 @@
*/
-->
<resources>
- <drawable name="notification_number_text_color">#ffffffff</drawable>
+ <drawable name="notification_number_text_color">#ff000000</drawable>
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
<drawable name="status_bar_background">#ff000000</drawable>
<color name="notification_panel_solid_background">#ff000000</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ed08115..8cd90b7 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -158,6 +158,12 @@
<!-- Height of the notification panel header bar -->
<dimen name="notification_panel_header_height">48dp</dimen>
+ <!-- Height of the notification panel widget bar -->
+ <dimen name="notification_panel_widget_height">48dp</dimen>
+
+ <!-- Height of the notification panel header and widget -->
+ <dimen name="notification_panel_header_and_widget">96dp</dimen>
+
<!-- Extra space above the panel -->
<dimen name="notification_panel_padding_top">0dp</dimen>
@@ -205,4 +211,9 @@
<!-- How far to slide the panel out when you touch it -->
<!-- For phones, this is close_handle_height + header_height -->
<dimen name="peek_height">84dp</dimen>
+
+ <!-- The padding of the items of the battery cluster -->
+ <dimen name="status_bar_battery_cluster_padding">2dip</dimen>
+ <!-- The margin adjusment of the text items of the battery cluster -->
+ <dimen name="status_bar_battery_cluster_text_margin">-1dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml
index 41ea6f3..b048117 100644
--- a/packages/SystemUI/res/values/donottranslate.xml
+++ b/packages/SystemUI/res/values/donottranslate.xml
@@ -17,7 +17,6 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Date format for display: should match the lockscreen in /policy. -->
- <string name="abbrev_wday_month_day_no_year">@*android:string/abbrev_wday_month_day_no_year</string>
-
+ <!-- Date format for display in status bar. -->
+ <string name="full_wday_month_day_no_year_split">@*android:string/full_wday_month_day_no_year_split</string>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f3db062..e774626 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -317,6 +317,9 @@
<!-- Content description of the data connection type 3.5G for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_data_connection_3.5g">3.5G</string>
+ <!-- Content description of the data connection type HSPA+ for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_HP">HSPA+</string>
+
<!-- Content description of the data connection type 4G for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_data_connection_4g">4G</string>
@@ -395,6 +398,9 @@
<!-- Content description of the alarm tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_alarm">Alarm set for <xliff:g id="time" example="Wed 3:30 PM">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_ringer">Sound <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+ <string name="accessibility_quick_settings_vibration">Vibration <xliff:g id="state" example="Off">%s</xliff:g>.</string>
+
<!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
<string name="data_usage_disabled_dialog_3g_title">2G-3G data disabled</string>
<!-- Title of dialog shown when 4G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
@@ -454,6 +460,8 @@
<!-- Name of the Jelly Bean platlogo screensaver -->
<string name="jelly_bean_dream_name">BeanFlinger</string>
+ <string name="bean_dream_settings_cid_title">Use CID head</string>
+ <string name="bean_dream_settings_cid_summary">Use CID head instead of jellybean inside the dream</string>
<!-- Name of the launcher shortcut icon that allows dreams to be started immediately [CHAR LIMIT=20] -->
<string name="start_dreams">Daydream</string>
@@ -507,6 +515,8 @@
<string name="quick_settings_wifi_display_label">Wi-Fi Display</string>
<!-- QuickSettings: Wifi display [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_display_no_connection_label">Wireless Display</string>
+ <!-- QuickSettings: Profile [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_profile_label">Profile</string>
<!-- QuickSettings: Brightness dialog title [CHAR LIMIT=NONE] -->
<string name="quick_settings_brightness_dialog_title">Brightness</string>
<!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
@@ -516,4 +526,51 @@
<string name="status_bar_help_title">Notifications appear here</string>
<!-- Body of help text shown when the notification panel is pulled down for the very first time. [CHAR LIMIT=NONE] -->
<string name="status_bar_help_text">Access them anytime by swiping down.\nSwipe down again for system controls.</string>
+ <string name="powerwidget_screen_timeout_toast">Screen timeout set to: %1$d %2$s</string>
+
+ <string name="quick_settings_gps">GPS</string>
+ <string name="quick_settings_gps_off">GPS off</string>
+ <string name="quick_settings_screen_sleep">Go to sleep</string>
+ <string name="quick_settings_ringer_on">Sound on</string>
+ <string name="quick_settings_ringer_off">Sound off</string>
+ <string name="quick_settings_vibration_on">Vibration on</string>
+ <string name="quick_settings_vibration_off">Vibration off</string>
+ <string name="quick_settings_label_enabled">On</string>
+ <string name="quick_settings_label_disabled">Off</string>
+ <string name="quick_settings_ringer_normal">Sound</string>
+ <string name="quick_settings_lockscreen">Lock screen</string>
+ <string name="quick_settings_network_type">Network mode</string>
+ <string name="quick_settings_report_bug">Report bug</string>
+ <string name="quick_settings_sync">Sync</string>
+ <string name="quick_settings_sync_off">Sync off</string>
+ <string name="quick_settings_torch">Torch</string>
+ <string name="quick_settings_torch_off">Torch off</string>
+ <string name="quick_settings_nfc">NFC</string>
+ <string name="quick_settings_nfc_off">NFC off</string>
+ <string name="quick_settings_screen_timeout">Timeout</string>
+ <string name="quick_settings_screen_timeout_summary">%1$d %2$s</string>
+ <string name="quick_settings_usb_tether_off_label">Disconnected</string>
+ <string name="quick_settings_usb_tether_connected_label">Tethering off</string>
+ <string name="quick_settings_usb_tether_on_label">Tethering</string>
+ <string name="quick_settings_wifiap">Wi-Fi AP</string>
+ <string name="quick_settings_wifiap_off">Wi-Fi AP off</string>
+ <string name="quick_settings_quiethours">Quiet hours</string>
+ <string name="quick_settings_quiethours_off">Quiet hours off</string>
+
+ <!-- Text to display next to the minimal graphical battery meter. [CHAR LIMIT=3] -->
+ <string name="status_bar_settings_battery_meter_min_format" translatable="false">
+ <xliff:g id="number">%d</xliff:g>
+ </string>
+
+ <!-- Dialog title for navigation bar button selection -->
+ <string name="navbar_dialog_title">Choose action to assign</string>
+ <string name="navbar_home_button">Home button</string>
+ <string name="navbar_recent_button">Recent button</string>
+ <string name="navbar_search_button">Search button</string>
+ <string name="navbar_back_button">Back button</string>
+ <string name="navbar_empty_button">Empty button</string>
+ <string name="navbar_menu_conditional_button">Menu (autoHide) button</string>
+ <string name="navbar_menu_always_button">Menu (alwaysShow) button</string>
+ <string name="navbar_menu_big_button">Menu button</string>
+
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 1a59d6c..cd108b1 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -52,6 +52,13 @@
<item name="android:textColor">#FFFFFFFF</item>
</style>
+ <style name="TextAppearance.StatusBar.Battery" parent="@*android:style/TextAppearance.StatusBar.Icon">
+ <!-- Note: must be dp to fit in status bar -->
+ <item name="android:textSize">12dp</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">@android:color/holo_blue_light</item>
+ </style>
+
<style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
<!-- Note: must be dp to fit in status bar -->
<item name="android:textSize">16dp</item>
@@ -71,19 +78,26 @@
<item name="android:textSize">32dp</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textStyle">normal</item>
- <item name="android:textColor">#ffffff</item>
+ <item name="android:textColor">@color/clock_view_color</item>
</style>
<style name="TextAppearance.StatusBar.Expanded.Date">
<item name="android:textSize">12dp</item>
<item name="android:textStyle">normal</item>
- <item name="android:textColor">#cccccc</item>
+ <item name="android:textColor">@color/date_view_color</item>
<item name="android:textAllCaps">true</item>
</style>
<style name="TextAppearance.StatusBar.Expanded.Network" parent="@style/TextAppearance.StatusBar.Expanded.Date">
<item name="android:textColor">#999999</item>
- </style>
+ </style>
+
+ <style name="TextAppearance.StatusBar.Signal" parent="@*android:style/TextAppearance.StatusBar.Icon">
+ <!-- Note: must be dp to fit in status bar -->
+ <item name="android:textSize">12dp</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">@android:color/holo_blue_light</item>
+ </style>
<style name="TextAppearance.StatusBar.Expanded.Network.EmergencyOnly">
</style>
diff --git a/packages/SystemUI/res/xml/dream_info.xml b/packages/SystemUI/res/xml/dream_info.xml
new file mode 100644
index 0000000..df51bc4
--- /dev/null
+++ b/packages/SystemUI/res/xml/dream_info.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+ android:settingsActivity="com.android.systemui/com.android.systemui.BeanBagDreamSettings"
+/>
diff --git a/packages/SystemUI/res/xml/dream_settings.xml b/packages/SystemUI/res/xml/dream_settings.xml
new file mode 100644
index 0000000..43fdc7f
--- /dev/null
+++ b/packages/SystemUI/res/xml/dream_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/jelly_bean_dream_name">
+ <CheckBoxPreference
+ android:key="beanbag_dream_cid"
+ android:title="@string/bean_dream_settings_cid_title"
+ android:summary="@string/bean_dream_settings_cid_summary"
+ android:defaultValue="false" />
+</PreferenceScreen>
diff --git a/packages/SystemUI/src/com/android/systemui/BeanBag.java b/packages/SystemUI/src/com/android/systemui/BeanBag.java
index f5a90ca..73136f3 100644
--- a/packages/SystemUI/src/com/android/systemui/BeanBag.java
+++ b/packages/SystemUI/src/com/android/systemui/BeanBag.java
@@ -137,6 +137,28 @@ public class BeanBag extends Activity {
0xFF333333,
};
+ static int CIDS[] = {
+ R.drawable.cid_angry,
+ R.drawable.cid_angry,
+ R.drawable.cid_angry,
+ R.drawable.cid_angry,
+ R.drawable.cid_normal,
+ R.drawable.cid_normal,
+ R.drawable.cid_confused,
+ };
+
+ static int CIDCOLORS[] = {
+ 0xFF0099CC,
+ 0xFF33B5E5,
+ 0xFF669900,
+ 0xFF99CC00,
+ 0xFFCC0000,
+ 0xFFFF8800,
+ 0xFFFFBB33,
+ 0xFF9933CC,
+ 0xFFAA66CC,
+ };
+
public class Bean extends ImageView {
public static final float VMAX = 1000.0f;
public static final float VMIN = 100.0f;
@@ -167,7 +189,7 @@ public class BeanBag extends Activity {
}
private void pickBean() {
- int beanId = pickInt(BEANS);
+ int beanId = pickInt(mIsCid ? CIDS : BEANS);
if (randfrange(0,1) <= LUCKY) {
beanId = R.drawable.jandycane;
}
@@ -182,7 +204,7 @@ public class BeanBag extends Activity {
this.setImageDrawable(bean);
Paint pt = new Paint();
- final int color = pickInt(COLORS);
+ final int color = pickInt(mIsCid ? CIDCOLORS : COLORS);
ColorMatrix CM = new ColorMatrix();
float[] M = CM.getArray();
// we assume the color information is in the red channel
@@ -266,10 +288,11 @@ public class BeanBag extends Activity {
TimeAnimator mAnim;
private int boardWidth;
private int boardHeight;
+ private boolean mIsCid;
- public Board(Context context, AttributeSet as) {
+ public Board(Context context, AttributeSet as, boolean isCid) {
super(context, as);
-
+ mIsCid = isCid;
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
setWillNotDraw(!DEBUG);
@@ -413,7 +436,7 @@ public class BeanBag extends Activity {
WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
);
- mBoard = new Board(this, null);
+ mBoard = new Board(this, null, getIntent().getBooleanExtra("is_cid", false));
setContentView(mBoard);
}
diff --git a/packages/SystemUI/src/com/android/systemui/BeanBagDream.java b/packages/SystemUI/src/com/android/systemui/BeanBagDream.java
index 39e4727..85c42d2 100644
--- a/packages/SystemUI/src/com/android/systemui/BeanBagDream.java
+++ b/packages/SystemUI/src/com/android/systemui/BeanBagDream.java
@@ -16,6 +16,8 @@
package com.android.systemui;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
import android.service.dreams.DreamService;
import com.android.systemui.BeanBag.Board;
@@ -29,7 +31,8 @@ public class BeanBagDream extends DreamService {
super.onAttachedToWindow();
setInteractive(true);
setFullscreen(true);
- mBoard = new Board(this, null);
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+ mBoard = new Board(this, null, prefs.getBoolean("beanbag_dream_cid", false));
setContentView(mBoard);
}
diff --git a/packages/SystemUI/src/com/android/systemui/BeanBagDreamSettings.java b/packages/SystemUI/src/com/android/systemui/BeanBagDreamSettings.java
new file mode 100644
index 0000000..171e8f4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/BeanBagDreamSettings.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+import com.android.systemui.R;
+
+public class BeanBagDreamSettings extends PreferenceActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.dream_settings);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUI.java b/packages/SystemUI/src/com/android/systemui/SystemUI.java
index 2110483..14f6345 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUI.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUI.java
@@ -26,7 +26,7 @@ public abstract class SystemUI {
public Context mContext;
public abstract void start();
-
+
protected void onConfigurationChanged(Configuration newConfig) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 427fe91..18bedf1 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -96,6 +96,7 @@ public class SystemUIService extends Service {
}
mServices[i].mContext = this;
Slog.d(TAG, "running: " + mServices[i]);
+
mServices[i].start();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/AirplaneModeTile.java
new file mode 100644
index 0000000..a4d64c0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/AirplaneModeTile.java
@@ -0,0 +1,83 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+
+public class AirplaneModeTile extends QuickSettingsTile implements NetworkSignalChangedCallback{
+
+ private boolean enabled = false;
+
+ public AirplaneModeTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mLabel = mContext.getString(R.string.quick_settings_airplane_mode_label);
+
+ mOnClick = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ // Change the system setting
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
+ !enabled ? 1 : 0);
+
+ // Post the intent
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", !enabled);
+ mContext.sendBroadcast(intent);
+ }
+ };
+ mOnLongClick = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
+ return true;
+ }
+ };
+ }
+
+ @Override
+ void onPostCreate() {
+ NetworkController controller = new NetworkController(mContext);
+ controller.addNetworkSignalChangedCallback(this);
+ super.onPostCreate();
+ }
+
+ @Override
+ public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
+ String wifitSignalContentDescriptionId, String description) {
+ }
+
+ @Override
+ public void onMobileDataSignalChanged(boolean enabled,
+ int mobileSignalIconId, String mobileSignalContentDescriptionId,
+ int dataTypeIconId, String dataTypeContentDescriptionId,
+ String description) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onAirplaneModeChanged(boolean enabled) {
+ this.enabled = enabled;
+ if(enabled){
+ mDrawable = R.drawable.ic_qs_airplane_on;
+ }else{
+ mDrawable = R.drawable.ic_qs_airplane_off;
+ }
+ updateQuickSettings();
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/AlarmTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/AlarmTile.java
new file mode 100644
index 0000000..dd15e47
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/AlarmTile.java
@@ -0,0 +1,63 @@
+package com.android.systemui.quicksettings;
+
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+
+public class AlarmTile extends QuickSettingsTile {
+
+ public AlarmTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container,
+ QuickSettingsController qsc, Handler handler) {
+ super(context, inflater, container, qsc);
+
+ mDrawable = R.drawable.ic_qs_alarm_on;
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(
+ "com.android.deskclock",
+ "com.android.deskclock.AlarmClock"));
+ startSettingsActivity(intent);
+ }
+ };
+
+ qsc.registerObservedContent(Settings.System.getUriFor(
+ Settings.System.NEXT_ALARM_FORMATTED), this);
+ updateStatus();
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ updateStatus();
+ updateQuickSettings();
+ }
+
+ @Override
+ public void updateQuickSettings() {
+ mTile.setVisibility(!TextUtils.isEmpty(mLabel) ? View.VISIBLE : View.GONE);
+ super.updateQuickSettings();
+ }
+
+ /**
+ * Updates the alarm status shown on the tile.
+ */
+ private void updateStatus() {
+ mLabel = Settings.System.getString(mContext.getContentResolver(),
+ Settings.System.NEXT_ALARM_FORMATTED);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/AutoRotateTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/AutoRotateTile.java
new file mode 100644
index 0000000..c0fc428
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/AutoRotateTile.java
@@ -0,0 +1,69 @@
+package com.android.systemui.quicksettings;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+
+import com.android.internal.view.RotationPolicy;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+
+public class AutoRotateTile extends QuickSettingsTile {
+
+ private static final String TAG = "AutoRotateButton";
+
+ public AutoRotateTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc, Handler handler) {
+ super(context, inflater, container, qsc);
+
+ mOnClick = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ RotationPolicy.setRotationLock(mContext, getAutoRotation());
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity(Settings.ACTION_DISPLAY_SETTINGS);
+ return true;
+ }
+ };
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION)
+ , this);
+ }
+
+ void applyAutoRotationChanges() {
+ if(!getAutoRotation()){
+ mDrawable = R.drawable.ic_qs_rotation_locked;
+ mLabel = mContext.getString(R.string.quick_settings_rotation_locked_label);
+ }else{
+ mDrawable = R.drawable.ic_qs_auto_rotate;
+ mLabel = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
+ }
+ updateQuickSettings();
+ }
+
+ @Override
+ void onPostCreate() {
+ applyAutoRotationChanges();
+ super.onPostCreate();
+ }
+
+ private boolean getAutoRotation() {
+ return !RotationPolicy.isRotationLocked(mContext);
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ applyAutoRotationChanges();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/BatteryTile.java
new file mode 100644
index 0000000..89fc546
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/BatteryTile.java
@@ -0,0 +1,85 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LevelListDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
+
+public class BatteryTile extends QuickSettingsTile implements BatteryStateChangeCallback{
+
+ private boolean charging = false;
+ private int batteryLevel = 0;
+ private Drawable batteryIcon;
+
+ private LevelListDrawable batteryLevels;
+ private LevelListDrawable chargingBatteryLevels;
+
+ public BatteryTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mTileLayout = R.layout.quick_settings_tile_battery;
+ batteryLevels = (LevelListDrawable) mContext.getResources().getDrawable(R.drawable.qs_sys_battery);
+ chargingBatteryLevels = (LevelListDrawable) mContext.getResources().getDrawable(R.drawable.qs_sys_battery_charging);
+
+ BatteryController controller = new BatteryController(mContext);
+ controller.addStateChangedCallback(this);
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
+ }
+ };
+ }
+
+ @Override
+ void onPostCreate() {
+ applyBatteryChanges();
+ super.onPostCreate();
+ }
+
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn) {
+ batteryLevel = level;
+ charging = pluggedIn;
+ applyBatteryChanges();
+ }
+
+ void applyBatteryChanges() {
+ batteryIcon = charging
+ ? chargingBatteryLevels :
+ batteryLevels;
+ if(batteryLevel == 100) {
+ mLabel = mContext.getString(R.string.quick_settings_battery_charged_label);
+ }else{
+ mLabel = charging
+ ? mContext.getString(R.string.quick_settings_battery_charging_label,
+ batteryLevel)
+ : mContext.getString(R.string.status_bar_settings_battery_meter_format,
+ batteryLevel);
+
+ }
+ updateQuickSettings();
+ }
+
+ @Override
+ void updateQuickSettings() {
+ TextView tv = (TextView) mTile.findViewById(R.id.battery_textview);
+ tv.setText(mLabel);
+ ImageView iv = (ImageView) mTile.findViewById(R.id.battery_image);
+ iv.setImageDrawable(batteryIcon);
+ iv.setImageLevel(batteryLevel);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/BluetoothTile.java
new file mode 100644
index 0000000..db37294
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/BluetoothTile.java
@@ -0,0 +1,107 @@
+package com.android.systemui.quicksettings;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.policy.BluetoothController;
+
+public class BluetoothTile extends QuickSettingsTile implements BluetoothStateChangeCallback{
+
+ private boolean enabled = false;
+ private boolean connected = false;
+ private BluetoothAdapter mBluetoothAdapter;
+
+ public BluetoothTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ enabled = mBluetoothAdapter.isEnabled();
+ connected = mBluetoothAdapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED;
+
+ mOnClick = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if(enabled){
+ mBluetoothAdapter.disable();
+ }else{
+ mBluetoothAdapter.enable();
+ }
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
+ return true;
+ }
+ };
+ qsc.registerAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED, this);
+ qsc.registerAction(BluetoothAdapter.ACTION_STATE_CHANGED, this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if(intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)){
+ int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+ BluetoothAdapter.ERROR);
+ enabled = (state == BluetoothAdapter.STATE_ON);
+ }
+
+ if(intent.getAction().equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)){
+ int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
+ BluetoothAdapter.STATE_DISCONNECTED);
+ connected = (state == BluetoothAdapter.STATE_CONNECTED);
+ }
+ applyBluetoothChanges();
+ }
+
+ void checkBluetoothState() {
+ enabled = mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON;
+ connected = mBluetoothAdapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED;
+ }
+
+ private void applyBluetoothChanges(){
+ if(enabled){
+ if(connected){
+ mDrawable = R.drawable.ic_qs_bluetooth_on;
+ }else{
+ mDrawable = R.drawable.ic_qs_bluetooth_not_connected;
+ }
+ mLabel = mContext.getString(R.string.quick_settings_bluetooth_label);
+ }else{
+ mDrawable = R.drawable.ic_qs_bluetooth_off;
+ mLabel = mContext.getString(R.string.quick_settings_bluetooth_off_label);
+ }
+ updateQuickSettings();
+ }
+
+ @Override
+ void onPostCreate() {
+ BluetoothController controller = new BluetoothController(mContext);
+ controller.addStateChangedCallback(this);
+ checkBluetoothState();
+ applyBluetoothChanges();
+ super.onPostCreate();
+ }
+
+ @Override
+ public void onBluetoothStateChange(boolean on) {
+ this.enabled = on;
+ applyBluetoothChanges();
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/BrightnessTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/BrightnessTile.java
new file mode 100644
index 0000000..90f0c7e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/BrightnessTile.java
@@ -0,0 +1,145 @@
+package com.android.systemui.quicksettings;
+
+import android.app.Dialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.policy.BrightnessController;
+import com.android.systemui.statusbar.policy.BrightnessController.BrightnessStateChangeCallback;
+import com.android.systemui.statusbar.policy.ToggleSlider;
+
+public class BrightnessTile extends QuickSettingsTile implements BrightnessStateChangeCallback {
+
+ private final int mBrightnessDialogLongTimeout;
+ private final int mBrightnessDialogShortTimeout;
+ private Dialog mBrightnessDialog;
+ private BrightnessController mBrightnessController;
+ private final Handler mHandler;
+ private boolean autoBrightness = true;
+
+ public BrightnessTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, final QuickSettingsController qsc, Handler handler) {
+ super(context, inflater, container, qsc);
+
+ mHandler = handler;
+
+ mBrightnessDialogLongTimeout = mContext.getResources().getInteger(R.integer.quick_settings_brightness_dialog_long_timeout);
+ mBrightnessDialogShortTimeout = mContext.getResources().getInteger(R.integer.quick_settings_brightness_dialog_short_timeout);
+
+ mOnClick = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ qsc.mBar.collapseAllPanels(true);
+ showBrightnessDialog();
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity(Settings.ACTION_DISPLAY_SETTINGS);
+ return true;
+ }
+
+ };
+
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS)
+ , this);
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System
+ .SCREEN_BRIGHTNESS_MODE), this);
+ onBrightnessLevelChanged();
+ }
+
+ private void showBrightnessDialog() {
+ if (mBrightnessDialog == null) {
+ mBrightnessDialog = new Dialog(mContext);
+ mBrightnessDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ mBrightnessDialog.setContentView(R.layout.quick_settings_brightness_dialog);
+ mBrightnessDialog.setCanceledOnTouchOutside(true);
+
+ mBrightnessController = new BrightnessController(mContext,
+ (ImageView) mBrightnessDialog.findViewById(R.id.brightness_icon),
+ (ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider));
+ mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mBrightnessController = null;
+ }
+ });
+
+ mBrightnessDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ mBrightnessDialog.getWindow().getAttributes().privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ mBrightnessDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+ }
+ if (!mBrightnessDialog.isShowing()) {
+ try {
+ WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
+ } catch (RemoteException e) {
+ }
+ mBrightnessDialog.show();
+ dismissBrightnessDialog(mBrightnessDialogLongTimeout);
+ }
+ }
+
+ private void dismissBrightnessDialog(int timeout) {
+ if (mBrightnessDialog != null) {
+ mHandler.postDelayed(mDismissBrightnessDialogRunnable, timeout);
+ }
+ }
+
+ private final Runnable mDismissBrightnessDialogRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (mBrightnessDialog != null && mBrightnessDialog.isShowing()) {
+ mBrightnessDialog.dismiss();
+ }
+ };
+ };
+
+ @Override
+ public void onBrightnessLevelChanged() {
+ int mode;
+ try {
+ mode = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+ autoBrightness =
+ (mode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ mDrawable = autoBrightness
+ ? R.drawable.ic_qs_brightness_auto_on
+ : R.drawable.ic_qs_brightness_auto_off;
+ mLabel = mContext.getString(R.string.quick_settings_brightness_label);
+ } catch (SettingNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ if(mTile != null){
+ updateQuickSettings();
+ }
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ onBrightnessLevelChanged();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/BugReportTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/BugReportTile.java
new file mode 100644
index 0000000..4ac1a0b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/BugReportTile.java
@@ -0,0 +1,107 @@
+package com.android.systemui.quicksettings;
+
+import android.app.ActivityManagerNative;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class BugReportTile extends QuickSettingsTile{
+
+ private boolean enabled = false;
+ private final Handler mHandler;
+
+ public BugReportTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container,
+ QuickSettingsController qsc, Handler handler) {
+ super(context, inflater, container, qsc);
+
+ mHandler = handler;
+ mLabel = mContext.getString(R.string.quick_settings_report_bug);
+ mDrawable = com.android.internal.R.drawable.stat_sys_adb;
+
+ try {
+ enabled = (Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.BUGREPORT_IN_POWER_MENU) != 0);
+ } catch (SettingNotFoundException e) {
+ }
+
+ mOnClick = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ mQsc.mBar.collapseAllPanels(true);
+ showBugreportDialog();
+ }
+ };
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.Secure.BUGREPORT_IN_POWER_MENU), this);
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ onBugreportChanged();
+ }
+
+ public void onBugreportChanged() {
+ final ContentResolver cr = mContext.getContentResolver();
+ try {
+ enabled = (Settings.Secure.getInt(cr, Settings.Secure.BUGREPORT_IN_POWER_MENU) != 0);
+ } catch (SettingNotFoundException e) {
+ }
+ updateQuickSettings();
+ }
+
+ @Override
+ void updateQuickSettings() {
+ mTile.setVisibility(enabled ? View.VISIBLE : View.GONE);
+ super.updateQuickSettings();
+ }
+
+ private void showBugreportDialog() {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setPositiveButton(com.android.internal.R.string.report, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ // Add a little delay before executing, to give the
+ // dialog a chance to go away before it takes a
+ // screenshot.
+ mHandler.postDelayed(new Runnable() {
+ @Override public void run() {
+ try {
+ ActivityManagerNative.getDefault()
+ .requestBugReport();
+ } catch (RemoteException e) {
+ }
+ }
+ }, 500);
+ }
+ }
+ });
+ builder.setMessage(com.android.internal.R.string.bugreport_message);
+ builder.setTitle(com.android.internal.R.string.bugreport_title);
+ builder.setCancelable(true);
+ final Dialog dialog = builder.create();
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ try {
+ WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
+ } catch (RemoteException e) {
+ }
+ dialog.show();
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/GPSTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/GPSTile.java
new file mode 100644
index 0000000..04c950f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/GPSTile.java
@@ -0,0 +1,96 @@
+package com.android.systemui.quicksettings;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.location.LocationManager;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.policy.LocationController;
+import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
+
+
+public class GPSTile extends QuickSettingsTile implements LocationGpsStateChangeCallback {
+
+ private boolean enabled = false;
+ private boolean working = false;
+
+ ContentResolver mContentResolver;
+
+ public GPSTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mContentResolver = mContext.getContentResolver();
+ LocationController controller = new LocationController(mContext);
+ controller.addStateChangedCallback(this);
+
+ enabled = Settings.Secure.isLocationProviderEnabled(mContentResolver, LocationManager.GPS_PROVIDER);
+
+ mOnClick = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Settings.Secure.setLocationProviderEnabled(mContentResolver, LocationManager.GPS_PROVIDER, !enabled);
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+ return true;
+ }
+ };
+ qsc.registerAction(LocationManager.PROVIDERS_CHANGED_ACTION, this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ enabled = Settings.Secure.isLocationProviderEnabled(mContentResolver, LocationManager.GPS_PROVIDER);
+ mLabel = mContext.getString(R.string.quick_settings_gps);
+ setGenericLabel();
+ applyGPSChanges();
+ }
+
+ @Override
+ void onPostCreate() {
+ setGenericLabel();
+ applyGPSChanges();
+ super.onPostCreate();
+ }
+
+ void applyGPSChanges() {
+ if (enabled && working) {
+ mDrawable = R.drawable.ic_qs_location;
+ } else if (enabled) {
+ mDrawable = R.drawable.ic_qs_gps_on;
+ } else {
+ mDrawable = R.drawable.ic_qs_gps_off;
+ }
+ updateQuickSettings();
+ }
+
+ @Override
+ public void onLocationGpsStateChanged(boolean inUse, String description) {
+ working = inUse;
+ if (description != null) {
+ mLabel = description;
+ } else {
+ setGenericLabel();
+ }
+ applyGPSChanges();
+ }
+
+ private void setGenericLabel() {
+ mLabel = (enabled ? mContext.getString(R.string.quick_settings_gps) : mContext.getString(R.string.quick_settings_gps_off));
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/InputMethodTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/InputMethodTile.java
new file mode 100644
index 0000000..1a7ed45
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/InputMethodTile.java
@@ -0,0 +1,133 @@
+package com.android.systemui.quicksettings;
+
+import java.util.List;
+
+import android.app.PendingIntent;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class InputMethodTile extends QuickSettingsTile {
+
+ private boolean showTile = false;
+ private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
+
+ public InputMethodTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mDrawable = R.drawable.ic_qs_ime;
+
+ mOnClick = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ try {
+ mQsc.mBar.collapseAllPanels(true);
+ Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+ pendingIntent.send();
+ } catch (Exception e) {}
+ }
+ };
+
+ }
+
+ public void toggleVisibility(boolean show) {
+ InputMethodManager imm =
+ (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
+ List<InputMethodInfo> imis = imm.getInputMethodList();
+
+ showTile = (show && needsToShowImeSwitchOngoingNotification(imm));
+ mLabel = getCurrentInputMethodName(mContext, mContext.getContentResolver(),
+ imm, imis, mContext.getPackageManager());
+ updateQuickSettings();
+ }
+
+ private static String getCurrentInputMethodName(Context context, ContentResolver resolver,
+ InputMethodManager imm, List<InputMethodInfo> imis, PackageManager pm) {
+ if (resolver == null || imis == null) return null;
+ final String currentInputMethodId = Settings.Secure.getString(resolver,
+ Settings.Secure.DEFAULT_INPUT_METHOD);
+ if (TextUtils.isEmpty(currentInputMethodId)) return null;
+ for (InputMethodInfo imi : imis) {
+ if (currentInputMethodId.equals(imi.getId())) {
+ final InputMethodSubtype subtype = imm.getCurrentInputMethodSubtype();
+ final CharSequence summary = subtype != null
+ ? subtype.getDisplayName(context, imi.getPackageName(),
+ imi.getServiceInfo().applicationInfo)
+ : context.getString(R.string.quick_settings_ime_label);
+ return summary.toString();
+ }
+ }
+ return null;
+ }
+
+ private boolean needsToShowImeSwitchOngoingNotification(InputMethodManager imm) {
+ List<InputMethodInfo> imis = imm.getEnabledInputMethodList();
+ final int N = imis.size();
+ if (N > 2) return true;
+ if (N < 1) return false;
+ int nonAuxCount = 0;
+ int auxCount = 0;
+ InputMethodSubtype nonAuxSubtype = null;
+ InputMethodSubtype auxSubtype = null;
+ for(int i = 0; i < N; ++i) {
+ final InputMethodInfo imi = imis.get(i);
+ final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi,
+ true);
+ final int subtypeCount = subtypes.size();
+ if (subtypeCount == 0) {
+ ++nonAuxCount;
+ } else {
+ for (int j = 0; j < subtypeCount; ++j) {
+ final InputMethodSubtype subtype = subtypes.get(j);
+ if (!subtype.isAuxiliary()) {
+ ++nonAuxCount;
+ nonAuxSubtype = subtype;
+ } else {
+ ++auxCount;
+ auxSubtype = subtype;
+ }
+ }
+ }
+ }
+ if (nonAuxCount > 1 || auxCount > 1) {
+ return true;
+ } else if (nonAuxCount == 1 && auxCount == 1) {
+ if (nonAuxSubtype != null && auxSubtype != null
+ && (nonAuxSubtype.getLocale().equals(auxSubtype.getLocale())
+ || auxSubtype.overridesImplicitlyEnabledSubtype()
+ || nonAuxSubtype.overridesImplicitlyEnabledSubtype())
+ && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ void updateQuickSettings() {
+ TextView tv = (TextView) mTile.findViewById(R.id.tile_textview);
+ tv.setText(mLabel);
+ tv.setCompoundDrawablesWithIntrinsicBounds(0, mDrawable, 0, 0);
+ mTile.setVisibility(showTile ? View.VISIBLE : View.GONE);
+ super.updateQuickSettings();
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTile.java
new file mode 100644
index 0000000..2338498
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTile.java
@@ -0,0 +1,158 @@
+package com.android.systemui.quicksettings;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+
+public class MobileNetworkTile extends QuickSettingsTile implements NetworkSignalChangedCallback{
+
+ private int mDataTypeIconId;
+ private String dataContentDescription;
+ private String signalContentDescription;
+ private boolean wifiOn = false;
+
+ private ConnectivityManager mCm;
+
+ private int NO_OVERLAY = 0;
+ private int DISABLED_OVERLAY = -1;
+
+ public MobileNetworkTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mTileLayout = R.layout.quick_settings_tile_rssi;
+ mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!mCm.getMobileDataEnabled()) {
+ updateOverlayImage(NO_OVERLAY); // None, onMobileDataSignalChanged will set final overlay image
+ mCm.setMobileDataEnabled(true);
+ } else {
+ updateOverlayImage(DISABLED_OVERLAY);
+ mCm.setMobileDataEnabled(false);
+ }
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(
+ "com.android.settings",
+ "com.android.settings.Settings$DataUsageSummaryActivity"));
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+ }
+
+ @Override
+ void onPostCreate() {
+ NetworkController controller = new NetworkController(mContext);
+ controller.addNetworkSignalChangedCallback(this);
+ super.onPostCreate();
+ }
+
+ @Override
+ public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
+ String wifitSignalContentDescriptionId, String description) {
+ wifiOn = enabled;
+ }
+
+ @Override
+ public void onMobileDataSignalChanged(boolean enabled,
+ int mobileSignalIconId, String mobileSignalContentDescriptionId,
+ int dataTypeIconId, String dataTypeContentDescriptionId,
+ String description) {
+ if (deviceSupportsTelephony()) {
+ // TODO: If view is in awaiting state, disable
+ Resources r = mContext.getResources();
+ mDrawable = enabled && (mobileSignalIconId > 0)
+ ? mobileSignalIconId
+ : R.drawable.ic_qs_signal_no_signal;
+ signalContentDescription = enabled && (mobileSignalIconId > 0)
+ ? signalContentDescription
+ : r.getString(R.string.accessibility_no_signal);
+
+ // Determine the overlay image
+ if (enabled && (dataTypeIconId > 0) && !wifiOn) {
+ mDataTypeIconId = dataTypeIconId;
+ } else if (!mCm.getMobileDataEnabled()) {
+ mDataTypeIconId = DISABLED_OVERLAY;
+ } else {
+ mDataTypeIconId = NO_OVERLAY;
+ }
+
+ dataContentDescription = enabled && (dataTypeIconId > 0) && !wifiOn
+ ? dataContentDescription
+ : r.getString(R.string.accessibility_no_data);
+ mLabel = enabled
+ ? removeTrailingPeriod(description)
+ : r.getString(R.string.quick_settings_rssi_emergency_only);
+ updateQuickSettings();
+ }
+ }
+
+ @Override
+ public void onAirplaneModeChanged(boolean enabled) {
+ // TODO Auto-generated method stub
+ }
+
+ boolean deviceSupportsTelephony() {
+ PackageManager pm = mContext.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+ }
+
+ @Override
+ void updateQuickSettings() {
+ TextView tv = (TextView) mTile.findViewById(R.id.rssi_textview);
+ ImageView iv = (ImageView) mTile.findViewById(R.id.rssi_image);
+
+ iv.setImageResource(mDrawable);
+ updateOverlayImage(mDataTypeIconId);
+ tv.setText(mLabel);
+ mTile.setContentDescription(mContext.getResources().getString(
+ R.string.accessibility_quick_settings_mobile,
+ signalContentDescription, dataContentDescription,
+ mLabel));
+ }
+
+ void updateOverlayImage(int dataTypeIconId) {
+ ImageView iov = (ImageView) mTile.findViewById(R.id.rssi_overlay_image);
+ if (dataTypeIconId > 0) {
+ iov.setImageResource(dataTypeIconId);
+ } else if (dataTypeIconId == DISABLED_OVERLAY) {
+ iov.setImageResource(R.drawable.ic_qs_signal_data_off);
+ } else {
+ iov.setImageDrawable(null);
+ }
+ }
+
+ // Remove the period from the network name
+ public static String removeTrailingPeriod(String string) {
+ if (string == null) return null;
+ final int length = string.length();
+ if (string.endsWith(".")) {
+ string.substring(0, length - 1);
+ }
+ return string;
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTypeTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTypeTile.java
new file mode 100644
index 0000000..a18d080
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/MobileNetworkTypeTile.java
@@ -0,0 +1,198 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.internal.telephony.Phone;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class MobileNetworkTypeTile extends QuickSettingsTile {
+
+ private static final String TAG = "NetworkModeQuickSettings";
+
+ // retrieved from Phone.apk
+ private static final String ACTION_NETWORK_MODE_CHANGED = "com.android.internal.telephony.NETWORK_MODE_CHANGED";
+ private static final String ACTION_MODIFY_NETWORK_MODE = "com.android.internal.telephony.MODIFY_NETWORK_MODE";
+ private static final String EXTRA_NETWORK_MODE = "networkMode";
+
+ private static final int STATE_2G_AND_3G = 1;
+ private static final int STATE_2G_ONLY = 2;
+ private static final int STATE_TURNING_ON = 3;
+ private static final int STATE_TURNING_OFF = 4;
+ private static final int STATE_INTERMEDIATE = 5;
+ private static final int STATE_UNEXPECTED = 6;
+ private static final int NO_NETWORK_MODE_YET = -99;
+ private static final int NETWORK_MODE_UNKNOWN = -100;
+
+ private static final int CM_MODE_3G2G = 0;
+ private static final int CM_MODE_3GONLY = 1;
+ private static final int CM_MODE_BOTH = 2;
+
+ private int mMode = NO_NETWORK_MODE_YET;
+ private int mIntendedMode = NO_NETWORK_MODE_YET;
+ private int mInternalState = STATE_INTERMEDIATE;
+ private int mState;
+
+ public MobileNetworkTypeTile(Context context,
+ LayoutInflater inflater, QuickSettingsContainerView container,
+ QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ updateState();
+
+ mOnClick = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int currentMode = getCurrentCMMode();
+
+ Intent intent = new Intent(ACTION_MODIFY_NETWORK_MODE);
+ switch (mMode) {
+ case Phone.NT_MODE_WCDMA_PREF:
+ case Phone.NT_MODE_GSM_UMTS:
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_GSM_ONLY);
+ mInternalState = STATE_TURNING_OFF;
+ mIntendedMode = Phone.NT_MODE_GSM_ONLY;
+ break;
+ case Phone.NT_MODE_WCDMA_ONLY:
+ if (currentMode == CM_MODE_3GONLY) {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_GSM_ONLY);
+ mInternalState = STATE_TURNING_OFF;
+ mIntendedMode = Phone.NT_MODE_GSM_ONLY;
+ } else {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF);
+ mInternalState = STATE_TURNING_ON;
+ mIntendedMode = Phone.NT_MODE_WCDMA_PREF;
+ }
+ break;
+ case Phone.NT_MODE_GSM_ONLY:
+ if (currentMode == CM_MODE_3GONLY || currentMode == CM_MODE_BOTH) {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_WCDMA_ONLY);
+ mInternalState = STATE_TURNING_ON;
+ mIntendedMode = Phone.NT_MODE_WCDMA_ONLY;
+ } else {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF);
+ mInternalState = STATE_TURNING_ON;
+ mIntendedMode = Phone.NT_MODE_WCDMA_PREF;
+ }
+ break;
+ }
+
+ mMode = NETWORK_MODE_UNKNOWN;
+ mContext.sendBroadcast(intent);
+ }
+ };
+
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.phone", "com.android.phone.Settings");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+
+ qsc.registerAction(ACTION_NETWORK_MODE_CHANGED, this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getExtras() != null) {
+ mMode = intent.getExtras().getInt(EXTRA_NETWORK_MODE);
+ //Update to actual state
+ mIntendedMode = mMode;
+ }
+
+ //need to clear intermediate states and update the tile
+ mInternalState = networkModeToState();
+ applyNetworkTypeChanges();
+ }
+
+ private void applyNetworkTypeChanges(){
+ updateState();
+ updateQuickSettings();
+ }
+
+ protected void updateState() {
+ mMode = get2G3G(mContext);
+ mState = networkModeToState();
+
+ mLabel = mContext.getString(R.string.quick_settings_network_type);
+
+ switch (mState) {
+ case STATE_UNEXPECTED:
+ mDrawable = R.drawable.ic_qs_unexpected_network;
+ break;
+ case STATE_2G_ONLY:
+ mDrawable = R.drawable.ic_qs_2g_on;
+ break;
+ case STATE_2G_AND_3G:
+ if (mMode == Phone.NT_MODE_WCDMA_ONLY) {
+ mDrawable = R.drawable.ic_qs_3g_on;
+ } else {
+ mDrawable = R.drawable.ic_qs_2g3g_on;
+ }
+ break;
+ case STATE_INTERMEDIATE:
+ if (mInternalState == STATE_TURNING_ON) {
+ if (mIntendedMode == Phone.NT_MODE_WCDMA_ONLY) {
+ mDrawable = R.drawable.ic_qs_3g_on;
+ } else {
+ mDrawable = R.drawable.ic_qs_2g3g_on;
+ }
+ } else {
+ mDrawable = R.drawable.ic_qs_2g_on;
+ }
+ break;
+ }
+ }
+
+ private static int get2G3G(Context context) {
+ int state = 99;
+ try {
+ state = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.PREFERRED_NETWORK_MODE);
+ } catch (SettingNotFoundException e) {
+ // Do nothing
+ }
+ return state;
+ }
+
+ private int networkModeToState() {
+ if (mInternalState == STATE_TURNING_ON || mInternalState == STATE_TURNING_OFF) {
+ return STATE_INTERMEDIATE;
+ }
+
+ switch (mMode) {
+ case Phone.NT_MODE_WCDMA_PREF:
+ case Phone.NT_MODE_WCDMA_ONLY:
+ case Phone.NT_MODE_GSM_UMTS:
+ return STATE_2G_AND_3G;
+ case Phone.NT_MODE_GSM_ONLY:
+ return STATE_2G_ONLY;
+ case Phone.NT_MODE_CDMA:
+ case Phone.NT_MODE_CDMA_NO_EVDO:
+ case Phone.NT_MODE_EVDO_NO_CDMA:
+ case Phone.NT_MODE_GLOBAL:
+ // need to check what is going on
+ Log.d(TAG, "Unexpected network mode (" + mMode + ")");
+ return STATE_UNEXPECTED;
+ }
+ return STATE_INTERMEDIATE;
+ }
+
+ private int getCurrentCMMode() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_NETWORK_MODE,
+ CM_MODE_3G2G);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/NfcTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/NfcTile.java
new file mode 100644
index 0000000..efbc9a0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/NfcTile.java
@@ -0,0 +1,102 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+
+public class NfcTile extends QuickSettingsTile {
+
+ private static String TAG = "NfcTile";
+ private static NfcAdapter mNfcAdapter;
+ private static final int NFC_ADAPTER_UNKNOWN = -100;
+
+ public NfcTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container,
+ QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ setTileState(getNfcState());
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleState();
+ applyNfcChanges();
+ }
+ };
+
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent("android.settings.NFC_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+
+ qsc.registerAction(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED, this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ applyNfcChanges();
+ }
+
+ private void applyNfcChanges() {
+ setTileState(getNfcState());
+ updateQuickSettings();
+ }
+
+ protected void toggleState() {
+ int state = getNfcState();
+ switch (state) {
+ case NfcAdapter.STATE_TURNING_ON:
+ case NfcAdapter.STATE_ON:
+ mNfcAdapter.disable();
+ break;
+ case NfcAdapter.STATE_TURNING_OFF:
+ case NfcAdapter.STATE_OFF:
+ mNfcAdapter.enable();
+ break;
+ }
+ }
+
+ private void setTileState(int state) {
+
+ switch (state) {
+ case NfcAdapter.STATE_TURNING_ON:
+ case NfcAdapter.STATE_ON:
+ mDrawable = R.drawable.ic_qs_nfc_on;
+ mLabel = mContext.getString(R.string.quick_settings_nfc);
+ break;
+ case NfcAdapter.STATE_TURNING_OFF:
+ case NfcAdapter.STATE_OFF:
+ default:
+ mDrawable = R.drawable.ic_qs_nfc_off;
+ mLabel = mContext.getString(R.string.quick_settings_nfc_off);
+ break;
+ }
+ }
+
+ private int getNfcState() {
+ if (mNfcAdapter == null) {
+ try {
+ mNfcAdapter = NfcAdapter.getNfcAdapter(mContext);
+ } catch (UnsupportedOperationException e) {
+ return NFC_ADAPTER_UNKNOWN;
+ }
+ }
+ return mNfcAdapter.getAdapterState();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/PreferencesTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/PreferencesTile.java
new file mode 100644
index 0000000..fbfeb65
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/PreferencesTile.java
@@ -0,0 +1,29 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class PreferencesTile extends QuickSettingsTile{
+
+ public PreferencesTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mDrawable = R.drawable.ic_qs_settings;
+ mLabel = mContext.getString(R.string.quick_settings_settings_label);
+
+ mOnClick = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
+ }
+ };
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/ProfileTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/ProfileTile.java
new file mode 100644
index 0000000..f65c204
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/ProfileTile.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2012 Sven Dawitz for the CyanogenMod 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.systemui.quicksettings;
+
+import android.app.AlertDialog;
+import android.app.Profile;
+import android.app.ProfileManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.server.ProfileManagerService;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+import java.util.UUID;
+
+public class ProfileTile extends QuickSettingsTile {
+ private Profile mChosenProfile;
+ private ProfileManager mProfileManager;
+
+ public ProfileTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container,
+ QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ qsc.registerAction(ProfileManagerService.INTENT_ACTION_PROFILE_SELECTED, this);
+
+ mProfileManager = (ProfileManager) mContext.getSystemService(Context.PROFILE_SERVICE);
+ mDrawable = R.drawable.ic_qs_profiles;
+
+ mLabel = mProfileManager.getActiveProfile().getName();
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ createProfileDialog();
+ }
+ };
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent("android.settings.PROFILES_SETTINGS");
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mLabel = mProfileManager.getActiveProfile().getName();
+ updateQuickSettings();
+ }
+
+ // copied from com.android.internal.policy.impl.GlobalActions
+ private void createProfileDialog() {
+ final ProfileManager profileManager = (ProfileManager) mContext
+ .getSystemService(Context.PROFILE_SERVICE);
+
+ final Profile[] profiles = profileManager.getProfiles();
+ UUID activeProfile = profileManager.getActiveProfile().getUuid();
+ final CharSequence[] names = new CharSequence[profiles.length];
+
+ int i = 0;
+ int checkedItem = 0;
+
+ for (Profile profile : profiles) {
+ if (profile.getUuid().equals(activeProfile)) {
+ checkedItem = i;
+ mChosenProfile = profile;
+ }
+ names[i++] = profile.getName();
+ }
+
+ final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
+
+ AlertDialog dialog = ab.setSingleChoiceItems(names, checkedItem,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which < 0)
+ return;
+ mChosenProfile = profiles[which];
+ profileManager.setActiveProfile(mChosenProfile.getUuid());
+ dialog.cancel();
+ }
+ }).create();
+ mStatusbarService.animateCollapsePanels();
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+ dialog.show();
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java
new file mode 100644
index 0000000..5f0538e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/QuickSettingsTile.java
@@ -0,0 +1,108 @@
+package com.android.systemui.quicksettings;
+
+import android.app.ActivityManagerNative;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsTileView;
+
+public class QuickSettingsTile implements OnClickListener {
+
+ protected final Context mContext;
+ protected final ViewGroup mContainerView;
+ protected final LayoutInflater mInflater;
+ protected QuickSettingsTileView mTile;
+ protected OnClickListener mOnClick;
+ protected OnLongClickListener mOnLongClick;
+ protected int mTileLayout;
+ protected int mDrawable;
+ protected String mLabel;
+ protected PhoneStatusBar mStatusbarService;
+ protected QuickSettingsController mQsc;
+
+ public QuickSettingsTile(Context context, LayoutInflater inflater, QuickSettingsContainerView container, QuickSettingsController qsc) {
+ mContext = context;
+ mContainerView = container;
+ mInflater = inflater;
+ mDrawable = R.drawable.ic_notifications;
+ mLabel = mContext.getString(R.string.quick_settings_label_enabled);
+ mStatusbarService = qsc.mStatusBarService;
+ mQsc = qsc;
+ mTileLayout = R.layout.quick_settings_tile_generic;
+ }
+
+ public void setupQuickSettingsTile(){
+ createQuickSettings();
+ onPostCreate();
+ updateQuickSettings();
+ mTile.setOnClickListener(this);
+ mTile.setOnLongClickListener(mOnLongClick);
+ }
+
+ void createQuickSettings(){
+ mTile = (QuickSettingsTileView) mInflater.inflate(R.layout.quick_settings_tile, mContainerView, false);
+ mTile.setContent(mTileLayout, mInflater);
+ mContainerView.addView(mTile);
+ }
+
+ void onPostCreate(){}
+
+ public void onReceive(Context context, Intent intent) {}
+
+ public void onChangeUri(ContentResolver resolver, Uri uri) {}
+
+ void updateQuickSettings(){
+ TextView tv = (TextView) mTile.findViewById(R.id.tile_textview);
+ tv.setCompoundDrawablesWithIntrinsicBounds(0, mDrawable, 0, 0);
+ tv.setText(mLabel);
+ }
+
+ void startSettingsActivity(String action){
+ Intent intent = new Intent(action);
+ startSettingsActivity(intent);
+ }
+
+ void startSettingsActivity(Intent intent) {
+ startSettingsActivity(intent, true);
+ }
+
+ private void startSettingsActivity(Intent intent, boolean onlyProvisioned) {
+ if (onlyProvisioned && !mStatusbarService.isDeviceProvisioned()) return;
+ try {
+ // Dismiss the lock screen when Settings starts.
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ }
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ mStatusbarService.animateCollapsePanels();
+ }
+
+ @Override
+ public final void onClick(View v) {
+ mOnClick.onClick(v);
+ ContentResolver resolver = mContext.getContentResolver();
+ boolean shouldCollapse = Settings.System.getInt(resolver, Settings.System.QS_COLLAPSE_PANEL, 0) == 1;
+ if (shouldCollapse) {
+ mQsc.mBar.collapseAllPanels(true);
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/QuietHoursTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/QuietHoursTile.java
new file mode 100644
index 0000000..52a1c4e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/QuietHoursTile.java
@@ -0,0 +1,61 @@
+package com.android.systemui.quicksettings;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class QuietHoursTile extends QuickSettingsTile {
+
+ private boolean mEnabled;
+
+ public QuietHoursTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+ updateTileState();
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Settings.System.putIntForUser(mContext.getContentResolver(), Settings.System.QUIET_HOURS_ENABLED,
+ mEnabled ? 0 : 1, UserHandle.USER_CURRENT);
+ }
+ };
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.settings", "com.android.settings.Settings$QuietHoursSettingsActivity");
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System.QUIET_HOURS_ENABLED), this);
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ updateTileState();
+ updateQuickSettings();
+ }
+
+ private void updateTileState() {
+ mEnabled = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.QUIET_HOURS_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
+ if (mEnabled) {
+ mDrawable = R.drawable.ic_qs_quiet_hours_on;
+ mLabel = mContext.getString(R.string.quick_settings_quiethours);
+ } else {
+ mDrawable = R.drawable.ic_qs_quiet_hours_off;
+ mLabel = mContext.getString(R.string.quick_settings_quiethours_off);
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/RingerModeTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/RingerModeTile.java
new file mode 100644
index 0000000..2a6139c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/RingerModeTile.java
@@ -0,0 +1,217 @@
+package com.android.systemui.quicksettings;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+
+public class RingerModeTile extends QuickSettingsTile {
+
+ private static final String SEPARATOR = "OV=I=XseparatorX=I=VO";
+
+ // Define the available ringer modes
+ private final Ringer mSilentRinger = new Ringer(AudioManager.RINGER_MODE_SILENT, false);
+ private final Ringer mVibrateRinger = new Ringer(AudioManager.RINGER_MODE_VIBRATE, true);
+ private final Ringer mSoundRinger = new Ringer(AudioManager.RINGER_MODE_NORMAL, false);
+ private final Ringer mSoundVibrateRinger = new Ringer(AudioManager.RINGER_MODE_NORMAL, true);
+ private final Ringer[] mRingers = new Ringer[] {
+ mSilentRinger, mVibrateRinger, mSoundRinger, mSoundVibrateRinger
+ };
+
+ private int mRingersIndex;
+ private int[] mRingerValues = new int[] {
+ 0, 1, 2, 3
+ };
+ private int mRingerValuesIndex;
+
+ private AudioManager mAudioManager;
+ private Handler mHandler;
+
+ public RingerModeTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ mHandler = new Handler();
+
+ // Load the available ringer modes
+ updateSettings(mContext.getContentResolver());
+
+ // Make sure we show the initial state correctly
+ updateState();
+
+ // Tile actions
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleState();
+ applyVibrationChanges();
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity(android.provider.Settings.ACTION_SOUND_SETTINGS);
+ return true;
+ }
+ };
+ qsc.registerAction(AudioManager.RINGER_MODE_CHANGED_ACTION, this);
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System.EXPANDED_RING_MODE)
+ , this);
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING)
+ , this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ applyVibrationChanges();
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ updateSettings(mContext.getContentResolver());
+ applyVibrationChanges();
+ }
+
+ private void applyVibrationChanges(){
+ updateState();
+ updateQuickSettings();
+ }
+
+ protected void updateState() {
+ // The title does not change
+ mLabel = mContext.getString(R.string.quick_settings_ringer_normal);
+
+ // The icon will change depending on index
+ findCurrentState();
+ switch (mRingersIndex) {
+ case 0:
+ mDrawable = R.drawable.ic_qs_ring_off;
+ break;
+ case 1:
+ mDrawable = R.drawable.ic_qs_vibrate_on;
+ break;
+ case 2:
+ mDrawable = R.drawable.ic_qs_ring_on;
+ break;
+ case 3:
+ mDrawable = R.drawable.ic_qs_ring_vibrate_on;
+ break;
+ }
+
+ for (int i = 0; i < mRingerValues.length; i++) {
+ if (mRingersIndex == mRingerValues[i]) {
+ mRingerValuesIndex = i;
+ break;
+ }
+ }
+ }
+
+ protected void toggleState() {
+ mRingerValuesIndex++;
+ if (mRingerValuesIndex > mRingerValues.length - 1) {
+ mRingerValuesIndex = 0;
+ }
+
+ mRingersIndex = mRingerValues[mRingerValuesIndex];
+ if (mRingersIndex > mRingers.length - 1) {
+ mRingersIndex = 0;
+ }
+
+ Ringer ringer = mRingers[mRingersIndex];
+ ringer.execute(mContext);
+ }
+
+ public String[] parseStoredValue(CharSequence val) {
+ if (TextUtils.isEmpty(val)) {
+ return null;
+ } else {
+ return val.toString().split(SEPARATOR);
+ }
+ }
+
+ private void updateSettings(ContentResolver resolver) {
+ String[] modes = parseStoredValue(Settings.System.getString(
+ resolver, Settings.System.EXPANDED_RING_MODE));
+ if (modes == null || modes.length == 0) {
+ mRingerValues = new int[] {
+ 0, 1, 2, 3
+ };
+ } else {
+ mRingerValues = new int[modes.length];
+ for (int i = 0; i < modes.length; i++) {
+ mRingerValues[i] = Integer.valueOf(modes[i]);
+ }
+ }
+ }
+
+ private void findCurrentState() {
+ ContentResolver resolver = mContext.getContentResolver();
+ boolean vibrateWhenRinging = Settings.System.getInt(resolver,
+ Settings.System.VIBRATE_WHEN_RINGING, 0) == 1;
+ int ringerMode = mAudioManager.getRingerMode();
+
+ Ringer ringer = new Ringer(ringerMode, vibrateWhenRinging);
+ for (int i = 0; i < mRingers.length; i++) {
+ if (mRingers[i].equals(ringer)) {
+ mRingersIndex = i;
+ break;
+ }
+ }
+ }
+
+ private class Ringer {
+ final boolean mVibrateWhenRinging;
+ final int mRingerMode;
+
+ Ringer( int ringerMode, boolean vibrateWhenRinging) {
+ mVibrateWhenRinging = vibrateWhenRinging;
+ mRingerMode = ringerMode;
+ }
+
+ void execute(Context context) {
+ // If we are setting a vibrating state, vibrate to indicate it
+ if (mVibrateWhenRinging) {
+ Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ vibrator.vibrate(250);
+ }
+
+ // Set the desired state
+ ContentResolver resolver = context.getContentResolver();
+ Settings.System.putInt(resolver, Settings.System.VIBRATE_WHEN_RINGING,
+ (mVibrateWhenRinging ? 1 : 0));
+ mAudioManager.setRingerMode(mRingerMode);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ if (o.getClass() != getClass()) {
+ return false;
+ }
+ Ringer r = (Ringer) o;
+ if ((mRingerMode == AudioManager.RINGER_MODE_SILENT || mRingerMode == AudioManager.RINGER_MODE_VIBRATE)
+ && (r.mRingerMode == mRingerMode))
+ return true;
+ return r.mVibrateWhenRinging == mVibrateWhenRinging
+ && r.mRingerMode == mRingerMode;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/ScreenTimeoutTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/ScreenTimeoutTile.java
new file mode 100644
index 0000000..b16b2b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/ScreenTimeoutTile.java
@@ -0,0 +1,168 @@
+package com.android.systemui.quicksettings;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.provider.Settings;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+import android.widget.Toast;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+
+public class ScreenTimeoutTile extends QuickSettingsTile {
+
+ // timeout values
+ private static final int SCREEN_TIMEOUT_MIN = 15000;
+ private static final int SCREEN_TIMEOUT_LOW = 30000;
+ private static final int SCREEN_TIMEOUT_NORMAL = 60000;
+ private static final int SCREEN_TIMEOUT_HIGH = 120000;
+ private static final int SCREEN_TIMEOUT_MAX = 300000;
+
+ // cm modes
+ private static final int CM_MODE_15_60_300 = 0;
+ private static final int CM_MODE_30_120_300 = 1;
+
+ public ScreenTimeoutTile(Context context,
+ LayoutInflater inflater, QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ updateTileState();
+
+ mOnClick = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleState();
+ applyTimeoutChanges();
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent("android.settings.DISPLAY_SETTINGS");
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT)
+ , this);
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ applyTimeoutChanges();
+ }
+
+ void applyTimeoutChanges() {
+ updateTileState();
+ updateQuickSettings();
+ }
+
+ protected void updateTileState() {
+ int timeout = getScreenTimeout();
+ mLabel = makeTimeoutSummaryString(mContext, timeout);
+ mDrawable = R.drawable.ic_qs_screen_timeout_off;
+
+ /* TODO: Determine if we need an on and off state
+ if (timeout <= SCREEN_TIMEOUT_LOW) {
+ mDrawable = R.drawable.ic_qs_screen_timeout_off;
+ } else if (timeout <= SCREEN_TIMEOUT_HIGH) {
+ mDrawable = R.drawable.ic_qs_screen_timeout_off;
+ } else {
+ mDrawable = R.drawable.ic_qs_screen_timeout_on;
+ }
+ */
+ }
+
+ protected void toggleState() {
+ int screenTimeout = getScreenTimeout();
+ int currentMode = getCurrentCMMode();
+
+ if (screenTimeout < SCREEN_TIMEOUT_MIN) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_MIN;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_LOW;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_LOW) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_NORMAL;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_LOW;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_NORMAL) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_NORMAL;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_HIGH;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_HIGH) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_MAX;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_HIGH;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_MAX) {
+ screenTimeout = SCREEN_TIMEOUT_MAX;
+ } else if (currentMode == CM_MODE_30_120_300) {
+ screenTimeout = SCREEN_TIMEOUT_LOW;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_MIN;
+ }
+
+ Settings.System.putInt(
+ mContext.getContentResolver(),
+ Settings.System.SCREEN_OFF_TIMEOUT, screenTimeout);
+ }
+
+ private String makeTimeoutSummaryString(Context context, int timeout) {
+ Resources res = context.getResources();
+ int resId;
+
+ /* ms -> seconds */
+ timeout /= 1000;
+
+ if (timeout >= 60 && timeout % 60 == 0) {
+ /* seconds -> minutes */
+ timeout /= 60;
+ if (timeout >= 60 && timeout % 60 == 0) {
+ /* minutes -> hours */
+ timeout /= 60;
+ resId = timeout == 1
+ ? com.android.internal.R.string.hour
+ : com.android.internal.R.string.hours;
+ } else {
+ resId = timeout == 1
+ ? com.android.internal.R.string.minute
+ : com.android.internal.R.string.minutes;
+ }
+ } else {
+ resId = timeout == 1
+ ? com.android.internal.R.string.second
+ : com.android.internal.R.string.seconds;
+ }
+
+ return res.getString(R.string.quick_settings_screen_timeout_summary,
+ timeout, res.getString(resId));
+ }
+
+ private int getScreenTimeout() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_OFF_TIMEOUT, 0);
+ }
+
+ private int getCurrentCMMode() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_SCREENTIMEOUT_MODE, CM_MODE_15_60_300);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/SleepScreenTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/SleepScreenTile.java
new file mode 100644
index 0000000..2daec1a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/SleepScreenTile.java
@@ -0,0 +1,41 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+
+public class SleepScreenTile extends QuickSettingsTile {
+
+ private PowerManager pm;
+
+ public SleepScreenTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+ mDrawable = R.drawable.ic_qs_sleep;
+ mLabel = mContext.getString(R.string.quick_settings_screen_sleep);
+ pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mOnClick = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ pm.goToSleep(SystemClock.uptimeMillis());
+ }
+ };
+ mOnLongClick = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity("android.settings.DISPLAY_SETTINGS");
+ return true;
+ }
+ };
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/SyncTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/SyncTile.java
new file mode 100644
index 0000000..4ba31e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/SyncTile.java
@@ -0,0 +1,102 @@
+package com.android.systemui.quicksettings;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncStatusObserver;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class SyncTile extends QuickSettingsTile {
+
+ private Object mSyncObserverHandle = null;
+ private Handler mHandler;
+ public SyncTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container,
+ QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ updateTileState();
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleState();
+ applySyncChanges();
+ }
+ };
+
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent("android.settings.SYNC_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+ mHandler = new Handler();
+ }
+
+ @Override
+ public void setupQuickSettingsTile() {
+ super.setupQuickSettingsTile();
+
+ if(mSyncObserverHandle != null) {
+ //Unregistering sync state listener
+ ContentResolver.removeStatusChangeListener(mSyncObserverHandle);
+ mSyncObserverHandle = null;
+ } else {
+ // Registering sync state listener
+ mSyncObserverHandle = ContentResolver.addStatusChangeListener(
+ ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, mSyncObserver);
+ }
+ }
+
+ private void applySyncChanges() {
+ updateTileState();
+ updateQuickSettings();
+ }
+
+ protected void toggleState() {
+ // If ON turn OFF else turn ON
+ if (getSyncState()) {
+ ContentResolver.setMasterSyncAutomatically(false);
+ } else {
+ ContentResolver.setMasterSyncAutomatically(true);
+ }
+ }
+
+ private void updateTileState() {
+
+ if (getSyncState()) {
+ mDrawable = R.drawable.ic_qs_sync_on;
+ mLabel = mContext.getString(R.string.quick_settings_sync);
+ } else {
+ mDrawable = R.drawable.ic_qs_sync_off;
+ mLabel = mContext.getString(R.string.quick_settings_sync_off);
+ }
+ }
+
+ private boolean getSyncState() {
+ return ContentResolver.getMasterSyncAutomatically();
+ }
+
+ private SyncStatusObserver mSyncObserver = new SyncStatusObserver() {
+ public void onStatusChanged(int which) {
+ // update state/view if something happened
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ applySyncChanges();
+ }
+ });
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/ToggleLockscreenTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/ToggleLockscreenTile.java
new file mode 100644
index 0000000..0a25a1f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/ToggleLockscreenTile.java
@@ -0,0 +1,81 @@
+package com.android.systemui.quicksettings;
+
+import android.app.KeyguardManager;
+import android.app.KeyguardManager.KeyguardLock;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.powerwidget.PowerButton;
+
+public class ToggleLockscreenTile extends QuickSettingsTile {
+
+ private KeyguardLock mLock = null;
+ private static final String KEY_DISABLED = "lockscreen_disabled";
+
+ private final KeyguardManager mKeyguardManager;
+ private boolean mDisabledLockscreen = false;
+ private SharedPreferences sp;
+
+ public ToggleLockscreenTile(Context context,
+ LayoutInflater inflater, QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mLabel = mContext.getString(R.string.quick_settings_lockscreen);
+
+ mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+
+ mOnClick = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ mDisabledLockscreen = !mDisabledLockscreen;
+
+ sp = mContext.getSharedPreferences("PowerButton-" + PowerButton.BUTTON_LOCKSCREEN, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putBoolean(KEY_DISABLED, mDisabledLockscreen);
+ editor.apply();
+
+ applyLockscreenChanges();
+ }
+ };
+
+ mOnLongClick = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity("android.settings.SECURITY_SETTINGS");
+ return true;
+ }
+ };
+ }
+
+ @Override
+ void onPostCreate() {
+ applyLockscreenChanges();
+ super.onPostCreate();
+ }
+
+ void applyLockscreenChanges() {
+ if (mLock == null) {
+ KeyguardManager keyguardManager = (KeyguardManager)
+ mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ mLock = keyguardManager.newKeyguardLock("PowerWidget");
+ }
+ if (mDisabledLockscreen) {
+ mDrawable = R.drawable.ic_qs_lock_screen_off;
+ mLock.disableKeyguard();
+ } else {
+ mDrawable = R.drawable.ic_qs_lock_screen_on;
+ mLock.reenableKeyguard();
+ }
+ updateQuickSettings();
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/TorchTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/TorchTile.java
new file mode 100644
index 0000000..5360b03
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/TorchTile.java
@@ -0,0 +1,64 @@
+package com.android.systemui.quicksettings;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class TorchTile extends QuickSettingsTile {
+
+ public TorchTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container,
+ QuickSettingsController qsc, Handler handler) {
+ super(context, inflater, container, qsc);
+
+ updateTileState();
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent i = new Intent("net.cactii.flash2.TOGGLE_FLASHLIGHT");
+ mContext.sendBroadcast(i);
+ }
+ };
+
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("net.cactii.flash2", "net.cactii.flash2.MainActivity");
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+
+ qsc.registerObservedContent(Settings.System.getUriFor(Settings.System.TORCH_STATE), this);
+ }
+
+ private void updateTileState() {
+ boolean enabled = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.TORCH_STATE, 0) == 1;
+
+ if(enabled) {
+ mDrawable = R.drawable.ic_qs_torch_on;
+ mLabel = mContext.getString(R.string.quick_settings_torch);
+ } else {
+ mDrawable = R.drawable.ic_qs_torch_off;
+ mLabel = mContext.getString(R.string.quick_settings_torch_off);
+ }
+ }
+
+ @Override
+ public void onChangeUri(ContentResolver resolver, Uri uri) {
+ updateTileState();
+ updateQuickSettings();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/UsbTetherTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/UsbTetherTile.java
new file mode 100644
index 0000000..ed70aa8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/UsbTetherTile.java
@@ -0,0 +1,140 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.usb.UsbManager;
+import android.net.ConnectivityManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class UsbTetherTile extends QuickSettingsTile {
+
+ private boolean mUsbTethered = false;
+ private boolean mUsbConnected = false;
+ private boolean mMassStorageActive = false;
+ private String[] mUsbRegexs;
+
+ private final String TAG = "UsbTetherTile";
+
+ public UsbTetherTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mUsbConnected) {
+ setUsbTethering(!mUsbTethered);
+ }
+ }
+ };
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.settings", "com.android.settings.TetherSettings");
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+ qsc.registerAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED, this);
+ qsc.registerAction(UsbManager.ACTION_USB_STATE, this);
+ qsc.registerAction(Intent.ACTION_MEDIA_SHARED, this);
+ qsc.registerAction(Intent.ACTION_MEDIA_UNSHARED, this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
+ Log.d(TAG,"ACTION_TETHER_STATE_CHANGED");
+ }
+
+ if (intent.getAction().equals(UsbManager.ACTION_USB_STATE)) {
+ Log.d(TAG,"ACTION_USB_STATE");
+ mUsbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
+ }
+
+ if (intent.getAction().equals(Intent.ACTION_MEDIA_SHARED)) {
+ mMassStorageActive = true;
+ }
+
+ if (intent.getAction().equals(Intent.ACTION_MEDIA_UNSHARED)) {
+ mMassStorageActive = false;
+ }
+
+ updateTileState();
+ }
+
+ @Override
+ void onPostCreate() {
+ updateTileState();
+ super.onPostCreate();
+ }
+
+ @Override
+ void updateQuickSettings() {
+ mTile.setVisibility(mUsbConnected ? View.VISIBLE : View.GONE);
+ super.updateQuickSettings();
+ }
+
+ private void updateTileState() {
+ updateState();
+ if (mUsbConnected && !mMassStorageActive) {
+ if (mUsbTethered) {
+ mDrawable = R.drawable.ic_qs_usb_tether_on;
+ mLabel = mContext.getString(R.string.quick_settings_usb_tether_on_label);
+ } else {
+ mDrawable = R.drawable.ic_qs_usb_tether_connected;
+ mLabel = mContext.getString(R.string.quick_settings_usb_tether_connected_label);
+ }
+ } else {
+ mDrawable = R.drawable.ic_qs_usb_tether_off;
+ mLabel = mContext.getString(R.string.quick_settings_usb_tether_off_label);
+ }
+ if(mTile != null) {
+ updateQuickSettings();
+ }
+ }
+
+ private void updateState() {
+ ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ mUsbRegexs = cm.getTetherableUsbRegexs();
+
+ String[] available = cm.getTetherableIfaces();
+ String[] tethered = cm.getTetheredIfaces();
+ String[] errored = cm.getTetheringErroredIfaces();
+ updateState(available, tethered, errored);
+ }
+
+ private void updateState(String[] available, String[] tethered,
+ String[] errored) {
+ updateUsbState(available, tethered, errored);
+ }
+
+
+ private void updateUsbState(String[] available, String[] tethered,
+ String[] errored) {
+
+ mUsbTethered = false;
+ for (String s : tethered) {
+ for (String regex : mUsbRegexs) {
+ if (s.matches(regex)) mUsbTethered = true;
+ }
+ }
+
+ }
+
+ private void setUsbTethering(boolean enabled) {
+ ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (cm.setUsbTethering(enabled) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ return;
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/UserTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/UserTile.java
new file mode 100644
index 0000000..2c7db9a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/UserTile.java
@@ -0,0 +1,174 @@
+package com.android.systemui.quicksettings;
+
+import android.app.ActivityManagerNative;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Profile;
+import android.util.Log;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManagerGlobal;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class UserTile extends QuickSettingsTile {
+
+ private static final String TAG = "UserTile";
+ private Drawable userAvatar;
+ private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask;
+
+ public UserTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mTileLayout = R.layout.quick_settings_tile_user;
+
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mQsc.mBar.collapseAllPanels(true);
+ final UserManager um =
+ (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ if (um.getUsers(true).size() > 1) {
+ try {
+ WindowManagerGlobal.getWindowManagerService().lockNow(
+ null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't show user switcher", e);
+ }
+ } else {
+ Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(
+ mContext, v, ContactsContract.Profile.CONTENT_URI,
+ ContactsContract.QuickContact.MODE_LARGE, null);
+ mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ }
+ }
+ };
+ qsc.registerAction(Intent.ACTION_USER_SWITCHED, this);
+ qsc.registerAction(ContactsContract.Intents.ACTION_PROFILE_CHANGED, this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ queryForUserInformation();
+ }
+
+ @Override
+ void onPostCreate() {
+ queryForUserInformation();
+ super.onPostCreate();
+ }
+
+ @Override
+ void updateQuickSettings() {
+ ImageView iv = (ImageView) mTile.findViewById(R.id.user_imageview);
+ TextView tv = (TextView) mTile.findViewById(R.id.user_textview);
+ tv.setText(mLabel);
+ iv.setImageDrawable(userAvatar);
+ }
+
+ private void queryForUserInformation() {
+ Context currentUserContext = null;
+ UserInfo userInfo = null;
+ try {
+ userInfo = ActivityManagerNative.getDefault().getCurrentUser();
+ currentUserContext = mContext.createPackageContextAsUser("android", 0,
+ new UserHandle(userInfo.id));
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Couldn't create user context", e);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't get user info", e);
+ }
+ final int userId = userInfo.id;
+ final String userName = userInfo.name;
+
+ final Context context = currentUserContext;
+ mUserInfoTask = new AsyncTask<Void, Void, Pair<String, Drawable>>() {
+ @Override
+ protected Pair<String, Drawable> doInBackground(Void... params) {
+ try {
+ // The system needs some time to change the picture, if we try to load it when we receive the broadcast, we will load the old one
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ final UserManager um =
+ (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+ // Fall back to the UserManager nickname if we can't read the name from the local
+ // profile below.
+ String name = userName;
+ Drawable avatar = null;
+ Bitmap rawAvatar = um.getUserIcon(userId);
+ if (rawAvatar != null) {
+ avatar = new BitmapDrawable(mContext.getResources(), rawAvatar);
+ } else {
+ avatar = mContext.getResources().getDrawable(R.drawable.ic_qs_default_user);
+ }
+
+ // If it's a single-user device, get the profile name, since the nickname is not
+ // usually valid
+ if (um.getUsers().size() <= 1) {
+ // Try and read the display name from the local profile
+ final Cursor cursor = context.getContentResolver().query(
+ Profile.CONTENT_URI, new String[] {Phone._ID, Phone.DISPLAY_NAME},
+ null, null, null);
+ if (cursor != null) {
+ try {
+ if (cursor.moveToFirst()) {
+ name = cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+ return new Pair<String, Drawable>(name, avatar);
+ }
+
+ @Override
+ protected void onPostExecute(Pair<String, Drawable> result) {
+ super.onPostExecute(result);
+ setUserTileInfo(result.first, result.second);
+ mUserInfoTask = null;
+ }
+ };
+ mUserInfoTask.execute();
+ }
+
+ void setUserTileInfo(String name, Drawable avatar) {
+ mLabel = name;
+ userAvatar = avatar;
+ updateQuickSettings();
+ }
+
+ void reloadUserInfo() {
+ if (mUserInfoTask != null) {
+ mUserInfoTask.cancel(false);
+ mUserInfoTask = null;
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/WiFiDisplayTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/WiFiDisplayTile.java
new file mode 100644
index 0000000..9becfa0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/WiFiDisplayTile.java
@@ -0,0 +1,64 @@
+package com.android.systemui.quicksettings;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.WifiDisplayStatus;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+
+public class WiFiDisplayTile extends QuickSettingsTile{
+
+ private boolean enabled = false;
+ private boolean connected = false;
+
+ public WiFiDisplayTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container,
+ QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mOnClick = new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ startSettingsActivity(android.provider.Settings.ACTION_WIFI_DISPLAY_SETTINGS);
+ }
+ };
+ qsc.registerAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED, this);
+ applyWiFiDisplayChanges();
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
+ enabled = status.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON;
+ connected = status.getActiveDisplay() != null;
+ applyWiFiDisplayChanges();
+ }
+
+ private void applyWiFiDisplayChanges() {
+ if(enabled && connected) {
+ mLabel = mContext.getString(R.string.quick_settings_wifi_display_label);
+ mDrawable = R.drawable.ic_qs_remote_display_connected;
+ }else{
+ mLabel = mContext.getString(R.string.quick_settings_wifi_display_no_connection_label);
+ mDrawable = R.drawable.ic_qs_remote_display;
+ }
+ if(mTile != null) {
+ updateQuickSettings();
+ }
+ }
+
+ @Override
+ void updateQuickSettings() {
+ mTile.setVisibility(enabled ? View.VISIBLE : View.GONE);
+ super.updateQuickSettings();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/WiFiTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/WiFiTile.java
new file mode 100644
index 0000000..5e75970
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/WiFiTile.java
@@ -0,0 +1,78 @@
+package com.android.systemui.quicksettings;
+
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+
+public class WiFiTile extends QuickSettingsTile implements NetworkSignalChangedCallback{
+
+ public WiFiTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+ mOnClick = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ WifiManager wfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ wfm.setWifiEnabled(!wfm.isWifiEnabled());
+ }
+ };
+ mOnLongClick = new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
+ return true;
+ }
+ };
+ }
+
+ @Override
+ void onPostCreate() {
+ NetworkController controller = new NetworkController(mContext);
+ controller.addNetworkSignalChangedCallback(this);
+ super.onPostCreate();
+ }
+
+ @Override
+ public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
+ String wifitSignalContentDescriptionId, String description) {
+ boolean wifiConnected = enabled && (wifiSignalIconId > 0) && (description != null);
+ boolean wifiNotConnected = (wifiSignalIconId > 0) && (description == null);
+ if (wifiConnected) {
+ mDrawable = wifiSignalIconId;
+ mLabel = description.substring(1, description.length()-1);
+ } else if (wifiNotConnected) {
+ mDrawable = R.drawable.ic_qs_wifi_0;
+ mLabel = mContext.getString(R.string.quick_settings_wifi_label);
+ } else {
+ mDrawable = R.drawable.ic_qs_wifi_no_network;
+ mLabel = mContext.getString(R.string.quick_settings_wifi_off_label);
+ }
+ updateQuickSettings();
+ }
+
+ @Override
+ public void onMobileDataSignalChanged(boolean enabled,
+ int mobileSignalIconId, String mobileSignalContentDescriptionId,
+ int dataTypeIconId, String dataTypeContentDescriptionId,
+ String description) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onAirplaneModeChanged(boolean enabled) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/quicksettings/WifiAPTile.java b/packages/SystemUI/src/com/android/systemui/quicksettings/WifiAPTile.java
new file mode 100644
index 0000000..48de8af
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/quicksettings/WifiAPTile.java
@@ -0,0 +1,111 @@
+package com.android.systemui.quicksettings;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsContainerView;
+import com.android.systemui.statusbar.phone.QuickSettingsController;
+
+public class WifiAPTile extends QuickSettingsTile {
+
+ private static WifiManager mWifiManager;
+
+ public WifiAPTile(Context context, LayoutInflater inflater,
+ QuickSettingsContainerView container, QuickSettingsController qsc) {
+ super(context, inflater, container, qsc);
+
+ mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+
+ updateTileState();
+ mOnClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int state = mWifiManager.getWifiApState();
+ switch (state) {
+ case WifiManager.WIFI_AP_STATE_ENABLING:
+ case WifiManager.WIFI_AP_STATE_ENABLED:
+ setSoftapEnabled(false);
+ break;
+ case WifiManager.WIFI_AP_STATE_DISABLING:
+ case WifiManager.WIFI_AP_STATE_DISABLED:
+ setSoftapEnabled(true);
+ break;
+ }
+ }
+ };
+ mOnLongClick = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.settings", "com.android.settings.TetherSettings");
+ startSettingsActivity(intent);
+ return true;
+ }
+ };
+ qsc.registerAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION, this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateTileState();
+ updateQuickSettings();
+ }
+
+ private void updateTileState() {
+ int state = mWifiManager.getWifiApState();
+ switch (state) {
+ case WifiManager.WIFI_AP_STATE_ENABLING:
+ case WifiManager.WIFI_AP_STATE_ENABLED:
+ mLabel = mContext.getString(R.string.quick_settings_wifiap);
+ mDrawable = R.drawable.ic_qs_wifi_ap_on;
+ break;
+ case WifiManager.WIFI_AP_STATE_DISABLING:
+ case WifiManager.WIFI_AP_STATE_DISABLED:
+ default:
+ mDrawable = R.drawable.ic_qs_wifi_ap_off;
+ mLabel = mContext.getString(R.string.quick_settings_wifiap_off);
+ break;
+ }
+ }
+
+ private void setSoftapEnabled(boolean enable) {
+ final ContentResolver cr = mContext.getContentResolver();
+ /**
+ * Disable Wifi if enabling tethering
+ */
+ int wifiState = mWifiManager.getWifiState();
+ if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
+ (wifiState == WifiManager.WIFI_STATE_ENABLED))) {
+ mWifiManager.setWifiEnabled(false);
+ Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);
+ }
+
+ // Turn on the Wifi AP
+ mWifiManager.setWifiApEnabled(null, enable);
+
+ /**
+ * If needed, restore Wifi on tether disable
+ */
+ if (!enable) {
+ int wifiSavedState = 0;
+ try {
+ wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE);
+ } catch (Settings.SettingNotFoundException e) {
+ // Do nothing here
+ }
+ if (wifiSavedState == 1) {
+ mWifiManager.setWifiEnabled(true);
+ Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
+ }
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 3330301..989ada0 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.Canvas;
+import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatMath;
@@ -176,6 +177,21 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
dismissChild(view);
}
+ @Override
+ public void removeAllViewsInLayout() {
+ smoothScrollTo(0, 0);
+ int count = mLinearLayout.getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = mLinearLayout.getChildAt(i);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ dismissChild(child);
+ }
+ }, i * 150);
+ }
+ }
+
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
return mSwipeHelper.onInterceptTouchEvent(ev) ||
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 9a1e38d..3b4155c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -89,6 +89,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
private boolean mFitThumbnailToXY;
private int mRecentItemLayoutId;
private boolean mHighEndGfx;
+ private ImageView mClearRecents;
public static interface RecentsScrollView {
public int numItemsInOneScreenful();
@@ -337,7 +338,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
&& (mRecentTaskDescriptions.size() == 0);
mRecentsNoApps.setAlpha(1f);
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
-
+ mClearRecents.setVisibility(noApps ? View.GONE : View.VISIBLE);
onAnimationEnd(null);
setFocusable(true);
setFocusableInTouchMode(true);
@@ -441,6 +442,16 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
mRecentsScrim = findViewById(R.id.recents_bg_protect);
mRecentsNoApps = findViewById(R.id.recents_no_apps);
+ mClearRecents = (ImageView) findViewById(R.id.recents_clear);
+ if (mClearRecents != null){
+ mClearRecents.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mRecentsContainer.removeAllViewsInLayout();
+ }
+ });
+ }
+
if (mRecentsScrim != null) {
mHighEndGfx = ActivityManager.isHighEndGfx();
if (!mHighEndGfx) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index b3adbaf..0f48751 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.Canvas;
+import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatMath;
@@ -184,6 +185,21 @@ public class RecentsVerticalScrollView extends ScrollView
dismissChild(view);
}
+ @Override
+ public void removeAllViewsInLayout() {
+ smoothScrollTo(0, 0);
+ int count = mLinearLayout.getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = mLinearLayout.getChildAt(i);
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ dismissChild(child);
+ }
+ }, i * 150);
+ }
+ }
+
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
return mSwipeHelper.onInterceptTouchEvent(ev) ||
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index f25ac0d..1a860d9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -381,7 +381,10 @@ class GlobalScreenshot {
// only in the natural orientation of the device :!)
mDisplay.getRealMetrics(mDisplayMetrics);
float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
- float degrees = getDegreesForRotation(mDisplay.getRotation());
+ int rot = mDisplay.getRotation();
+ // Allow for abnormal hardware orientation
+ rot = (rot + (android.os.SystemProperties.getInt("ro.sf.hwrotation",0) / 90 )) % 4;
+ float degrees = getDegreesForRotation(rot);
boolean requiresRotation = (degrees > 0);
if (requiresRotation) {
// Get the dimensions of the device in its native orientation
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index d4491d8..78226c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -70,6 +70,7 @@ public class AnimatedImageView extends ImageView {
public void onAttachedToWindow() {
super.onAttachedToWindow();
mAttached = true;
+ updateAnim();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index fe33b02..67a8061 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -73,6 +73,7 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
@@ -124,6 +125,8 @@ public abstract class BaseStatusBar extends SystemUI implements
protected int mCurrentUserId = 0;
+ protected FrameLayout mStatusBarContainer;
+
// UI-specific methods
/**
@@ -138,6 +141,8 @@ public abstract class BaseStatusBar extends SystemUI implements
private boolean mDeviceProvisioned = false;
+ private boolean mShowNotificationCounts;
+
public IStatusBarService getStatusBarService() {
return mBarService;
}
@@ -203,6 +208,11 @@ public abstract class BaseStatusBar extends SystemUI implements
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+ mShowNotificationCounts = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_NOTIF_COUNT, 0) == 1;
+
+ mStatusBarContainer = new FrameLayout(mContext);
+
// Connect in to the status bar manager service
StatusBarIconList iconList = new StatusBarIconList();
ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index c82f250..9c947ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -147,6 +147,10 @@ public class NotificationData {
return e;
}
+ public void clear() {
+ mEntries.clear();
+ }
+
/**
* Return whether there are any visible items (i.e. items without an error).
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java
new file mode 100644
index 0000000..8d9dcfd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.style.CharacterStyle;
+import android.text.style.RelativeSizeSpan;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.systemui.statusbar.SignalClusterView.SettingsObserver;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.R;
+
+// Intimately tied to the design of res/layout/signal_cluster_text_view.xml
+public class SignalClusterTextView
+ extends LinearLayout {
+
+ private static final int SIGNAL_CLUSTER_STYLE_NORMAL = 0;
+ private static final int SIGNAL_CLUSTER_STYLE_TEXT = 1;
+ private static final int SIGNAL_CLUSTER_STYLE_HIDDEN = 2;
+
+ private boolean mAttached;
+ private boolean mAirplaneMode;
+ private int mSignalClusterStyle;
+ private int mPhoneState;
+
+ private SignalStrength signalStrength;
+
+ ViewGroup mMobileGroup;
+ TextView mMobileSignalText;
+
+ Handler mHandler;
+
+ int dBm = 0;
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_SIGNAL_TEXT), false, this);
+ }
+
+ @Override public void onChange(boolean selfChange) {
+ updateSettings();
+ }
+ }
+
+ public SignalClusterTextView(Context context) {
+ this(context, null);
+ }
+
+ public SignalClusterTextView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SignalClusterTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mHandler = new Handler();
+
+ SettingsObserver settingsObserver = new SettingsObserver(mHandler);
+ settingsObserver.observe();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ mMobileGroup = (ViewGroup) findViewById(R.id.mobile_signal_text_combo);
+ mMobileSignalText = (TextView) findViewById(R.id.mobile_signal_text);
+
+ if (!mAttached) {
+ mAttached = true;
+ ((TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE)).listen(
+ mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+
+ updateSettings();
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mAttached) {
+ mAttached = false;
+ }
+ super.onDetachedFromWindow();
+ }
+
+ private String getSignalLevelString(int dBm) {
+ if (dBm == 0) {
+ return "-\u221e"; // -oo ('minus infinity')
+ }
+ return Integer.toString(dBm);
+ }
+
+ final void updateSignalText() {
+
+ if (mAirplaneMode || dBm == 0) {
+ mMobileGroup.setVisibility(View.GONE);
+ return;
+ } else if (mSignalClusterStyle == SIGNAL_CLUSTER_STYLE_TEXT) {
+ mMobileGroup.setVisibility(View.VISIBLE);
+ mMobileSignalText.setText(getSignalLevelString(dBm));
+ } else {
+ mMobileGroup.setVisibility(View.GONE);
+ }
+ }
+
+ /*
+ * Phone listener to update signal information
+ */
+ private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ if (signalStrength != null) {
+ dBm = signalStrength.getDbm();
+ } else {
+ dBm = 0;
+ }
+
+ // update text if it's visible
+ if (mAttached) {
+ updateSettings();
+ }
+ }
+
+ public void onServiceStateChanged(ServiceState serviceState) {
+ mAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
+ updateSettings();
+ }
+ };
+
+ private void updateSettings() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mSignalClusterStyle = (Settings.System.getInt(resolver,
+ Settings.System.STATUS_BAR_SIGNAL_TEXT, SIGNAL_CLUSTER_STYLE_NORMAL));
+ updateSignalText();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 1321ade..01815a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -16,7 +16,11 @@
package com.android.systemui.statusbar;
+import android.content.ContentResolver;
import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.View;
@@ -39,6 +43,9 @@ public class SignalClusterView
NetworkController mNC;
+ private static final int SIGNAL_CLUSTER_STYLE_NORMAL = 0;
+
+ private int mSignalClusterStyle;
private boolean mWifiVisible = false;
private int mWifiStrengthId = 0, mWifiActivityId = 0;
private boolean mMobileVisible = false;
@@ -51,6 +58,25 @@ public class SignalClusterView
ImageView mWifi, mMobile, mWifiActivity, mMobileActivity, mMobileType, mAirplane;
View mSpacer;
+ Handler mHandler;
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_SIGNAL_TEXT), false, this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateSettings();
+ }
+ }
+
public SignalClusterView(Context context) {
this(context, null);
}
@@ -61,6 +87,11 @@ public class SignalClusterView
public SignalClusterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+
+ mHandler = new Handler();
+
+ SettingsObserver settingsObserver = new SettingsObserver(mHandler);
+ settingsObserver.observe();
}
public void setNetworkController(NetworkController nc) {
@@ -191,6 +222,22 @@ public class SignalClusterView
mMobileType.setVisibility(
!mWifiVisible ? View.VISIBLE : View.GONE);
+
+ updateSettings();
+ }
+
+ private void updateSignalClusterStyle() {
+ if (!mIsAirplaneMode) {
+ mMobileGroup.setVisibility(mSignalClusterStyle !=
+ SIGNAL_CLUSTER_STYLE_NORMAL ? View.GONE : View.VISIBLE);
+ }
+ }
+
+ private void updateSettings() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mSignalClusterStyle = (Settings.System.getInt(resolver,
+ Settings.System.STATUS_BAR_SIGNAL_TEXT, SIGNAL_CLUSTER_STYLE_NORMAL));
+ updateSignalClusterStyle();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index dbc55c8..20d69ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -20,11 +20,15 @@ import android.app.Notification;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.os.Handler;
import android.os.UserHandle;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Slog;
@@ -50,18 +54,27 @@ public class StatusBarIconView extends AnimatedImageView {
private int mNumberY;
private String mNumberText;
private Notification mNotification;
+ private boolean mShowNotificationCount;
public StatusBarIconView(Context context, String slot, Notification notification) {
super(context);
final Resources res = context.getResources();
+ final float densityMultiplier = res.getDisplayMetrics().density;
+ final float scaledPx = 8 * densityMultiplier;
mSlot = slot;
mNumberPain = new Paint();
mNumberPain.setTextAlign(Paint.Align.CENTER);
mNumberPain.setColor(res.getColor(R.drawable.notification_number_text_color));
mNumberPain.setAntiAlias(true);
+ mNumberPain.setTypeface(Typeface.DEFAULT_BOLD);
+ mNumberPain.setTextSize(scaledPx);
mNotification = notification;
+ mShowNotificationCount = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_NOTIF_COUNT, 0) == 1;
setContentDescription(notification);
+ SettingsObserver observer = new SettingsObserver(new Handler());
+ observer.observe();
// We do not resize and scale system icons (on the right), only notification icons (on the
// left).
if (notification != null) {
@@ -106,6 +119,10 @@ public class StatusBarIconView extends AnimatedImageView {
* Returns whether the set succeeded.
*/
public boolean set(StatusBarIcon icon) {
+ return set(icon, false);
+ }
+
+ private boolean set(StatusBarIcon icon, boolean force) {
final boolean iconEquals = mIcon != null
&& streq(mIcon.iconPackage, icon.iconPackage)
&& mIcon.iconId == icon.iconId;
@@ -117,7 +134,7 @@ public class StatusBarIconView extends AnimatedImageView {
&& mIcon.number == icon.number;
mIcon = icon.clone();
setContentDescription(icon.contentDescription);
- if (!iconEquals) {
+ if (!iconEquals || force) {
Drawable drawable = getIcon(icon);
if (drawable == null) {
Slog.w(TAG, "No icon for slot " + mSlot);
@@ -125,13 +142,12 @@ public class StatusBarIconView extends AnimatedImageView {
}
setImageDrawable(drawable);
}
- if (!levelEquals) {
+ if (!levelEquals || force) {
setImageLevel(icon.iconLevel);
}
- if (!numberEquals) {
- if (icon.number > 0 && mContext.getResources().getBoolean(
- R.bool.config_statusBarShowNumber)) {
+ if (!numberEquals || force) {
+ if (icon.number > 0 && mShowNotificationCount) {
if (mNumberBackground == null) {
mNumberBackground = getContext().getResources().getDrawable(
R.drawable.ic_notification_overlay);
@@ -143,7 +159,7 @@ public class StatusBarIconView extends AnimatedImageView {
}
invalidate();
}
- if (!visibilityEquals) {
+ if (!visibilityEquals || force) {
setVisibility(icon.visible ? VISIBLE : GONE);
}
return true;
@@ -207,6 +223,10 @@ public class StatusBarIconView extends AnimatedImageView {
}
}
+ public String getStatusBarSlot() {
+ return mSlot;
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
@@ -278,4 +298,25 @@ public class StatusBarIconView extends AnimatedImageView {
return "StatusBarIconView(slot=" + mSlot + " icon=" + mIcon
+ " notification=" + mNotification + ")";
}
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+ void observe() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUS_BAR_NOTIF_COUNT),
+ false, this);
+ }
+ void unobserve() {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ }
+ @Override
+ public void onChange(boolean selfChange) {
+ mShowNotificationCount = Settings.System.getInt(
+ mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_NOTIF_COUNT, 0) == 1;
+ set(mIcon, true);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java
new file mode 100644
index 0000000..c4a7fde
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java
@@ -0,0 +1,558 @@
+package com.android.systemui.statusbar.phone;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Configuration;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.provider.Settings;
+import android.util.DisplayMetrics;
+import android.view.DisplayInfo;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.KeyButtonView;
+
+/**
+ * Handles the editing of the navigation bar
+ * @author Danesh M
+ * @hide
+ */
+public class NavbarEditor implements OnTouchListener {
+
+ /**
+ * Holds reference to all assignable button ids
+ */
+ ArrayList<Integer> mIds = new ArrayList<Integer>(Arrays.asList(R.id.one, R.id.two, R.id.three,
+ R.id.four, R.id.five,R.id.six));
+
+ /**
+ * Subset of mIds, to differentiate small/side buttons
+ * since they can be assigned additional functionality
+ */
+ public static final int[] smallButtonIds = {R.id.one, R.id.six};
+
+ /**
+ * Map which holds references to supported/available buttons.
+ */
+ public static final LinkedHashMap<String, ButtonInfo> buttonMap =
+ new LinkedHashMap<String,ButtonInfo>();
+
+ protected static int visibleCount = 4;
+ private static Boolean mIsDevicePhone = null;
+
+ /**
+ * Holds reference to the parent/root of the inflated view
+ */
+ private ViewGroup mParent;
+
+ /**
+ * Button chooser dialog
+ */
+ AlertDialog mDialog;
+
+ /**
+ * mVertical = Whether we're in landscape mode
+ * mLongPressed = Whether the longpress runnable was activated.
+ */
+ boolean mVertical,mLongPressed;
+
+ private Context mContext;
+
+ //Available buttons
+ public static final String NAVBAR_EMPTY = "empty";
+ public static final String NAVBAR_HOME = "home";
+ public static final String NAVBAR_BACK = "back";
+ public static final String NAVBAR_SEARCH = "search";
+ public static final String NAVBAR_RECENT = "recent";
+ public static final String NAVBAR_CONDITIONAL_MENU = "menu0";
+ public static final String NAVBAR_ALWAYS_MENU = "menu1";
+ public static final String NAVBAR_MENU_BIG = "menu2";
+
+ static {
+ buttonMap.put(NAVBAR_HOME,
+ new ButtonInfo(R.string.navbar_home_button, R.string.accessibility_home, KeyEvent.KEYCODE_HOME, R.drawable.ic_sysbar_home,
+ R.drawable.ic_sysbar_home_land, R.drawable.ic_sysbar_home));
+ buttonMap.put(NAVBAR_CONDITIONAL_MENU,
+ new ButtonInfo(R.string.navbar_menu_conditional_button, R.string.accessibility_menu, KeyEvent.KEYCODE_MENU, R.drawable.ic_sysbar_menu,
+ R.drawable.ic_sysbar_menu_land, R.drawable.ic_sysbar_menu));
+ buttonMap.put(NAVBAR_ALWAYS_MENU,
+ new ButtonInfo(R.string.navbar_menu_always_button, R.string.accessibility_menu, KeyEvent.KEYCODE_MENU, R.drawable.ic_sysbar_menu,
+ R.drawable.ic_sysbar_menu_land, R.drawable.ic_sysbar_menu));
+ buttonMap.put(NAVBAR_MENU_BIG,
+ new ButtonInfo(R.string.navbar_menu_big_button, R.string.accessibility_menu, KeyEvent.KEYCODE_MENU, R.drawable.ic_sysbar_menu_big,
+ R.drawable.ic_sysbar_menu_big_land, 0));
+ buttonMap.put(NAVBAR_BACK,
+ new ButtonInfo(R.string.navbar_back_button, R.string.accessibility_back,KeyEvent.KEYCODE_BACK, R.drawable.ic_sysbar_back,
+ R.drawable.ic_sysbar_back_land, R.drawable.ic_sysbar_back_side));
+ buttonMap.put(NAVBAR_SEARCH,
+ new ButtonInfo(R.string.navbar_search_button, R.string.accessibility_back, KeyEvent.KEYCODE_SEARCH, R.drawable.ic_sysbar_search,
+ R.drawable.ic_sysbar_search_land, R.drawable.ic_sysbar_search_side));
+ buttonMap.put(NAVBAR_RECENT,
+ new ButtonInfo(R.string.navbar_recent_button, R.string.accessibility_recent,0, R.drawable.ic_sysbar_recent,
+ R.drawable.ic_sysbar_recent_land, R.drawable.ic_sysbar_recent_side));
+ buttonMap.put(NAVBAR_EMPTY,
+ new ButtonInfo(R.string.navbar_empty_button, R.string.accessibility_clear_all,0, R.drawable.ic_sysbar_add,
+ R.drawable.ic_sysbar_add_land, R.drawable.ic_sysbar_add_side));
+ }
+
+ public NavbarEditor (ViewGroup parent, Boolean orientation) {
+ mParent = parent;
+ mVertical = orientation;
+ mContext = parent.getContext();
+ }
+
+ /**
+ * Set the button listeners to this
+ * class when in edit mode
+ */
+ protected void setupListeners() {
+ for (int id : mIds) {
+ mParent.findViewById(id).setOnTouchListener(this);
+ }
+ }
+
+ /**
+ * Find intersecting views in mIds
+ * @param pos - pointer location
+ * @param v - view being dragged
+ * @return array index in mIds of view intersecting
+ */
+ private int findInterceptingViewIndex(float pos, View v) {
+ int location[] = new int[2];
+ for (int cc = 0; cc < mIds.size(); cc++) {
+ if (!ArrayUtils.contains(smallButtonIds,mIds.get(cc))) {
+ View tmpV = mParent.findViewById(mIds.get(cc));
+ tmpV.getLocationOnScreen(location);
+ if (tmpV == v) {
+ continue;
+ } else if (!mVertical && (pos > (location[0]+v.getWidth()/4) && pos < location[0]+v.getWidth())) {
+ return cc;
+ } else if (mVertical && (pos > (location[1]+v.getHeight()/4) && pos < location[1]+v.getHeight())) {
+ return cc;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Longpress runnable to assign buttons in edit mode
+ */
+ Runnable mCheckLongPress = new Runnable() {
+ public void run() {
+ if (NavigationBarView.getEditMode()) {
+ mLongPressed = true;
+ mParent.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+ return;
+ }
+ }
+ };
+
+ protected static boolean isDevicePhone(Context con) {
+ if (mIsDevicePhone == null) {
+ WindowManager wm = (WindowManager)con.getSystemService(Context.WINDOW_SERVICE);
+ DisplayInfo outDisplayInfo = new DisplayInfo();
+ wm.getDefaultDisplay().getDisplayInfo(outDisplayInfo);
+ int shortSize = Math.min(outDisplayInfo.logicalHeight, outDisplayInfo.logicalWidth);
+ int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / outDisplayInfo.logicalDensityDpi;
+ if (shortSizeDp < 600) {
+ // 0-599dp: "phone" UI with a separate status & navigation bar
+ mIsDevicePhone = true;
+ } else {
+ mIsDevicePhone = false;
+ }
+ }
+ return mIsDevicePhone;
+ }
+
+ @Override
+ public boolean onTouch(final View view, MotionEvent event) {
+ if (!NavigationBarView.getEditMode() || (mDialog != null && mDialog.isShowing())) {
+ return false;
+ }
+ float curPos = 0;
+ if (!mVertical) {
+ curPos = event.getRawX();
+ } else {
+ curPos = event.getRawY();
+ }
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ int screenLoc[] = new int[2];
+ view.setPressed(true);
+ view.getLocationOnScreen(screenLoc);
+ // Store the starting view position in the parent's tag
+ if (!mVertical) {
+ mParent.setTag(Float.valueOf(screenLoc[0]));
+ } else {
+ mParent.setTag(Float.valueOf(screenLoc[1]));
+ }
+ view.postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
+ } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ view.setPressed(false);
+ if (!mLongPressed || ArrayUtils.contains(smallButtonIds, view.getId())) {
+ return false;
+ }
+ view.bringToFront();
+ ViewGroup viewParent = (ViewGroup) view.getParent();
+ float buttonSize = 0;
+ if (!mVertical) {
+ buttonSize = view.getWidth();
+ } else {
+ buttonSize = view.getHeight();
+ }
+ // Prevents user from dragging view outside of bounds
+ if ((!mVertical && ((curPos) > (viewParent.getWidth() + viewParent.getLeft()) || (curPos - buttonSize/2 <= viewParent.getLeft()))) ||
+ (mVertical && ((curPos > (viewParent.getHeight() + viewParent.getTop())) || (curPos < viewParent.getTop())))) {
+ return false;
+ }
+ if (!mVertical) {
+ view.setX(curPos - viewParent.getLeft() - buttonSize/2);
+ } else {
+ view.setY(curPos - viewParent.getTop() - buttonSize/2);
+ }
+ int affectedViewPosition = findInterceptingViewIndex(curPos, view);
+ if (affectedViewPosition == -1) {
+ return false;
+ }
+ switchId(mIds.indexOf(view.getId()), affectedViewPosition, view);
+ } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
+ view.setPressed(false);
+ view.removeCallbacks(mCheckLongPress);
+ if (!mLongPressed && !view.getTag().equals("home")) {
+ final ButtonAdapter list = new ButtonAdapter(ArrayUtils.contains(smallButtonIds, view.getId()) ? true : false);
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setTitle(mContext.getString(R.string.navbar_dialog_title));
+ builder.setAdapter(list, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ ((KeyButtonView) view).setInfo(list.getItem(which).toString(), mVertical);
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+ mDialog = builder.create();
+ mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ mDialog.setCanceledOnTouchOutside(false);
+ mDialog.show();
+ mLongPressed=false;
+ return true;
+ }
+ mLongPressed=false;
+ // Reset the dragged view to its original location
+ ViewGroup vParent = (ViewGroup) view.getParent();
+ if (!mVertical) {
+ view.setX((Float) mParent.getTag() - vParent.getLeft());
+ } else {
+ view.setY((Float) mParent.getTag() - vParent.getTop());
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Switches positions of two views and
+ * updates their mIds entry
+ * @param to - index for new position in mIds
+ * @param from - index for old position in mIds
+ * @param view - view being dragged
+ */
+ private void switchId(int to, int from, View view) {
+ View tView = mParent.findViewById(mIds.get(from));
+ int screenLoc[] = new int[2];
+ tView.getLocationOnScreen(screenLoc);
+ ViewGroup a = (ViewGroup) view.getParent();
+ if (!mVertical) {
+ tView.setX((Float) mParent.getTag() - a.getLeft());
+ mParent.setTag(Float.valueOf(screenLoc[0]));
+ } else {
+ tView.setY((Float) mParent.getTag() - a.getTop());
+ mParent.setTag(Float.valueOf(screenLoc[1]));
+ }
+ Collections.swap(mIds,to,from);
+ }
+
+ /**
+ * Saves the current key arrangement
+ * to the settings provider
+ */
+ @SuppressWarnings("unchecked")
+ protected void saveKeys() {
+ ((ViewGroup) mParent.findViewById(R.id.mid_nav_buttons)).setLayoutTransition(null);
+ StringBuilder saveValue = new StringBuilder();
+ String delim = "";
+ ArrayList<Integer> idMap = (ArrayList<Integer>) mIds.clone();
+ if (mVertical) Collections.reverse(idMap);
+ for (int id : idMap) {
+ saveValue.append(delim);
+ delim="|";
+ saveValue.append(mParent.findViewById(id).getTag());
+ }
+ Settings.System.putString(mContext.getContentResolver(), Settings.System.NAV_BUTTONS, saveValue.toString());
+ }
+
+ /**
+ * Reinflates navigation bar on demand
+ * base on current orientation
+ */
+ protected void reInflate() {
+ ((ViewGroup)mParent).removeAllViews();
+ if (mVertical) {
+ View.inflate(mContext, R.layout.mid_navigation_bar_land, (ViewGroup) mParent);
+ } else {
+ View.inflate(mContext, R.layout.mid_navigation_bar_port, (ViewGroup) mParent);
+ }
+ }
+
+ /**
+ * Updates the buttons according to the
+ * key arrangement stored in settings provider
+ */
+ @SuppressWarnings("unchecked")
+ protected void updateKeys() {
+ String saved = Settings.System.getString(mContext.getContentResolver(), Settings.System.NAV_BUTTONS);
+ if (saved == null) {
+ saved = "empty|back|home|recent|empty|menu0";
+ }
+ int cc = 0;
+ ArrayList<Integer> idMap = (ArrayList<Integer>) mIds.clone();
+ if (mVertical) Collections.reverse(idMap);
+ visibleCount = 0;
+ for (String buttons : saved.split("\\|")) {
+ KeyButtonView curView = (KeyButtonView) mParent.findViewById(idMap.get(cc));
+ boolean isSmallButton = ArrayUtils.contains(NavbarEditor.smallButtonIds, curView.getId());
+ curView.setInfo(buttons, mVertical);
+ if (!curView.getTag().equals(NAVBAR_EMPTY) && !isSmallButton) {
+ visibleCount++;
+ }
+ cc++;
+ }
+ if (isDevicePhone(mContext)) {
+ adjustPadding();
+ }
+ }
+
+ /**
+ * Accommodates the padding between keys based on
+ * number of keys in use.
+ */
+ private void adjustPadding() {
+ ViewGroup viewParent = (ViewGroup) mParent.findViewById(R.id.mid_nav_buttons);
+ int sCount = visibleCount;
+ for (int v = 0; v < viewParent.getChildCount();v++) {
+ View cView = viewParent.getChildAt(v);
+ if (cView instanceof KeyButtonView) {
+ View nextPadding = viewParent.getChildAt(v+1);
+ if (nextPadding != null) {
+ View nextKey = viewParent.getChildAt(v+2);
+ String nextTag = NAVBAR_EMPTY;
+ if (nextKey != null) {
+ nextTag = (String) nextKey.getTag();
+ }
+ String curTag = (String) cView.getTag();
+ if (nextKey != null && nextTag != null && curTag != null && !curTag.equals(NAVBAR_EMPTY)) {
+ if (!nextTag.equals(NAVBAR_EMPTY)){
+ nextPadding.setVisibility(View.VISIBLE);
+ } else {
+ if (sCount > 1) {
+ nextPadding.setVisibility(View.VISIBLE);
+ } else {
+ nextPadding.setVisibility(View.GONE);
+ }
+ }
+ sCount--;
+ } else {
+ nextPadding.setVisibility(View.GONE);
+ }
+ }
+ }
+ }
+ }
+
+ protected void updateLowLights(View current) {
+ ViewGroup lowLights = (ViewGroup) current.findViewById(R.id.lights_out);
+ int totalViews = lowLights.getChildCount();
+ int visibleCount = NavbarEditor.visibleCount;
+ for (int v = 0;v<totalViews;v++) {
+ if (lowLights.getChildAt(v) instanceof ImageView) {
+ View blank = lowLights.getChildAt(v+1);
+ if (visibleCount <= 0) {
+ lowLights.getChildAt(v).setVisibility(View.GONE);
+ if (blank != null) {
+ blank.setVisibility(View.GONE);
+ }
+ } else {
+ lowLights.getChildAt(v).setVisibility(View.VISIBLE);
+ visibleCount--;
+ if (visibleCount > 0 && blank != null) {
+ blank.setVisibility(View.VISIBLE);
+ } else if (blank != null) {
+ blank.setVisibility(View.GONE);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Class to store info about supported buttons
+ */
+ public static final class ButtonInfo {
+ public int displayId;
+ public int contentDescription;
+ public int keyCode;
+ public int portResource;
+ public int landResource;
+ public int sideResource;
+ /**
+ * Constructor for new button type
+ * @param rId - resource id of text shown to user in choose dialog
+ * @param cD - accessibility information regarding button
+ * @param mC - keyCode to execute on button press
+ * @param pR - portrait resource used to display button
+ * @param lR - landscape resource used to display button
+ * @param sR - smaller scaled resource for side buttons
+ */
+ ButtonInfo (int rId, int cD, int mC, int pR, int lR, int sR) {
+ displayId = rId;
+ contentDescription = cD;
+ keyCode = mC;
+ portResource = pR;
+ landResource = lR;
+ sideResource = sR;
+ }
+ }
+
+ private class ButtonAdapter implements ListAdapter {
+
+ /**
+ * Already assigned items
+ */
+ ArrayList<String> takenItems;
+ ArrayList<String> items;
+ LayoutInflater inflater;
+
+ ButtonAdapter (boolean smallButtons) {
+ inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ takenItems = new ArrayList<String>();
+ for (int id : mIds) {
+ String vTag = (String) mParent.findViewById(id).getTag();
+ if (vTag == null || vTag.equals(NAVBAR_EMPTY)) {
+ continue;
+ }
+ takenItems.add(vTag);
+ }
+ items = new ArrayList<String>(buttonMap.keySet());
+ // home button is not assignable
+ items.remove(NAVBAR_HOME);
+ // menu buttons can only be assigned to side buttons
+ if (!smallButtons) {
+ items.remove(NAVBAR_CONDITIONAL_MENU);
+ items.remove(NAVBAR_ALWAYS_MENU);
+ } else {
+ items.remove(NAVBAR_MENU_BIG);
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return items.size();
+ }
+
+ @Override
+ public Object getItem(int arg0) {
+ return items.get(arg0);
+ }
+
+ @Override
+ public long getItemId(int arg0) {
+ return 0;
+ }
+
+ @Override
+ public int getItemViewType(int arg0) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int arg0, View convertView, ViewGroup parent) {
+ if(convertView == null) {
+ convertView = inflater.inflate(android.R.layout.select_dialog_item, parent,false);
+ }
+ TextView text = (TextView) convertView.findViewById(android.R.id.text1);
+ if (takenItems.contains(items.get(arg0))) {
+ text.setBackgroundColor(Color.parseColor("#181818"));
+ } else {
+ text.setBackground(null);
+ }
+ text.setText(mParent.getResources().getString(buttonMap.get(items.get(arg0)).displayId));
+ return convertView;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 1;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public void registerDataSetObserver(DataSetObserver arg0) {
+ }
+
+ @Override
+ public void unregisterDataSetObserver(DataSetObserver arg0) {
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled(int arg0) {
+ if (takenItems.contains(items.get(arg0))) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ final void dismissDialog() {
+ if (mDialog != null && mDialog.isShowing()) {
+ mDialog.dismiss();
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 5eeef93..be17e37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -20,7 +20,11 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition;
import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
@@ -59,6 +63,14 @@ public class NavigationBarView extends LinearLayout {
final static boolean SLIPPERY_WHEN_DISABLED= true;
final static boolean ANIMATE_HIDE_TRANSITION = false; // turned off because it introduces unsightly delay when videos goes to full screen
+ final static String NAVBAR_EDIT = "android.intent.action.NAVBAR_EDIT";
+
+ private static boolean EDIT_MODE;
+ private NavbarEditor mEditBar;
+ private NavBarReceiver mNavBarReceiver;
+ private OnClickListener mRecentsClickListener;
+ private OnTouchListener mRecentsPreloadListener;
+ private OnTouchListener mHomeSearchActionListener;
protected IStatusBarService mBarService;
final Display mDisplay;
@@ -132,20 +144,33 @@ public class NavigationBarView extends LinearLayout {
private H mHandler = new H();
- public View getRecentsButton() {
- return mCurrentView.findViewById(R.id.recent_apps);
+ public static boolean getEditMode() {
+ return EDIT_MODE;
}
-
- public View getMenuButton() {
- return mCurrentView.findViewById(R.id.menu);
+
+ protected void setListener(OnClickListener RecentsClickListener, OnTouchListener RecentsPreloadListener, OnTouchListener HomeSearchActionListener) {
+ mRecentsClickListener = RecentsClickListener;
+ mRecentsPreloadListener = RecentsPreloadListener;
+ mHomeSearchActionListener = HomeSearchActionListener;
}
- public View getBackButton() {
- return mCurrentView.findViewById(R.id.back);
+ protected void toggleButtonListener(boolean enable) {
+ View recentView = mCurrentView.findViewWithTag(NavbarEditor.NAVBAR_RECENT);
+ if (recentView != null) {
+ recentView.setOnClickListener(enable ? mRecentsClickListener : null);
+ recentView.setOnTouchListener(enable ? mRecentsPreloadListener : null);
+ }
+ View homeView = mCurrentView.findViewWithTag(NavbarEditor.NAVBAR_HOME);
+ if (homeView != null) {
+ homeView.setOnTouchListener(enable ? mHomeSearchActionListener : null);
+ }
}
- public View getHomeButton() {
- return mCurrentView.findViewById(R.id.home);
+ private void setButtonWithTagVisibility(String string, int visibility) {
+ View findView = mCurrentView.findViewWithTag(string);
+ if (findView != null) {
+ findView.setVisibility(visibility);
+ }
}
// for when home is disabled, but search isn't
@@ -168,11 +193,48 @@ public class NavigationBarView extends LinearLayout {
mVertical = false;
mShowMenu = false;
mDelegateHelper = new DelegateViewHelper(this);
+ updateResources();
+
+ mNavBarReceiver = new NavBarReceiver();
+ mContext.registerReceiver(mNavBarReceiver, new IntentFilter(NAVBAR_EDIT));
+ }
+ protected void updateResources() {
+ final Resources res = mContext.getResources();
mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
mBackAltIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
- mBackAltLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
+ mBackAltLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime_land);
+ }
+
+ public class NavBarReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ boolean edit = intent.getBooleanExtra("edit", false);
+ boolean save = intent.getBooleanExtra("save", false);
+ if (edit != EDIT_MODE) {
+ EDIT_MODE = edit;
+ if (EDIT_MODE) {
+ toggleButtonListener(false);
+ mEditBar.setupListeners();
+ mEditBar.updateKeys();
+ } else {
+ mEditBar.dismissDialog();
+ if (save) {
+ mEditBar.saveKeys();
+ }
+ mEditBar.reInflate();
+ mEditBar = new NavbarEditor((ViewGroup) mCurrentView.findViewById(R.id.container), mVertical);
+ mEditBar.updateKeys();
+ toggleButtonListener(true);
+ if (save) {
+ mEditBar.updateLowLights(mCurrentView);
+ }
+ ((ViewGroup) mCurrentView.findViewById(R.id.mid_nav_buttons)).setLayoutTransition(
+ new LayoutTransition());
+ }
+ }
+ }
}
public void notifyScreenOn(boolean screenOn) {
@@ -213,18 +275,25 @@ public class NavigationBarView extends LinearLayout {
mNavigationIconHints = hints;
- getBackButton().setAlpha(
- (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_NOP)) ? 0.5f : 1.0f);
- getHomeButton().setAlpha(
- (0 != (hints & StatusBarManager.NAVIGATION_HINT_HOME_NOP)) ? 0.5f : 1.0f);
- getRecentsButton().setAlpha(
- (0 != (hints & StatusBarManager.NAVIGATION_HINT_RECENT_NOP)) ? 0.5f : 1.0f);
-
- ((ImageView)getBackButton()).setImageDrawable(
- (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT))
- ? (mVertical ? mBackAltLandIcon : mBackAltIcon)
- : (mVertical ? mBackLandIcon : mBackIcon));
-
+ View button = mCurrentView.findViewWithTag(NavbarEditor.NAVBAR_HOME);
+ if (button != null) {
+ button.setAlpha(
+ (0 != (hints & StatusBarManager.NAVIGATION_HINT_HOME_NOP)) ? 0.5f : 1.0f);
+ }
+ button = mCurrentView.findViewWithTag(NavbarEditor.NAVBAR_RECENT);
+ if (button != null) {
+ button.setAlpha(
+ (0 != (hints & StatusBarManager.NAVIGATION_HINT_RECENT_NOP)) ? 0.5f : 1.0f);
+ }
+ button = mCurrentView.findViewWithTag(NavbarEditor.NAVBAR_BACK);
+ if (button != null) {
+ button.setAlpha(
+ (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_NOP)) ? 0.5f : 1.0f);
+ ((ImageView)button).setImageDrawable(
+ (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT))
+ ? (mVertical ? mBackAltLandIcon : mBackAltIcon)
+ : (mVertical ? mBackLandIcon : mBackIcon));
+ }
setDisabledFlags(mDisabledFlags, true);
}
@@ -257,10 +326,13 @@ public class NavigationBarView extends LinearLayout {
}
}
- getBackButton() .setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
- getHomeButton() .setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
- getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
-
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_BACK, disableBack ? View.INVISIBLE : View.VISIBLE);
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_HOME, disableHome ? View.INVISIBLE : View.VISIBLE);
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_RECENT, disableRecent ? View.INVISIBLE : View.VISIBLE);
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_RECENT, disableRecent ? View.INVISIBLE : View.VISIBLE);
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_ALWAYS_MENU, disableRecent ? View.INVISIBLE : View.VISIBLE);
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_MENU_BIG, disableRecent ? View.INVISIBLE : View.VISIBLE);
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_SEARCH, disableRecent ? View.INVISIBLE : View.VISIBLE);
getSearchLight().setVisibility((disableHome && !disableSearch) ? View.VISIBLE : View.GONE);
}
@@ -289,7 +361,7 @@ public class NavigationBarView extends LinearLayout {
mShowMenu = show;
- getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
+ setButtonWithTagVisibility(NavbarEditor.NAVBAR_CONDITIONAL_MENU, mShowMenu ? View.VISIBLE : View.INVISIBLE);
}
public void setLowProfile(final boolean lightsOut) {
@@ -353,25 +425,28 @@ public class NavigationBarView extends LinearLayout {
@Override
public void onFinishInflate() {
- mRotatedViews[Surface.ROTATION_0] =
- mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
-
- mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
-
- mRotatedViews[Surface.ROTATION_270] = NAVBAR_ALWAYS_AT_RIGHT
- ? findViewById(R.id.rot90)
- : findViewById(R.id.rot270);
-
- mCurrentView = mRotatedViews[Surface.ROTATION_0];
+ mRotatedViews[Configuration.ORIENTATION_PORTRAIT] = findViewById(R.id.rot0);
+ mRotatedViews[Configuration.ORIENTATION_LANDSCAPE] = findViewById(R.id.rot90);
+ mCurrentView = mRotatedViews[mContext.getResources().getConfiguration().orientation];
}
public void reorient() {
- final int rot = mDisplay.getRotation();
- for (int i=0; i<4; i++) {
+ int rot = mContext.getResources().getConfiguration().orientation;
+ for (int i=1; i<3; i++) {
mRotatedViews[i].setVisibility(View.GONE);
}
mCurrentView = mRotatedViews[rot];
mCurrentView.setVisibility(View.VISIBLE);
+ if (NavbarEditor.isDevicePhone(mContext)) {
+ rot = mDisplay.getRotation();
+ mVertical = (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270);
+ } else {
+ mVertical = getWidth() > 0 && getHeight() > getWidth();
+ }
+ mEditBar = new NavbarEditor((ViewGroup) mCurrentView.findViewById(R.id.container), mVertical);
+ mEditBar.updateKeys();
+ mEditBar.updateLowLights(mCurrentView);
+ toggleButtonListener(true);
mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
@@ -390,7 +465,12 @@ public class NavigationBarView extends LinearLayout {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- mDelegateHelper.setInitialTouchRegion(getHomeButton(), getBackButton(), getRecentsButton());
+ ViewGroup mid_nav = (ViewGroup) mCurrentView.findViewById(R.id.mid_nav_buttons);
+ View vViews[] = new View[mid_nav.getChildCount()];
+ for (int cc = 0;cc < mid_nav.getChildCount(); cc++) {
+ vViews[cc] = mid_nav.getChildAt(cc);
+ }
+ mDelegateHelper.setInitialTouchRegion(vViews);
}
@Override
@@ -487,10 +567,9 @@ public class NavigationBarView extends LinearLayout {
mLowProfile ? "true" : "false",
mShowMenu ? "true" : "false"));
- final View back = getBackButton();
- final View home = getHomeButton();
- final View recent = getRecentsButton();
- final View menu = getMenuButton();
+ final View back = mCurrentView.findViewWithTag("back");
+ final View home = mCurrentView.findViewWithTag("home");
+ final View recent = mCurrentView.findViewWithTag("recent");
pw.println(" back: "
+ PhoneStatusBar.viewInfo(back)
@@ -504,10 +583,6 @@ public class NavigationBarView extends LinearLayout {
+ PhoneStatusBar.viewInfo(recent)
+ " " + visibilityToString(recent.getVisibility())
);
- pw.println(" menu: "
- + PhoneStatusBar.viewInfo(menu)
- + " " + visibilityToString(menu.getVisibility())
- );
pw.println(" }");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 2bad353..b46aa3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.MotionEvent;
@@ -30,12 +31,25 @@ import com.android.systemui.statusbar.GestureRecorder;
public class NotificationPanelView extends PanelView {
- Drawable mHandleBar;
- int mHandleBarHeight;
- View mHandleView;
- int mFingers;
- PhoneStatusBar mStatusBar;
- boolean mOkToFlip;
+ private static final float STATUS_BAR_SETTINGS_LEFT_PERCENTAGE = 0.8f;
+ private static final float STATUS_BAR_SETTINGS_RIGHT_PERCENTAGE = 0.2f;
+ private static final float STATUS_BAR_SWIPE_TRIGGER_PERCENTAGE = 0.05f;
+ private static final float STATUS_BAR_SWIPE_VERTICAL_MAX_PERCENTAGE = 0.025f;
+ private static final float STATUS_BAR_SWIPE_MOVE_PERCENTAGE = 0.2f;
+
+ private Drawable mHandleBar;
+ private int mHandleBarHeight;
+ private View mHandleView;
+ private int mFingers;
+ private PhoneStatusBar mStatusBar;
+ private boolean mOkToFlip;
+
+ private float mGestureStartX;
+ private float mGestureStartY;
+ private float mFlipOffset;
+ private float mSwipeDirection;
+ private boolean mTrackingSwipe;
+ private boolean mSwipeTriggered;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -91,32 +105,120 @@ public class NotificationPanelView extends PanelView {
@Override
public boolean onTouchEvent(MotionEvent event) {
+ boolean shouldRecycleEvent = false;
if (PhoneStatusBar.SETTINGS_DRAG_SHORTCUT && mStatusBar.mHasFlipSettings) {
+ boolean flip = false;
+ boolean swipeFlipJustFinished = false;
+ boolean swipeFlipJustStarted = false;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
+ mGestureStartX = event.getX(0);
+ mGestureStartY = event.getY(0);
+ mTrackingSwipe = isFullyExpanded() &&
+ // Pointer is at the handle portion of the view?
+ mGestureStartY > getHeight() - mHandleBarHeight - getPaddingBottom();
mOkToFlip = getExpandedHeight() == 0;
+ if (event.getX(0) > getWidth() * (1.0f - STATUS_BAR_SETTINGS_RIGHT_PERCENTAGE) &&
+ Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.QS_QUICK_PULLDOWN, 0) == 1) {
+ flip = true;
+ } else if (event.getX(0) < getWidth() * (1.0f - STATUS_BAR_SETTINGS_LEFT_PERCENTAGE) &&
+ Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.QS_QUICK_PULLDOWN, 0) == 2) {
+ flip = true;
+ }
break;
- case MotionEvent.ACTION_POINTER_DOWN:
- if (mOkToFlip) {
- float miny = event.getY(0);
- float maxy = miny;
- for (int i=1; i<event.getPointerCount(); i++) {
- final float y = event.getY(i);
- if (y < miny) miny = y;
- if (y > maxy) maxy = y;
- }
- if (maxy - miny < mHandleBarHeight) {
- if (getMeasuredHeight() < mHandleBarHeight) {
- mStatusBar.switchToSettings();
- } else {
- mStatusBar.flipToSettings();
- }
- mOkToFlip = false;
+ case MotionEvent.ACTION_MOVE:
+ final float deltaX = Math.abs(event.getX(0) - mGestureStartX);
+ final float deltaY = Math.abs(event.getY(0) - mGestureStartY);
+ final float maxDeltaY = getHeight() * STATUS_BAR_SWIPE_VERTICAL_MAX_PERCENTAGE;
+ final float minDeltaX = getWidth() * STATUS_BAR_SWIPE_TRIGGER_PERCENTAGE;
+ if (mTrackingSwipe && deltaY > maxDeltaY) {
+ mTrackingSwipe = false;
+ }
+ if (mTrackingSwipe && deltaX > deltaY && deltaX > minDeltaX) {
+
+ // The value below can be used to adjust deltaX to always increase,
+ // if the user keeps swiping in the same direction as she started the
+ // gesture. If she, however, moves her finger the other way, deltaX will
+ // decrease.
+ //
+ // This allows for an horizontal swipe, in any direction, to always flip
+ // the views.
+ mSwipeDirection = event.getX(0) < mGestureStartX ? -1f : 1f;
+
+ if (mStatusBar.isShowingSettings()) {
+ mFlipOffset = 1f;
+ // in this case, however, we need deltaX to decrease
+ mSwipeDirection = -mSwipeDirection;
+ } else {
+ mFlipOffset = -1f;
}
+ mGestureStartX = event.getX(0);
+ mTrackingSwipe = false;
+ mSwipeTriggered = true;
+ swipeFlipJustStarted = true;
}
break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ flip = true;
+ break;
+ case MotionEvent.ACTION_UP:
+ swipeFlipJustFinished = mSwipeTriggered;
+ mSwipeTriggered = false;
+ mTrackingSwipe = false;
+ break;
}
+ if (mOkToFlip && flip) {
+ float miny = event.getY(0);
+ float maxy = miny;
+ for (int i=1; i<event.getPointerCount(); i++) {
+ final float y = event.getY(i);
+ if (y < miny) miny = y;
+ if (y > maxy) maxy = y;
+ }
+ if (maxy - miny < mHandleBarHeight) {
+ if (getMeasuredHeight() < mHandleBarHeight) {
+ mStatusBar.switchToSettings();
+ } else {
+ mStatusBar.flipToSettings();
+ }
+ mOkToFlip = false;
+ }
+ } else if (mSwipeTriggered) {
+ final float deltaX = (event.getX(0) - mGestureStartX) * mSwipeDirection;
+ mStatusBar.partialFlip(mFlipOffset +
+ deltaX / (getWidth() * STATUS_BAR_SWIPE_MOVE_PERCENTAGE));
+ if (!swipeFlipJustStarted) {
+ return true; // Consume the event.
+ }
+ } else if (swipeFlipJustFinished) {
+ mStatusBar.completePartialFlip();
+ }
+
+ if (swipeFlipJustStarted || swipeFlipJustFinished) {
+ // Made up event: finger at the middle bottom of the view.
+ MotionEvent original = event;
+ event = MotionEvent.obtain(original.getDownTime(), original.getEventTime(),
+ original.getAction(), getWidth()/2, getHeight(),
+ original.getPressure(0), original.getSize(0), original.getMetaState(),
+ original.getXPrecision(), original.getYPrecision(), original.getDeviceId(),
+ original.getEdgeFlags());
+
+ // The following two lines looks better than the chunk of code above, but,
+ // nevertheless, doesn't work. The view is not pinned down, and may close,
+ // just after the gesture is finished.
+ //
+ // event = MotionEvent.obtainNoHistory(original);
+ // event.setLocation(getWidth()/2, getHeight());
+ shouldRecycleEvent = true;
+ }
+
+ }
+ final boolean result = mHandleView.dispatchTouchEvent(event);
+ if (shouldRecycleEvent) {
+ event.recycle();
}
- return mHandleView.dispatchTouchEvent(event);
+ return result;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 30af333..58d41ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -16,6 +16,11 @@
package com.android.systemui.statusbar.phone;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -27,10 +32,12 @@ import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.res.CustomTheme;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Canvas;
@@ -43,6 +50,7 @@ import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IPowerManager;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -53,12 +61,15 @@ import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.Gravity;
+import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewPropertyAnimator;
@@ -85,6 +96,7 @@ import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.DockBatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.DateView;
import com.android.systemui.statusbar.policy.IntruderAlertView;
@@ -93,10 +105,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NotificationRowLayout;
import com.android.systemui.statusbar.policy.OnSizeChangedListener;
import com.android.systemui.statusbar.policy.Prefs;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
+import com.android.systemui.statusbar.powerwidget.PowerWidget;
public class PhoneStatusBar extends BaseStatusBar {
static final String TAG = "PhoneStatusBar";
@@ -130,6 +139,10 @@ public class PhoneStatusBar extends BaseStatusBar {
private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
+ private static final float BRIGHTNESS_CONTROL_PADDING = 0.15f;
+ private static final int BRIGHTNESS_CONTROL_LONG_PRESS_TIMEOUT = 750; // ms
+ private static final int BRIGHTNESS_CONTROL_LINGER_THRESHOLD = 20;
+
// fling gesture tuning parameters, scaled to display density
private float mSelfExpandVelocityPx; // classic value: 2000px/s
private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
@@ -142,7 +155,7 @@ public class PhoneStatusBar extends BaseStatusBar {
private float mExpandAccelPx; // classic value: 2000px/s/s
private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
- private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
+ private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
// faster than mSelfCollapseVelocityPx)
PhoneStatusBarPolicy mIconPolicy;
@@ -150,9 +163,12 @@ public class PhoneStatusBar extends BaseStatusBar {
// These are no longer handled by the policy, because we need custom strategies for them
BluetoothController mBluetoothController;
BatteryController mBatteryController;
+ DockBatteryController mDockBatteryController;
LocationController mLocationController;
NetworkController mNetworkController;
+ private boolean mHasDockBattery;
+
int mNaturalBarHeight = -1;
int mIconSize = -1;
int mIconHPadding = -1;
@@ -169,11 +185,11 @@ public class PhoneStatusBar extends BaseStatusBar {
// viewgroup containing the normal contents of the statusbar
LinearLayout mStatusBarContents;
-
+
// right-hand icons
LinearLayout mSystemIconArea;
-
- // left-hand icons
+
+ // left-hand icons
LinearLayout mStatusIcons;
// the icons themselves
IconMerger mNotificationIcons;
@@ -191,16 +207,17 @@ public class PhoneStatusBar extends BaseStatusBar {
TextView mNotificationPanelDebugText;
// settings
- QuickSettings mQS;
+ QuickSettingsController mQS;
boolean mHasSettingsPanel, mHasFlipSettings;
SettingsPanelView mSettingsPanel;
View mFlipSettingsView;
QuickSettingsContainerView mSettingsContainer;
int mSettingsPanelGravity;
+ private TilesChangedObserver mTilesChangedObserver;
// top bar
View mNotificationPanelHeader;
- View mDateTimeView;
+ View mDateTimeView;
View mClearButton;
ImageView mSettingsButton, mNotificationButton;
@@ -213,6 +230,13 @@ public class PhoneStatusBar extends BaseStatusBar {
private boolean mShowCarrierInPanel = false;
+ // clock
+ private boolean mShowClock;
+
+ // drag bar
+ CloseDragHandle mCloseView;
+ private int mCloseViewHeight;
+
// position
int[] mPositionTmp = new int[2];
boolean mExpandedVisible;
@@ -229,6 +253,9 @@ public class PhoneStatusBar extends BaseStatusBar {
// the tracker view
int mTrackingPosition; // the position of the top of the tracking view.
+ // the power widget
+ PowerWidget mPowerWidget;
+
// ticker
private Ticker mTicker;
private View mTickerView;
@@ -260,6 +287,18 @@ public class PhoneStatusBar extends BaseStatusBar {
private Animator mLightsOutAnimation;
private Animator mLightsOnAnimation;
+ // last theme that was applied in order to detect theme change (as opposed
+ // to some other configuration change).
+ CustomTheme mCurrentTheme;
+ private boolean mRecreating = false;
+
+ private boolean mBrightnessControl = true;
+ private float mScreenWidth;
+ private int mMinBrightness;
+ int mLinger;
+ int mInitialTouchX;
+ int mInitialTouchY;
+
// for disabling the status bar
int mDisabled = 0;
@@ -270,7 +309,7 @@ public class PhoneStatusBar extends BaseStatusBar {
// XXX: gesture research
private final GestureRecorder mGestureRec = DEBUG_GESTURES
- ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
+ ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
: null;
private int mNavigationIconHints = 0;
@@ -285,9 +324,48 @@ public class PhoneStatusBar extends BaseStatusBar {
}
};
+ Runnable mLongPressBrightnessChange = new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ adjustBrightness(mInitialTouchX);
+ mLinger = BRIGHTNESS_CONTROL_LINGER_THRESHOLD + 1;
+ }
+ };
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_BRIGHTNESS_CONTROL), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.SCREEN_BRIGHTNESS_MODE), false, this);
+ update();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ update();
+ }
+
+ public void update() {
+ ContentResolver resolver = mContext.getContentResolver();
+ boolean autoBrightness = Settings.System.getInt(
+ resolver, Settings.System.SCREEN_BRIGHTNESS_MODE, 0) ==
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
+ mBrightnessControl = !autoBrightness && Settings.System.getInt(
+ resolver, Settings.System.STATUS_BAR_BRIGHTNESS_CONTROL, 0) == 1;
+ }
+ }
+
+
// ensure quick settings is disabled until the current user makes it through the setup wizard
private boolean mUserSetup = false;
- private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
+ private final ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
final boolean userSetup = 0 != Settings.Secure.getIntForUser(
@@ -320,12 +398,20 @@ public class PhoneStatusBar extends BaseStatusBar {
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE));
+ CustomTheme currentTheme = mContext.getResources().getConfiguration().customTheme;
+ if (currentTheme != null) {
+ mCurrentTheme = (CustomTheme)currentTheme.clone();
+ }
+
super.start(); // calls createAndAddWindows()
addNavigationBar();
if (ENABLE_INTRUDERS) addIntruderView();
+ SettingsObserver observer = new SettingsObserver(mHandler);
+ observer.observe();
+
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext);
}
@@ -338,6 +424,10 @@ public class PhoneStatusBar extends BaseStatusBar {
Resources res = context.getResources();
+ mScreenWidth = (float) context.getResources().getDisplayMetrics().widthPixels;
+ mMinBrightness = context.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessDim);
+
updateDisplaySize(); // populates mDisplayMetrics
loadDimens();
@@ -359,7 +449,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
mStatusBarView.setBar(this);
-
+
PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
mStatusBarView.setPanelHolder(holder);
@@ -378,11 +468,6 @@ public class PhoneStatusBar extends BaseStatusBar {
}
});
- if (!ActivityManager.isHighEndGfx()) {
- mStatusBarWindow.setBackground(null);
- mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
- R.color.notification_panel_solid_background)));
- }
if (ENABLE_INTRUDERS) {
mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
mIntruderAlertView.setVisibility(View.GONE);
@@ -398,7 +483,7 @@ public class PhoneStatusBar extends BaseStatusBar {
try {
boolean showNav = mWindowManagerService.hasNavigationBar();
if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
- if (showNav) {
+ if (showNav && !mRecreating) {
mNavigationBarView =
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
@@ -419,6 +504,11 @@ public class PhoneStatusBar extends BaseStatusBar {
mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
mTickerView = mStatusBarView.findViewById(R.id.ticker);
+ /* Destroy the old widget before recreating the expanded dialog
+ to make sure there are no context issues */
+ if (mRecreating)
+ mPowerWidget.destroyWidget();
+
mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems);
mPile.setLayoutTransitionsEnabled(false);
mPile.setLongPressListener(getNotificationLongClicker());
@@ -480,8 +570,26 @@ public class PhoneStatusBar extends BaseStatusBar {
View.STATUS_BAR_DISABLE_CLOCK);
}
- mTicker = new MyTicker(context, mStatusBarView);
+ // Load the Power widget views and set the listeners
+ mPowerWidget = (PowerWidget)mStatusBarWindow.findViewById(R.id.exp_power_stat);
+ mPowerWidget.setGlobalButtonOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_HIDE_ONCHANGE, 0) == 1) {
+ animateCollapsePanels();
+ }
+ }
+ });
+ mPowerWidget.setGlobalButtonOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ animateCollapsePanels();
+ return true;
+ }
+ });
+ mTicker = new MyTicker(context, mStatusBarView);
TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
tickerView.mTicker = mTicker;
@@ -494,6 +602,28 @@ public class PhoneStatusBar extends BaseStatusBar {
mLocationController = new LocationController(mContext); // will post a notification
mBatteryController = new BatteryController(mContext);
mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
+ mBatteryController.addLabelView((TextView)mStatusBarView.findViewById(R.id.battery_text));
+
+ // Dock Battery support
+ mHasDockBattery = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_hasDockBattery);
+
+ if (mHasDockBattery) {
+ mDockBatteryController = new DockBatteryController(mContext);
+ mDockBatteryController.addIconView(
+ (ImageView)mStatusBarView.findViewById(R.id.dock_battery));
+ mDockBatteryController.addLabelView(
+ (TextView)mStatusBarView.findViewById(R.id.dock_battery_text));
+ } else {
+ // Remove dock battery icons if device doesn't hava dock battery support
+ View v = mStatusBarView.findViewById(R.id.dock_battery);
+ if (v != null) mStatusBarView.removeView(v);
+ v = mStatusBarView.findViewById(R.id.dock_battery_text);
+ if (v != null) mStatusBarView.removeView(v);
+ v = mStatusBarView.findViewById(R.id.circle_dock_battery);
+ if (v != null) mStatusBarView.removeView(v);
+ }
+
mNetworkController = new NetworkController(mContext);
mBluetoothController = new BluetoothController(mContext);
final SignalClusterView signalCluster =
@@ -507,6 +637,7 @@ public class PhoneStatusBar extends BaseStatusBar {
if (mEmergencyCallLabel != null) {
mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() {
+ @Override
public void onClick(View v) { }});
mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
@@ -559,20 +690,13 @@ public class PhoneStatusBar extends BaseStatusBar {
} else {
mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
}
-
- if (mSettingsPanel != null) {
- if (!ActivityManager.isHighEndGfx()) {
- mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
- R.color.notification_panel_solid_background)));
- }
- }
}
// wherever you find it, Quick Settings needs a container to survive
mSettingsContainer = (QuickSettingsContainerView)
mStatusBarWindow.findViewById(R.id.quick_settings_container);
if (mSettingsContainer != null) {
- mQS = new QuickSettings(mContext, mSettingsContainer);
+ mQS = new QuickSettingsController(mContext, mSettingsContainer, this);
if (!mNotificationPanelIsFullScreenWidth) {
mSettingsContainer.setSystemUiVisibility(
View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
@@ -583,14 +707,18 @@ public class PhoneStatusBar extends BaseStatusBar {
}
mQS.setService(this);
mQS.setBar(mStatusBarView);
- mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
- mLocationController);
+ mQS.updateResources();
+
+ // Start observing for changes
+ mTilesChangedObserver = new TilesChangedObserver(mHandler);
+ mTilesChangedObserver.startObserving();
+
} else {
mQS = null; // fly away, be free
}
}
- mClingShown = ! (DEBUG_CLINGS
+ mClingShown = ! (DEBUG_CLINGS
|| !Prefs.read(mContext).getBoolean(Prefs.SHOWN_QUICK_SETTINGS_HELP, false));
if (!ENABLE_NOTIFICATION_PANEL_CLING || ActivityManager.isRunningInTestHarness()) {
@@ -614,6 +742,11 @@ public class PhoneStatusBar extends BaseStatusBar {
// listen for USER_SETUP_COMPLETE setting (per-user)
resetUserSetupObserver();
+ mPowerWidget.setupWidget();
+ mPowerWidget.updateVisibility();
+
+ mVelocityTracker = VelocityTracker.obtain();
+
return mStatusBarView;
}
@@ -670,6 +803,10 @@ public class PhoneStatusBar extends BaseStatusBar {
return lp;
}
+ void onBarViewDetached() {
+ // WindowManagerImpl.getDefault().removeView(mStatusBarWindow);
+ }
+
@Override
protected void updateSearchPanel() {
super.updateSearchPanel();
@@ -713,14 +850,16 @@ public class PhoneStatusBar extends BaseStatusBar {
return mNaturalBarHeight;
}
- private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
+ private final View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
+ @Override
public void onClick(View v) {
toggleRecentApps();
}
};
private int mShowSearchHoldoff = 0;
- private Runnable mShowSearchPanel = new Runnable() {
+ private final Runnable mShowSearchPanel = new Runnable() {
+ @Override
public void run() {
showSearchPanel();
awakenDreams();
@@ -728,6 +867,7 @@ public class PhoneStatusBar extends BaseStatusBar {
};
View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
+ @Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
@@ -759,11 +899,7 @@ public class PhoneStatusBar extends BaseStatusBar {
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
-
- mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
- mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
- mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
- mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
+ mNavigationBarView.setListener(mRecentsClickListener,mRecentsPreloadOnTouchListener, mHomeSearchActionListener);
updateSearchPanel();
}
@@ -780,6 +916,12 @@ public class PhoneStatusBar extends BaseStatusBar {
private void repositionNavigationBar() {
if (mNavigationBarView == null) return;
+ CustomTheme newTheme = mContext.getResources().getConfiguration().customTheme;
+ if (newTheme != null &&
+ (mCurrentTheme == null || !mCurrentTheme.equals(newTheme))) {
+ // Nevermind, this will be re-created
+ return;
+ }
prepareNavigationBarView();
mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
@@ -832,14 +974,17 @@ public class PhoneStatusBar extends BaseStatusBar {
mWindowManager.addView(mIntruderAlertView, lp);
}
+ @Override
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ " icon=" + icon);
StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
view.set(icon);
mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+ mPowerWidget.updateAllButtons();
}
+ @Override
public void updateIcon(String slot, int index, int viewIndex,
StatusBarIcon old, StatusBarIcon icon) {
if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
@@ -848,11 +993,13 @@ public class PhoneStatusBar extends BaseStatusBar {
view.set(icon);
}
+ @Override
public void removeIcon(String slot, int index, int viewIndex) {
if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
mStatusIcons.removeViewAt(viewIndex);
}
+ @Override
public void addNotification(IBinder key, StatusBarNotification notification) {
if (DEBUG) Slog.d(TAG, "addNotification score=" + notification.score);
StatusBarIconView iconView = addNotificationViews(key, notification);
@@ -914,7 +1061,7 @@ public class PhoneStatusBar extends BaseStatusBar {
notification.notification.fullScreenIntent.send();
} catch (PendingIntent.CanceledException e) {
}
- } else {
+ } else if (!mRecreating) {
// usual case: status bar visible & not immersive
// show the ticker if there isn't an intruder too
@@ -928,6 +1075,7 @@ public class PhoneStatusBar extends BaseStatusBar {
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
}
+ @Override
public void removeNotification(IBinder key) {
StatusBarNotification old = removeNotificationViews(key);
if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
@@ -1045,7 +1193,7 @@ public class PhoneStatusBar extends BaseStatusBar {
protected void updateCarrierLabelVisibility(boolean force) {
if (!mShowCarrierInPanel) return;
- // The idea here is to only show the carrier label when there is enough room to see it,
+ // The idea here is to only show the carrier label when there is enough room to see it,
// i.e. when there aren't enough notifications to fill the panel.
if (DEBUG) {
Slog.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
@@ -1057,7 +1205,7 @@ public class PhoneStatusBar extends BaseStatusBar {
!(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
&& mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
&& mScrollView.getVisibility() == View.VISIBLE;
-
+
if (force || mCarrierLabelVisible != makeVisible) {
mCarrierLabelVisible = makeVisible;
if (DEBUG) {
@@ -1096,8 +1244,8 @@ public class PhoneStatusBar extends BaseStatusBar {
+ " any=" + any + " clearable=" + clearable);
}
- if (mHasFlipSettings
- && mFlipSettingsView != null
+ if (mHasFlipSettings
+ && mFlipSettingsView != null
&& mFlipSettingsView.getVisibility() == View.VISIBLE
&& mScrollView.getVisibility() != View.VISIBLE) {
// the flip settings panel is unequivocally showing; we should not be shown
@@ -1154,15 +1302,19 @@ public class PhoneStatusBar extends BaseStatusBar {
public void showClock(boolean show) {
if (mStatusBarView == null) return;
+ ContentResolver resolver = mContext.getContentResolver();
View clock = mStatusBarView.findViewById(R.id.clock);
+ mShowClock = (Settings.System.getInt(resolver,
+ Settings.System.STATUS_BAR_CLOCK, 1) == 1);
if (clock != null) {
- clock.setVisibility(show ? View.VISIBLE : View.GONE);
+ clock.setVisibility(show ? (mShowClock ? View.VISIBLE : View.GONE) : View.GONE);
}
}
/**
* State is one or more of the DISABLE constants from StatusBarManager.
*/
+ @Override
public void disable(int state) {
final int old = mDisabled;
final int diff = state ^ old;
@@ -1283,6 +1435,7 @@ public class PhoneStatusBar extends BaseStatusBar {
* All changes to the status bar and notifications funnel through here and are batched.
*/
private class H extends BaseStatusBar.H {
+ @Override
public void handleMessage(Message m) {
super.handleMessage(m);
switch (m.what) {
@@ -1311,6 +1464,7 @@ public class PhoneStatusBar extends BaseStatusBar {
}
View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
+ @Override
public void onFocusChange(View v, boolean hasFocus) {
// Because 'v' is a ViewGroup, all its children will be (un)selected
// too, which allows marqueeing to work.
@@ -1335,11 +1489,11 @@ public class PhoneStatusBar extends BaseStatusBar {
// Expand the window to encompass the full screen in anticipation of the drag.
// This is only possible to do atomically because the status bar is at the top of the screen!
- WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
+ WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarContainer.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
- mWindowManager.updateViewLayout(mStatusBarWindow, lp);
+ mWindowManager.updateViewLayout(mStatusBarContainer, lp);
// Updating the window layout will force an expensive traversal/redraw.
// Kick off the reveal animation after this is complete to avoid animation latency.
@@ -1354,6 +1508,7 @@ public class PhoneStatusBar extends BaseStatusBar {
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
}
+ @Override
public void animateCollapsePanels(int flags) {
if (SPEW) {
Slog.d(TAG, "animateCollapse():"
@@ -1411,7 +1566,7 @@ public class PhoneStatusBar extends BaseStatusBar {
a.setStartDelay(d);
return a;
}
-
+
public Animator start(Animator a) {
a.start();
return a;
@@ -1448,17 +1603,28 @@ public class PhoneStatusBar extends BaseStatusBar {
if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+ final boolean halfWayDone = mScrollView.getVisibility() == View.VISIBLE;
+ final int zeroOutDelays = halfWayDone ? 0 : 1;
+
+ if (!halfWayDone) {
+ mScrollView.setScaleX(0f);
+ mFlipSettingsView.setScaleX(1f);
+ }
+
+ // Only show the Power widget if it should be shown
+ mPowerWidget.updateVisibility();
+
mScrollView.setVisibility(View.VISIBLE);
mScrollViewAnim = start(
- startDelay(FLIP_DURATION_OUT,
+ startDelay(FLIP_DURATION_OUT * zeroOutDelays,
interpolator(mDecelerateInterpolator,
- ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
+ ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f)
.setDuration(FLIP_DURATION_IN)
)));
mFlipSettingsViewAnim = start(
setVisibilityWhenDone(
interpolator(mAccelerateInterpolator,
- ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
+ ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f)
)
.setDuration(FLIP_DURATION_OUT),
mFlipSettingsView, View.INVISIBLE));
@@ -1475,6 +1641,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mClearButton.setAlpha(0f);
setAreThereNotifications(); // this will show/hide the button as necessary
mNotificationPanel.postDelayed(new Runnable() {
+ @Override
public void run() {
updateCarrierLabelVisibility(false);
}
@@ -1512,11 +1679,56 @@ public class PhoneStatusBar extends BaseStatusBar {
mSettingsButton.setVisibility(View.GONE);
mScrollView.setVisibility(View.GONE);
mScrollView.setScaleX(0f);
+ mPowerWidget.setVisibility(View.GONE);
mNotificationButton.setVisibility(View.VISIBLE);
mNotificationButton.setAlpha(1f);
mClearButton.setVisibility(View.GONE);
}
+ public boolean isShowingSettings() {
+ return mHasFlipSettings && mFlipSettingsView.getVisibility() == View.VISIBLE;
+ }
+
+ public void completePartialFlip() {
+ if (mHasFlipSettings) {
+ if (mFlipSettingsView.getVisibility() == View.VISIBLE) {
+ flipToSettings();
+ } else {
+ flipToNotifications();
+ }
+ }
+ }
+
+ public void partialFlip(float progress) {
+ if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
+ if (mScrollViewAnim != null) mScrollViewAnim.cancel();
+ if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
+ if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+ if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+
+ progress = Math.min(Math.max(progress, -1f), 1f);
+ if (progress < 0f) { // notifications side
+ mFlipSettingsView.setScaleX(0f);
+ mFlipSettingsView.setVisibility(View.GONE);
+ mSettingsButton.setVisibility(View.VISIBLE);
+ mSettingsButton.setAlpha(-progress);
+ mScrollView.setVisibility(View.VISIBLE);
+ mScrollView.setScaleX(-progress);
+ mPowerWidget.updateVisibility();
+ mNotificationButton.setVisibility(View.GONE);
+ } else { // settings side
+ mFlipSettingsView.setScaleX(progress);
+ mFlipSettingsView.setVisibility(View.VISIBLE);
+ mSettingsButton.setVisibility(View.GONE);
+ mScrollView.setVisibility(View.GONE);
+ mScrollView.setScaleX(0f);
+ mPowerWidget.setVisibility(View.GONE);
+ mNotificationButton.setVisibility(View.VISIBLE);
+ mNotificationButton.setAlpha(progress);
+ }
+ mClearButton.setVisibility(View.GONE);
+ }
+
public void flipToSettings() {
// Settings are not available in setup
if (!mUserSetup) return;
@@ -1527,26 +1739,34 @@ public class PhoneStatusBar extends BaseStatusBar {
if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+ final boolean halfWayDone = mFlipSettingsView.getVisibility() == View.VISIBLE;
+ final int zeroOutDelays = halfWayDone ? 0 : 1;
+
+ if (!halfWayDone) {
+ mFlipSettingsView.setScaleX(0f);
+ mScrollView.setScaleX(1f);
+ }
+
mFlipSettingsView.setVisibility(View.VISIBLE);
- mFlipSettingsView.setScaleX(0f);
mFlipSettingsViewAnim = start(
- startDelay(FLIP_DURATION_OUT,
+ startDelay(FLIP_DURATION_OUT * zeroOutDelays,
interpolator(mDecelerateInterpolator,
- ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
+ ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f)
.setDuration(FLIP_DURATION_IN)
)));
mScrollViewAnim = start(
setVisibilityWhenDone(
interpolator(mAccelerateInterpolator,
- ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
+ ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f)
)
- .setDuration(FLIP_DURATION_OUT),
+ .setDuration(FLIP_DURATION_OUT),
mScrollView, View.INVISIBLE));
mSettingsButtonAnim = start(
setVisibilityWhenDone(
ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
.setDuration(FLIP_DURATION),
mScrollView, View.INVISIBLE));
+ mPowerWidget.setVisibility(View.GONE);
mNotificationButton.setVisibility(View.VISIBLE);
mNotificationButtonAnim = start(
ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
@@ -1557,6 +1777,7 @@ public class PhoneStatusBar extends BaseStatusBar {
.setDuration(FLIP_DURATION),
mClearButton, View.INVISIBLE));
mNotificationPanel.postDelayed(new Runnable() {
+ @Override
public void run() {
updateCarrierLabelVisibility(false);
}
@@ -1578,7 +1799,8 @@ public class PhoneStatusBar extends BaseStatusBar {
}
void makeExpandedInvisibleSoon() {
- mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50);
+ mHandler.postDelayed(new Runnable() { @Override
+ public void run() { makeExpandedInvisible(); }}, 50);
}
void makeExpandedInvisible() {
@@ -1602,6 +1824,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mScrollView.setScaleX(1f);
mScrollView.setVisibility(View.VISIBLE);
+ mPowerWidget.updateVisibility();
mSettingsButton.setAlpha(1f);
mSettingsButton.setVisibility(View.VISIBLE);
mNotificationPanel.setVisibility(View.GONE);
@@ -1617,11 +1840,11 @@ public class PhoneStatusBar extends BaseStatusBar {
visibilityChanged(false);
// Shrink the window to the size of the status bar only
- WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
+ WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarContainer.getLayoutParams();
lp.height = getStatusBarHeight();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
- mWindowManager.updateViewLayout(mStatusBarWindow, lp);
+ mWindowManager.updateViewLayout(mStatusBarContainer, lp);
if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
@@ -1638,13 +1861,13 @@ public class PhoneStatusBar extends BaseStatusBar {
/**
* Enables or disables layers on the children of the notifications pile.
- *
+ *
* When layers are enabled, this method attempts to enable layers for the minimal
* number of children. Only children visible when the notification area is fully
* expanded will receive a layer. The technique used in this method might cause
* more children than necessary to get a layer (at most one extra child with the
* current UI.)
- *
+ *
* @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
*/
private void setPileLayers(int layerType) {
@@ -1657,7 +1880,7 @@ public class PhoneStatusBar extends BaseStatusBar {
}
break;
case View.LAYER_TYPE_HARDWARE:
- final int[] location = new int[2];
+ final int[] location = new int[2];
mNotificationPanel.getLocationInWindow(location);
final int left = location[0];
@@ -1740,6 +1963,78 @@ public class PhoneStatusBar extends BaseStatusBar {
animateExpandNotificationsPanel();
}
+ private void adjustBrightness(int x) {
+ float raw = ((float) x) / mScreenWidth;
+
+ // Add a padding to the brightness control on both sides to
+ // make it easier to reach min/max brightness
+ float padded = Math.min(1.0f - BRIGHTNESS_CONTROL_PADDING,
+ Math.max(BRIGHTNESS_CONTROL_PADDING, raw));
+ float value = (padded - BRIGHTNESS_CONTROL_PADDING) /
+ (1 - (2.0f * BRIGHTNESS_CONTROL_PADDING));
+
+ int newBrightness = mMinBrightness + (int) Math.round(value *
+ (android.os.PowerManager.BRIGHTNESS_ON - mMinBrightness));
+ newBrightness = Math.min(newBrightness, android.os.PowerManager.BRIGHTNESS_ON);
+ newBrightness = Math.max(newBrightness, mMinBrightness);
+
+ try {
+ IPowerManager power = IPowerManager.Stub.asInterface(
+ ServiceManager.getService("power"));
+ if (power != null) {
+ power.setTemporaryScreenBrightnessSettingOverride(newBrightness);
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, newBrightness);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Setting Brightness failed: " + e);
+ }
+ }
+
+ private void brightnessControl(MotionEvent event)
+ {
+ if (mBrightnessControl)
+ {
+ final int action = event.getAction();
+ final int x = (int)event.getRawX();
+ final int y = (int)event.getRawY();
+ if (action == MotionEvent.ACTION_DOWN) {
+ mLinger = 0;
+ mInitialTouchX = x;
+ mInitialTouchY = y;
+ mHandler.removeCallbacks(mLongPressBrightnessChange);
+ if ((y + mViewDelta) < mNotificationHeaderHeight) {
+ mHandler.postDelayed(mLongPressBrightnessChange,
+ BRIGHTNESS_CONTROL_LONG_PRESS_TIMEOUT);
+ }
+ } else if (action == MotionEvent.ACTION_MOVE) {
+ if ((y + mViewDelta) < mNotificationHeaderHeight) {
+ mVelocityTracker.computeCurrentVelocity(1000);
+ float yVel = mVelocityTracker.getYVelocity();
+ yVel = Math.abs(yVel);
+ if (yVel < 50.0f) {
+ if (mLinger > BRIGHTNESS_CONTROL_LINGER_THRESHOLD) {
+ adjustBrightness(x);
+ } else {
+ mLinger++;
+ }
+ }
+ int touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+ if (Math.abs(x - mInitialTouchX) > touchSlop ||
+ Math.abs(y - mInitialTouchY) > touchSlop) {
+ mHandler.removeCallbacks(mLongPressBrightnessChange);
+ }
+ } else {
+ mHandler.removeCallbacks(mLongPressBrightnessChange);
+ }
+ } else if (action == MotionEvent.ACTION_UP
+ || action == MotionEvent.ACTION_CANCEL) {
+ mHandler.removeCallbacks(mLongPressBrightnessChange);
+ mLinger = 0;
+ }
+ }
+ }
+
public boolean interceptTouchEvent(MotionEvent event) {
if (SPEW) {
Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
@@ -1757,11 +2052,13 @@ public class PhoneStatusBar extends BaseStatusBar {
mGestureRec.add(event);
}
+ brightnessControl(event);
+
// Cling (first-run help) handling.
// The cling is supposed to show the first time you drag, or even tap, the status bar.
- // It should show the notification panel, then fade in after half a second, giving you
+ // It should show the notification panel, then fade in after half a second, giving you
// an explanation of what just happened, as well as teach you how to access quick
- // settings (another drag). The user can dismiss the cling by clicking OK or by
+ // settings (another drag). The user can dismiss the cling by clicking OK or by
// dragging quick settings into view.
final int act = event.getActionMasked();
if (mSuppressStatusBarDrags) {
@@ -1824,27 +2121,61 @@ public class PhoneStatusBar extends BaseStatusBar {
final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
+ final View signal2 = mStatusBarView.findViewById(R.id.signal_cluster_text);
final View battery = mStatusBarView.findViewById(R.id.battery);
+ final View battery2 = mStatusBarView.findViewById(R.id.battery_text);
+ final View battery3 = mStatusBarView.findViewById(R.id.circle_battery);
+ final View dockBattery = mStatusBarView.findViewById(R.id.dock_battery);
+ final View dockBattery2 = mStatusBarView.findViewById(R.id.dock_battery_text);
+ final View dockBattery3 = mStatusBarView.findViewById(R.id.circle_dock_battery);
final View clock = mStatusBarView.findViewById(R.id.clock);
+ List<ObjectAnimator> lightsOutObjs = new ArrayList<ObjectAnimator>();
+ lightsOutObjs.add(ObjectAnimator.ofFloat(notifications, View.ALPHA, 0));
+ lightsOutObjs.add(ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0));
+ lightsOutObjs.add(ObjectAnimator.ofFloat(signal, View.ALPHA, 0));
+ lightsOutObjs.add(ObjectAnimator.ofFloat(signal2, View.ALPHA, 0));
+ lightsOutObjs.add(ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f));
+ lightsOutObjs.add(ObjectAnimator.ofFloat(battery2, View.ALPHA, 0.5f));
+ lightsOutObjs.add(ObjectAnimator.ofFloat(battery3, View.ALPHA, 0.5f));
+ if (dockBattery != null) {
+ lightsOutObjs.add(ObjectAnimator.ofFloat(dockBattery, View.ALPHA, 0.5f));
+ }
+ if (dockBattery2 != null) {
+ lightsOutObjs.add(ObjectAnimator.ofFloat(dockBattery2, View.ALPHA, 0.5f));
+ }
+ if (dockBattery3 != null) {
+ lightsOutObjs.add(ObjectAnimator.ofFloat(dockBattery3, View.ALPHA, 0.5f));
+ }
+ lightsOutObjs.add(ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f));
+
+ List<ObjectAnimator> lightsOnObjs = new ArrayList<ObjectAnimator>();
+ lightsOnObjs.add(ObjectAnimator.ofFloat(notifications, View.ALPHA, 1));
+ lightsOnObjs.add(ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1));
+ lightsOnObjs.add(ObjectAnimator.ofFloat(signal, View.ALPHA, 1));
+ lightsOnObjs.add(ObjectAnimator.ofFloat(signal2, View.ALPHA, 1));
+ lightsOnObjs.add(ObjectAnimator.ofFloat(battery, View.ALPHA, 1));
+ lightsOnObjs.add(ObjectAnimator.ofFloat(battery2, View.ALPHA, 1));
+ lightsOnObjs.add(ObjectAnimator.ofFloat(battery3, View.ALPHA, 1));
+ if (dockBattery != null) {
+ lightsOnObjs.add(ObjectAnimator.ofFloat(dockBattery, View.ALPHA, 1));
+ }
+ if (dockBattery2 != null) {
+ lightsOnObjs.add(ObjectAnimator.ofFloat(dockBattery2, View.ALPHA, 1));
+ }
+ if (dockBattery3 != null) {
+ lightsOnObjs.add(ObjectAnimator.ofFloat(dockBattery3, View.ALPHA, 1));
+ }
+ lightsOnObjs.add(ObjectAnimator.ofFloat(clock, View.ALPHA, 1));
+
final AnimatorSet lightsOutAnim = new AnimatorSet();
lightsOutAnim.playTogether(
- ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
- ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
- ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
- ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
- ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
- );
+ lightsOutObjs.toArray(new ObjectAnimator[lightsOutObjs.size()]));
lightsOutAnim.setDuration(750);
final AnimatorSet lightsOnAnim = new AnimatorSet();
lightsOnAnim.playTogether(
- ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
- ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
- ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
- ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
- ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
- );
+ lightsOnObjs.toArray(new ObjectAnimator[lightsOnObjs.size()]));
lightsOnAnim.setDuration(250);
mLightsOutAnimation = lightsOutAnim;
@@ -1880,6 +2211,7 @@ public class PhoneStatusBar extends BaseStatusBar {
}
}
+ @Override
public void topAppWindowChanged(boolean showMenu) {
if (DEBUG) {
Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
@@ -1921,7 +2253,7 @@ public class PhoneStatusBar extends BaseStatusBar {
// until status bar window is attached to the window manager,
// because... well, what's the point otherwise? And trying to
// run a ticker without being attached will crash!
- if (n.notification.tickerText != null && mStatusBarWindow.getWindowToken() != null) {
+ if (n.notification.tickerText != null && mStatusBarContainer.getWindowToken() != null) {
if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
| StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
mTicker.addEntry(n);
@@ -1952,6 +2284,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mTickingDoneListener));
}
+ @Override
public void tickerHalting() {
mStatusBarContents.setVisibility(View.VISIBLE);
mTickerView.setVisibility(View.GONE);
@@ -1961,11 +2294,14 @@ public class PhoneStatusBar extends BaseStatusBar {
}
Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
+ @Override
public void onAnimationEnd(Animation animation) {
mTicking = false;
}
+ @Override
public void onAnimationRepeat(Animation animation) {
}
+ @Override
public void onAnimationStart(Animation animation) {
}
};
@@ -1983,6 +2319,7 @@ public class PhoneStatusBar extends BaseStatusBar {
+ ") " + v.getWidth() + "x" + v.getHeight() + "]";
}
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
synchronized (mQueueLock) {
pw.println("Current Status Bar state:");
@@ -1990,9 +2327,9 @@ public class PhoneStatusBar extends BaseStatusBar {
+ ", mTrackingPosition=" + mTrackingPosition);
pw.println(" mTicking=" + mTicking);
pw.println(" mTracking=" + mTracking);
- pw.println(" mNotificationPanel=" +
- ((mNotificationPanel == null)
- ? "null"
+ pw.println(" mNotificationPanel=" +
+ ((mNotificationPanel == null)
+ ? "null"
: (mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""))));
pw.println(" mAnimating=" + mAnimating
+ ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
@@ -2039,6 +2376,7 @@ public class PhoneStatusBar extends BaseStatusBar {
pw.println("see the logcat for a dump of the views we have created.");
// must happen on ui thread
mHandler.post(new Runnable() {
+ @Override
public void run() {
mStatusBarView.getLocationOnScreen(mAbsPos);
Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
@@ -2066,7 +2404,6 @@ public class PhoneStatusBar extends BaseStatusBar {
private void addStatusBarWindow() {
// Put up the view
final int height = getStatusBarHeight();
-
// Now that the status bar window encompasses the sliding panel and its
// translucent backdrop, the entire thing is made TRANSLUCENT and is
// hardware-accelerated.
@@ -2086,7 +2423,8 @@ public class PhoneStatusBar extends BaseStatusBar {
lp.packageName = mContext.getPackageName();
makeStatusBarView();
- mWindowManager.addView(mStatusBarWindow, lp);
+ mStatusBarContainer.addView(mStatusBarWindow);
+ mWindowManager.addView(mStatusBarContainer, lp);
}
void setNotificationIconVisibility(boolean visible, int anim) {
@@ -2138,12 +2476,13 @@ public class PhoneStatusBar extends BaseStatusBar {
void updateDisplaySize() {
mDisplay.getMetrics(mDisplayMetrics);
if (DEBUG_GESTURES) {
- mGestureRec.tag("display",
+ mGestureRec.tag("display",
String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
}
}
- private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
+ private final View.OnClickListener mClearButtonListener = new View.OnClickListener() {
+ @Override
public void onClick(View v) {
synchronized (mNotificationData) {
// animate-swipe all dismissable notifications, then animate the shade closed
@@ -2232,7 +2571,8 @@ public class PhoneStatusBar extends BaseStatusBar {
animateCollapsePanels();
}
- private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
+ private final View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
+ @Override
public void onClick(View v) {
if (mHasSettingsPanel) {
animateExpandSettingsPanel();
@@ -2243,20 +2583,23 @@ public class PhoneStatusBar extends BaseStatusBar {
}
};
- private View.OnClickListener mClockClickListener = new View.OnClickListener() {
+ private final View.OnClickListener mClockClickListener = new View.OnClickListener() {
+ @Override
public void onClick(View v) {
startActivityDismissingKeyguard(
new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
}
};
- private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
+ private final View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
+ @Override
public void onClick(View v) {
animateExpandNotificationsPanel();
}
};
- private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) Slog.v(TAG, "onReceive: " + intent);
String action = intent.getAction();
@@ -2280,7 +2623,6 @@ public class PhoneStatusBar extends BaseStatusBar {
Slog.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
}
mDisplay.getSize(mCurrentDisplaySize);
-
updateResources();
repositionNavigationBar();
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
@@ -2319,6 +2661,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
}
+ @Override
public void dismissIntruder() {
if (mCurrentlyIntrudingNotification == null) return;
@@ -2332,6 +2675,61 @@ public class PhoneStatusBar extends BaseStatusBar {
}
}
+ private static void copyNotifications(ArrayList<Pair<IBinder, StatusBarNotification>> dest,
+ NotificationData source) {
+ int N = source.size();
+ for (int i = 0; i < N; i++) {
+ NotificationData.Entry entry = source.get(i);
+ dest.add(Pair.create(entry.key, entry.notification));
+ }
+ }
+
+ private void recreateStatusBar() {
+ mRecreating = true;
+ mStatusBarContainer.removeAllViews();
+
+ // extract icons from the soon-to-be recreated viewgroup.
+ int nIcons = mStatusIcons.getChildCount();
+ ArrayList<StatusBarIcon> icons = new ArrayList<StatusBarIcon>(nIcons);
+ ArrayList<String> iconSlots = new ArrayList<String>(nIcons);
+ for (int i = 0; i < nIcons; i++) {
+ StatusBarIconView iconView = (StatusBarIconView)mStatusIcons.getChildAt(i);
+ icons.add(iconView.getStatusBarIcon());
+ iconSlots.add(iconView.getStatusBarSlot());
+ }
+
+ // extract notifications.
+ int nNotifs = mNotificationData.size();
+ ArrayList<Pair<IBinder, StatusBarNotification>> notifications =
+ new ArrayList<Pair<IBinder, StatusBarNotification>>(nNotifs);
+ copyNotifications(notifications, mNotificationData);
+ mNotificationData.clear();
+
+ makeStatusBarView();
+ repositionNavigationBar();
+ mNavigationBarView.updateResources();
+
+ // recreate StatusBarIconViews.
+ for (int i = 0; i < nIcons; i++) {
+ StatusBarIcon icon = icons.get(i);
+ String slot = iconSlots.get(i);
+ addIcon(slot, i, i, icon);
+ }
+
+ // recreate notifications.
+ for (int i = 0; i < nNotifs; i++) {
+ Pair<IBinder, StatusBarNotification> notifData = notifications.get(i);
+ addNotificationViews(notifData.first, notifData.second);
+ }
+
+ setAreThereNotifications();
+
+ mStatusBarContainer.addView(mStatusBarWindow);
+
+ updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+ mRecreating = false;
+ }
+
/**
* Reload some of our resources when the configuration changes.
*
@@ -2343,14 +2741,23 @@ public class PhoneStatusBar extends BaseStatusBar {
final Context context = mContext;
final Resources res = context.getResources();
- if (mClearButton instanceof TextView) {
- ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
+ // detect theme change.
+ CustomTheme newTheme = res.getConfiguration().customTheme;
+ if (newTheme != null &&
+ (mCurrentTheme == null || !mCurrentTheme.equals(newTheme))) {
+ mCurrentTheme = (CustomTheme)newTheme.clone();
+ recreateStatusBar();
+ } else {
+
+ if (mClearButton instanceof TextView) {
+ ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
+ }
+ loadDimens();
}
// Update the QuickSettings container
if (mQS != null) mQS.updateResources();
- loadDimens();
}
protected void loadDimens() {
@@ -2427,6 +2834,7 @@ public class PhoneStatusBar extends BaseStatusBar {
}
Runnable mStartTracing = new Runnable() {
+ @Override
public void run() {
vibrate();
SystemClock.sleep(250);
@@ -2437,6 +2845,7 @@ public class PhoneStatusBar extends BaseStatusBar {
};
Runnable mStopTracing = new Runnable() {
+ @Override
public void run() {
android.os.Debug.stopMethodTracing();
Slog.d(TAG, "stopTracing");
@@ -2452,7 +2861,7 @@ public class PhoneStatusBar extends BaseStatusBar {
@Override
protected boolean shouldDisableNavbarGestures() {
return !isDeviceProvisioned()
- || mExpandedVisible
+ || mExpandedVisible || NavigationBarView.getEditMode()
|| (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
}
@@ -2489,4 +2898,50 @@ public class PhoneStatusBar extends BaseStatusBar {
public void setBounds(Rect bounds) {
}
}
+
+ /**
+ * ContentObserver to watch for Quick Settings tiles changes
+ * @author dvtonder
+ *
+ */
+ private class TilesChangedObserver extends ContentObserver {
+ public TilesChangedObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ if (mSettingsContainer != null) {
+ mQS.updateResources();
+ }
+ }
+
+ public void startObserving() {
+ final ContentResolver cr = mContext.getContentResolver();
+ cr.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.QUICK_SETTINGS_TILES),
+ false, this);
+
+ cr.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.QS_DYNAMIC_ALARM),
+ false, this);
+
+ cr.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.QS_DYNAMIC_BUGREPORT),
+ false, this);
+
+ cr.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.QS_DYNAMIC_IME),
+ false, this);
+
+ cr.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.QS_DYNAMIC_USBTETHER),
+ false, this);
+
+ cr.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.QS_DYNAMIC_WIFI),
+ false, this);
+ }
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index af6a149..a86a869 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -84,6 +84,12 @@ public class PhoneStatusBarView extends PanelBar {
}
@Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mBar.onBarViewDetached();
+ }
+
+ @Override
public boolean panelsEnabled() {
return ((mBar.mDisabled & StatusBarManager.DISABLE_EXPAND) == 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 9b0a320..9e22567 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -635,7 +635,7 @@ class QuickSettings {
// TODO: Jump into the alarm application
Intent intent = new Intent();
intent.setComponent(new ComponentName(
- "com.google.android.deskclock",
+ "com.android.deskclock",
"com.android.deskclock.AlarmClock"));
startSettingsActivity(intent);
}
@@ -791,6 +791,7 @@ class QuickSettings {
}
private Runnable mDismissBrightnessDialogRunnable = new Runnable() {
+ @Override
public void run() {
if (mBrightnessDialog != null && mBrightnessDialog.isShowing()) {
mBrightnessDialog.dismiss();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java
index 4e8339e..2a8608e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsContainerView.java
@@ -29,7 +29,7 @@ import com.android.systemui.R;
/**
*
*/
-class QuickSettingsContainerView extends FrameLayout {
+public class QuickSettingsContainerView extends FrameLayout {
// The number of columns in the QuickSettings grid
private int mNumColumns;
@@ -108,11 +108,11 @@ class QuickSettingsContainerView extends FrameLayout {
int cursor = 0;
for (int i = 0; i < N; ++i) {
QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i);
- ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) v.getLayoutParams();
+ ViewGroup.LayoutParams lp = v.getLayoutParams();
if (v.getVisibility() != GONE) {
int col = cursor % mNumColumns;
int colSpan = v.getColumnSpan();
- int row = (int) (cursor / mNumColumns);
+ int row = cursor / mNumColumns;
// Push the item to the next row if it can't fit on this one
if ((col + colSpan) > mNumColumns) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java
new file mode 100644
index 0000000..8aed0c3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java
@@ -0,0 +1,496 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+
+import com.android.systemui.quicksettings.AirplaneModeTile;
+import com.android.systemui.quicksettings.AlarmTile;
+import com.android.systemui.quicksettings.AutoRotateTile;
+import com.android.systemui.quicksettings.BatteryTile;
+import com.android.systemui.quicksettings.BluetoothTile;
+import com.android.systemui.quicksettings.BrightnessTile;
+import com.android.systemui.quicksettings.BugReportTile;
+import com.android.systemui.quicksettings.NfcTile;
+import com.android.systemui.quicksettings.QuietHoursTile;
+import com.android.systemui.quicksettings.ScreenTimeoutTile;
+import com.android.systemui.quicksettings.TorchTile;
+import com.android.systemui.quicksettings.GPSTile;
+import com.android.systemui.quicksettings.InputMethodTile;
+import com.android.systemui.quicksettings.MobileNetworkTile;
+import com.android.systemui.quicksettings.MobileNetworkTypeTile;
+import com.android.systemui.quicksettings.PreferencesTile;
+import com.android.systemui.quicksettings.ProfileTile;
+import com.android.systemui.quicksettings.QuickSettingsTile;
+import com.android.systemui.quicksettings.RingerModeTile;
+import com.android.systemui.quicksettings.SleepScreenTile;
+import com.android.systemui.quicksettings.SyncTile;
+import com.android.systemui.quicksettings.ToggleLockscreenTile;
+import com.android.systemui.quicksettings.UsbTetherTile;
+import com.android.systemui.quicksettings.UserTile;
+import com.android.systemui.quicksettings.WiFiDisplayTile;
+import com.android.systemui.quicksettings.WiFiTile;
+import com.android.systemui.quicksettings.WifiAPTile;
+
+public class QuickSettingsController {
+ private static String TAG = "QuickSettingsController";
+
+ // Stores the broadcast receivers and content observers
+ // quick tiles register for.
+ public HashMap<String, ArrayList<QuickSettingsTile>> mReceiverMap
+ = new HashMap<String, ArrayList<QuickSettingsTile>>();
+ public HashMap<Uri, ArrayList<QuickSettingsTile>> mObserverMap
+ = new HashMap<Uri, ArrayList<QuickSettingsTile>>();
+
+ /**
+ * START OF DATA MATCHING BLOCK
+ *
+ * THE FOLLOWING DATA MUST BE KEPT UP-TO-DATE WITH THE DATA IN
+ * com.android.settings.cyanogenmod.QuickSettingsUtil IN THE
+ * Settings PACKAGE.
+ */
+ public static final String TILE_USER = "toggleUser";
+ public static final String TILE_BATTERY = "toggleBattery";
+ public static final String TILE_SETTINGS = "toggleSettings";
+ public static final String TILE_WIFI = "toggleWifi";
+ public static final String TILE_GPS = "toggleGPS";
+ public static final String TILE_BLUETOOTH = "toggleBluetooth";
+ public static final String TILE_BRIGHTNESS = "toggleBrightness";
+ public static final String TILE_RINGER = "toggleSound";
+ public static final String TILE_SYNC = "toggleSync";
+ public static final String TILE_WIFIAP = "toggleWifiAp";
+ public static final String TILE_SCREENTIMEOUT = "toggleScreenTimeout";
+ public static final String TILE_MOBILEDATA = "toggleMobileData";
+ public static final String TILE_LOCKSCREEN = "toggleLockScreen";
+ public static final String TILE_NETWORKMODE = "toggleNetworkMode";
+ public static final String TILE_AUTOROTATE = "toggleAutoRotate";
+ public static final String TILE_AIRPLANE = "toggleAirplane";
+ public static final String TILE_TORCH = "toggleFlashlight"; // Keep old string for compatibility
+ public static final String TILE_SLEEP = "toggleSleepMode";
+ public static final String TILE_LTE = "toggleLte";
+ public static final String TILE_WIMAX = "toggleWimax";
+ public static final String TILE_PROFILE = "toggleProfile";
+ public static final String TILE_NFC = "toggleNfc";
+ public static final String TILE_USBTETHER = "toggleUsbTether";
+ public static final String TILE_QUIETHOURS = "toggleQuietHours";
+
+ private static final String TILE_DELIMITER = "|";
+ private static ArrayList<String> TILES_DEFAULT = new ArrayList<String>();
+
+ static {
+ TILES_DEFAULT.add(TILE_USER);
+ TILES_DEFAULT.add(TILE_BRIGHTNESS);
+ TILES_DEFAULT.add(TILE_SETTINGS);
+ TILES_DEFAULT.add(TILE_WIFI);
+ TILES_DEFAULT.add(TILE_MOBILEDATA);
+ TILES_DEFAULT.add(TILE_BATTERY);
+ TILES_DEFAULT.add(TILE_AIRPLANE);
+ TILES_DEFAULT.add(TILE_BLUETOOTH);
+ }
+
+ /**
+ * END OF DATA MATCHING BLOCK
+ */
+
+ private final Context mContext;
+ public PanelBar mBar;
+ private final QuickSettingsContainerView mContainerView;
+ private final Handler mHandler;
+ private BroadcastReceiver mReceiver;
+ private ContentObserver mObserver;
+ private final ArrayList<Integer> mQuickSettings;
+ public PhoneStatusBar mStatusBarService;
+
+ // Constants for use in switch statement
+ public static final int WIFI_TILE = 0;
+ public static final int MOBILE_NETWORK_TILE = 1;
+ public static final int AIRPLANE_MODE_TILE = 2;
+ public static final int BLUETOOTH_TILE = 3;
+ public static final int RINGER_TILE = 4;
+ public static final int SLEEP_TILE = 5;
+ public static final int TOGGLE_LOCKSCREEN_TILE = 6;
+ public static final int GPS_TILE = 7;
+ public static final int AUTO_ROTATION_TILE = 8;
+ public static final int BRIGHTNESS_TILE = 9;
+ public static final int MOBILE_NETWORK_TYPE_TILE = 10;
+ public static final int SETTINGS_TILE = 11;
+ public static final int BATTERY_TILE = 12;
+ public static final int IME_TILE = 13;
+ public static final int ALARM_TILE = 14;
+ public static final int BUG_REPORT_TILE = 15;
+ public static final int WIFI_DISPLAY_TILE = 16;
+ public static final int TORCH_TILE = 17;
+ public static final int WIFIAP_TILE = 18;
+ public static final int PROFILE_TILE = 19;
+ public static final int SYNC_TILE = 20;
+ public static final int NFC_TILE = 21;
+ public static final int SCREENTIMEOUT_TILE = 22;
+ public static final int USBTETHER_TILE = 23;
+ public static final int QUIET_HOURS_TILE = 24;
+ public static final int USER_TILE = 99;
+ private InputMethodTile IMETile;
+
+ public QuickSettingsController(Context context, QuickSettingsContainerView container, PhoneStatusBar statusBarService) {
+ mContext = context;
+ mContainerView = container;
+ mHandler = new Handler();
+ mStatusBarService = statusBarService;
+ mQuickSettings = new ArrayList<Integer>();
+ }
+
+ void loadTiles() {
+
+ // Filter items not compatible with device
+ boolean bluetoothSupported = deviceSupportsBluetooth();
+ boolean telephonySupported = deviceSupportsTelephony();
+
+ if (!bluetoothSupported) {
+ TILES_DEFAULT.remove(TILE_BLUETOOTH);
+ }
+ if (!telephonySupported) {
+ TILES_DEFAULT.remove(TILE_WIFIAP);
+ TILES_DEFAULT.remove(TILE_MOBILEDATA);
+ TILES_DEFAULT.remove(TILE_NETWORKMODE);
+ }
+
+ // Read the stored list of tiles
+ ContentResolver resolver = mContext.getContentResolver();
+ String tiles = Settings.System.getString(resolver, Settings.System.QUICK_SETTINGS_TILES);
+ if (tiles == null) {
+ Log.i(TAG, "Default tiles being loaded");
+ tiles = TextUtils.join(TILE_DELIMITER, TILES_DEFAULT);
+ }
+
+ Log.i(TAG, "Tiles list: " + tiles);
+
+ // Clear the list
+ mQuickSettings.clear();
+
+ // Split out the tile names and add to the list
+ for (String tile : tiles.split("\\|")) {
+ if (tile.equals(TILE_USER)) {
+ mQuickSettings.add(USER_TILE);
+ } else if (tile.equals(TILE_BATTERY)) {
+ mQuickSettings.add(BATTERY_TILE);
+ } else if (tile.equals(TILE_SETTINGS)) {
+ mQuickSettings.add(SETTINGS_TILE);
+ } else if (tile.equals(TILE_WIFI)) {
+ mQuickSettings.add(WIFI_TILE);
+ } else if (tile.equals(TILE_GPS)) {
+ mQuickSettings.add(GPS_TILE);
+ } else if (tile.equals(TILE_BLUETOOTH)) {
+ if(bluetoothSupported) {
+ mQuickSettings.add(BLUETOOTH_TILE);
+ }
+ } else if (tile.equals(TILE_BRIGHTNESS)) {
+ mQuickSettings.add(BRIGHTNESS_TILE);
+ } else if (tile.equals(TILE_RINGER)) {
+ mQuickSettings.add(RINGER_TILE);
+ } else if (tile.equals(TILE_SYNC)) {
+ mQuickSettings.add(SYNC_TILE);
+ } else if (tile.equals(TILE_WIFIAP)) {
+ if(telephonySupported) {
+ mQuickSettings.add(WIFIAP_TILE);
+ }
+ } else if (tile.equals(TILE_SCREENTIMEOUT)) {
+ mQuickSettings.add(SCREENTIMEOUT_TILE);
+ } else if (tile.equals(TILE_MOBILEDATA)) {
+ if(telephonySupported) {
+ mQuickSettings.add(MOBILE_NETWORK_TILE);
+ }
+ } else if (tile.equals(TILE_LOCKSCREEN)) {
+ mQuickSettings.add(TOGGLE_LOCKSCREEN_TILE);
+ } else if (tile.equals(TILE_NETWORKMODE)) {
+ if(telephonySupported) {
+ mQuickSettings.add(MOBILE_NETWORK_TYPE_TILE);
+ }
+ } else if (tile.equals(TILE_AUTOROTATE)) {
+ mQuickSettings.add(AUTO_ROTATION_TILE);
+ } else if (tile.equals(TILE_AIRPLANE)) {
+ mQuickSettings.add(AIRPLANE_MODE_TILE);
+ } else if (tile.equals(TILE_TORCH)) {
+ mQuickSettings.add(TORCH_TILE);
+ } else if (tile.equals(TILE_SLEEP)) {
+ mQuickSettings.add(SLEEP_TILE);
+ } else if (tile.equals(TILE_PROFILE)) {
+ if (systemProfilesEnabled(resolver)) {
+ mQuickSettings.add(PROFILE_TILE);
+ }
+ } else if (tile.equals(TILE_NFC)) {
+ // User cannot add the NFC tile if the device does not support it
+ // No need to check again here
+ mQuickSettings.add(NFC_TILE);
+ } else if (tile.equals(TILE_WIMAX)) {
+ // Not available yet
+ } else if (tile.equals(TILE_LTE)) {
+ // Not available yet
+ } else if (tile.equals(TILE_QUIETHOURS)) {
+ mQuickSettings.add(QUIET_HOURS_TILE);
+ }
+ }
+
+ // Load the dynamic tiles
+ // These toggles must be the last ones added to the view, as they will show
+ // only when they are needed
+ if (Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_ALARM, 1) == 1) {
+ mQuickSettings.add(ALARM_TILE);
+ }
+ if (Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_BUGREPORT, 1) == 1) {
+ mQuickSettings.add(BUG_REPORT_TILE);
+ }
+ if (Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_WIFI, 1) == 1) {
+ mQuickSettings.add(WIFI_DISPLAY_TILE);
+ }
+ if (Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_IME, 1) == 1) {
+ mQuickSettings.add(IME_TILE);
+ }
+ if (deviceSupportsUsbTether() && Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_USBTETHER, 1) == 1) {
+ mQuickSettings.add(USBTETHER_TILE);
+ }
+ }
+
+ private void setupQuickSettings() {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ // Clear out old receiver
+ if (mReceiver != null) {
+ mContext.unregisterReceiver(mReceiver);
+ }
+ mReceiver = new QSBroadcastReceiver();
+ mReceiverMap.clear();
+ ContentResolver resolver = mContext.getContentResolver();
+ // Clear out old observer
+ if (mObserver != null) {
+ resolver.unregisterContentObserver(mObserver);
+ }
+ mObserver = new QuickSettingsObserver(mHandler);
+ mObserverMap.clear();
+ addQuickSettings(inflater);
+ setupBroadcastReceiver();
+ setupContentObserver();
+ }
+
+ void setupContentObserver() {
+ ContentResolver resolver = mContext.getContentResolver();
+ for (Uri uri : mObserverMap.keySet()) {
+ resolver.registerContentObserver(uri, false, mObserver);
+ }
+ }
+
+ private class QuickSettingsObserver extends ContentObserver {
+ public QuickSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ ContentResolver resolver = mContext.getContentResolver();
+ for (QuickSettingsTile tile : mObserverMap.get(uri)) {
+ tile.onChangeUri(resolver, uri);
+ }
+ }
+ }
+
+ void setupBroadcastReceiver() {
+ IntentFilter filter = new IntentFilter();
+ for (String action : mReceiverMap.keySet()) {
+ filter.addAction(action);
+ }
+ mContext.registerReceiver(mReceiver, filter);
+ }
+
+ private void registerInMap(Object item, QuickSettingsTile tile, HashMap map) {
+ if (map.keySet().contains(item)) {
+ ArrayList list = (ArrayList) map.get(item);
+ if (!list.contains(tile)) {
+ list.add(tile);
+ }
+ } else {
+ ArrayList<QuickSettingsTile> list = new ArrayList<QuickSettingsTile>();
+ list.add(tile);
+ map.put(item, list);
+ }
+ }
+
+ public void registerAction(Object action, QuickSettingsTile tile) {
+ registerInMap(action, tile, mReceiverMap);
+ }
+
+ public void registerObservedContent(Uri uri, QuickSettingsTile tile) {
+ registerInMap(uri, tile, mObserverMap);
+ }
+
+ private class QSBroadcastReceiver extends BroadcastReceiver {
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action != null) {
+ for (QuickSettingsTile t : mReceiverMap.get(action)) {
+ t.onReceive(context, intent);
+ }
+ }
+ }
+ };
+
+ boolean deviceSupportsTelephony() {
+ PackageManager pm = mContext.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+ }
+
+ boolean deviceSupportsBluetooth() {
+ return (BluetoothAdapter.getDefaultAdapter() != null);
+ }
+
+ boolean deviceSupportsUsbTether() {
+ ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ return (cm.getTetherableUsbRegexs().length != 0);
+ }
+
+ boolean systemProfilesEnabled(ContentResolver resolver) {
+ return (Settings.System.getInt(resolver, Settings.System.SYSTEM_PROFILES_ENABLED, 1) == 1);
+ }
+
+ void setBar(PanelBar bar) {
+ mBar = bar;
+ }
+
+ void addQuickSettings(LayoutInflater inflater){
+ // Load the user configured tiles
+ loadTiles();
+
+ // Now add the actual tiles from the loaded list
+ for (Integer entry: mQuickSettings) {
+ QuickSettingsTile qs = null;
+ switch (entry) {
+ case WIFI_TILE:
+ qs = new WiFiTile(mContext, inflater, mContainerView, this);
+ break;
+ case MOBILE_NETWORK_TILE:
+ qs = new MobileNetworkTile(mContext, inflater, mContainerView, this);
+ break;
+ case AIRPLANE_MODE_TILE:
+ qs = new AirplaneModeTile(mContext, inflater, mContainerView, this);
+ break;
+ case BLUETOOTH_TILE:
+ qs = new BluetoothTile(mContext, inflater, mContainerView, this);
+ break;
+ case RINGER_TILE:
+ qs = new RingerModeTile(mContext, inflater, mContainerView, this);
+ break;
+ case SLEEP_TILE:
+ qs = new SleepScreenTile(mContext, inflater, mContainerView, this);
+ break;
+ case TOGGLE_LOCKSCREEN_TILE:
+ qs = new ToggleLockscreenTile(mContext, inflater, mContainerView, this);
+ break;
+ case GPS_TILE:
+ qs = new GPSTile(mContext, inflater, mContainerView, this);
+ break;
+ case AUTO_ROTATION_TILE:
+ qs = new AutoRotateTile(mContext, inflater, mContainerView, this, mHandler);
+ break;
+ case BRIGHTNESS_TILE:
+ qs = new BrightnessTile(mContext, inflater, mContainerView, this, mHandler);
+ break;
+ case MOBILE_NETWORK_TYPE_TILE:
+ qs = new MobileNetworkTypeTile(mContext, inflater, mContainerView, this);
+ break;
+ case ALARM_TILE:
+ qs = new AlarmTile(mContext, inflater, mContainerView, this, mHandler);
+ break;
+ case BUG_REPORT_TILE:
+ qs = new BugReportTile(mContext, inflater, mContainerView, this, mHandler);
+ break;
+ case WIFI_DISPLAY_TILE:
+ qs = new WiFiDisplayTile(mContext, inflater, mContainerView, this);
+ break;
+ case SETTINGS_TILE:
+ qs = new PreferencesTile(mContext, inflater, mContainerView, this);
+ break;
+ case BATTERY_TILE:
+ qs = new BatteryTile(mContext, inflater, mContainerView, this);
+ break;
+ case IME_TILE:
+ IMETile = new InputMethodTile(mContext, inflater, mContainerView, this);
+ qs = IMETile;
+ break;
+ case USER_TILE:
+ qs = new UserTile(mContext, inflater, mContainerView, this);
+ break;
+ case TORCH_TILE:
+ qs = new TorchTile(mContext, inflater, mContainerView, this, mHandler);
+ break;
+ case WIFIAP_TILE:
+ qs = new WifiAPTile(mContext, inflater, mContainerView, this);
+ break;
+ case PROFILE_TILE:
+ qs = new ProfileTile(mContext, inflater, mContainerView, this);
+ break;
+ case SYNC_TILE:
+ qs = new SyncTile(mContext, inflater, mContainerView, this);
+ break;
+ case NFC_TILE:
+ qs = new NfcTile(mContext, inflater, mContainerView, this);
+ break;
+ case SCREENTIMEOUT_TILE:
+ qs = new ScreenTimeoutTile(mContext, inflater, mContainerView, this);
+ break;
+ case USBTETHER_TILE:
+ qs = new UsbTetherTile(mContext, inflater, mContainerView, this);
+ break;
+ case QUIET_HOURS_TILE:
+ qs = new QuietHoursTile(mContext, inflater, mContainerView, this);
+ break;
+ }
+ if (qs != null) {
+ qs.setupQuickSettingsTile();
+ }
+ }
+ }
+
+ public void setService(PhoneStatusBar phoneStatusBar) {
+ mStatusBarService = phoneStatusBar;
+ }
+
+ public void setImeWindowStatus(boolean visible) {
+ if (IMETile != null) {
+ IMETile.toggleVisibility(visible);
+ }
+ }
+
+ public void updateResources() {
+ mContainerView.updateResources();
+ mContainerView.removeAllViews();
+ setupQuickSettings();
+ mContainerView.requestLayout();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 00991c1..72938c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -16,7 +16,8 @@
package com.android.systemui.statusbar.phone;
-import android.app.ActivityManager;
+import java.util.List;
+
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
import android.content.BroadcastReceiver;
@@ -48,8 +49,6 @@ import com.android.systemui.statusbar.policy.CurrentUserTracker;
import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
-import java.util.List;
-
class QuickSettingsModel implements BluetoothStateChangeCallback,
NetworkSignalChangedCallback,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java
index 8f5cde6..65c5ae4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java
@@ -24,10 +24,10 @@ import android.widget.FrameLayout;
/**
*
*/
-class QuickSettingsTileView extends FrameLayout {
+public class QuickSettingsTileView extends FrameLayout {
private int mColSpan;
- private int mRowSpan;
+ private final int mRowSpan;
private int mCellWidth;
public QuickSettingsTileView(Context context, AttributeSet attrs) {
@@ -45,7 +45,7 @@ class QuickSettingsTileView extends FrameLayout {
return mColSpan;
}
- void setContent(int layoutId, LayoutInflater inflater) {
+ public void setContent(int layoutId, LayoutInflater inflater) {
inflater.inflate(layoutId, this);
}
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
index bbb8455..a3a0ea8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
@@ -16,19 +16,14 @@
package com.android.systemui.statusbar.phone;
-import android.animation.LayoutTransition;
import android.content.Context;
-import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import com.android.systemui.R;
-import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
@@ -37,13 +32,13 @@ import com.android.systemui.statusbar.policy.NetworkController;
public class SettingsPanelView extends PanelView {
- private QuickSettings mQS;
+ private QuickSettingsController mQS;
private QuickSettingsContainerView mQSContainer;
Drawable mHandleBar;
int mHandleBarHeight;
View mHandleView;
-
+
public SettingsPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -60,9 +55,10 @@ public class SettingsPanelView extends PanelView {
mHandleView = findViewById(R.id.handle);
setContentDescription(resources.getString(R.string.accessibility_desc_quick_settings));
+
}
-
- public void setQuickSettings(QuickSettings qs) {
+
+ public void setQuickSettings(QuickSettingsController qs) {
mQS = qs;
}
@@ -81,24 +77,6 @@ public class SettingsPanelView extends PanelView {
}
}
- public void setup(NetworkController networkController, BluetoothController bluetoothController,
- BatteryController batteryController, LocationController locationController) {
- if (mQS != null) {
- mQS.setup(networkController, bluetoothController, batteryController,
- locationController);
- }
- }
-
- void updateResources() {
- if (mQS != null) {
- mQS.updateResources();
- }
- if (mQSContainer != null) {
- mQSContainer.updateResources();
- }
- requestLayout();
- }
-
@Override
public void fling(float vel, boolean always) {
GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
@@ -136,4 +114,5 @@ public class SettingsPanelView extends PanelView {
mHandleBar.draw(canvas);
canvas.translate(0, -off);
}
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index f526f0c..76f3964 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -66,6 +66,13 @@ public class StatusBarWindowView extends FrameLayout
}
@Override
+ public void dispatchWindowFocusChanged(boolean hasFocus) {
+ this.setFocusableInTouchMode(hasFocus);
+ this.requestFocus();
+ super.dispatchWindowFocusChanged(hasFocus);
+ }
+
+ @Override
public boolean dispatchKeyEvent(KeyEvent event) {
boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
switch (event.getKeyCode()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 716341f..95fede4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -18,13 +18,16 @@ package com.android.systemui.statusbar.policy;
import java.util.ArrayList;
-import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
import android.os.BatteryManager;
-import android.util.Slog;
+import android.os.Handler;
+import android.provider.Settings;
+import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -37,6 +40,45 @@ public class BatteryController extends BroadcastReceiver {
private ArrayList<ImageView> mIconViews = new ArrayList<ImageView>();
private ArrayList<TextView> mLabelViews = new ArrayList<TextView>();
+ public static final int BATTERY_STYLE_NORMAL = 0;
+ public static final int BATTERY_STYLE_PERCENT = 1;
+ /***
+ * BATTERY_STYLE_CIRCLE* cannot be handled in this controller, since we cannot get views from
+ * statusbar here. Yet it is listed for completion and not to confuse at future updates
+ * See CircleBattery.java for more info
+ *
+ * set to public to be reused by CircleBattery
+ */
+ public static final int BATTERY_STYLE_CIRCLE = 2;
+ public static final int BATTERY_STYLE_CIRCLE_PERCENT = 3;
+ public static final int BATTERY_STYLE_GONE = 4;
+
+
+ private static final int BATTERY_TEXT_STYLE_NORMAL = R.string.status_bar_settings_battery_meter_format;
+ private static final int BATTERY_TEXT_STYLE_MIN = R.string.status_bar_settings_battery_meter_min_format;
+
+ private boolean mBatteryPlugged = false;
+ private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ private int mBatteryStyle;
+
+ Handler mHandler;
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_BATTERY), false, this);
+ }
+
+ @Override public void onChange(boolean selfChange) {
+ updateSettings();
+ }
+ }
+
private ArrayList<BatteryStateChangeCallback> mChangeCallbacks =
new ArrayList<BatteryStateChangeCallback>();
@@ -46,10 +88,15 @@ public class BatteryController extends BroadcastReceiver {
public BatteryController(Context context) {
mContext = context;
+ mHandler = new Handler();
+
+ SettingsObserver settingsObserver = new SettingsObserver(mHandler);
+ settingsObserver.observe();
+ updateSettings();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
- context.registerReceiver(this, filter);
+ mContext.registerReceiver(this, filter);
}
public void addIconView(ImageView v) {
@@ -64,42 +111,120 @@ public class BatteryController extends BroadcastReceiver {
mChangeCallbacks.add(cb);
}
+ // Allow override battery icons
+ public int getIconStyleUnknown() {
+ return R.drawable.stat_sys_battery;
+ }
+ public int getIconStyleNormal() {
+ return R.drawable.stat_sys_battery;
+ }
+ public int getIconStyleCharge() {
+ return R.drawable.stat_sys_battery_charge;
+ }
+ public int getIconStyleNormalMin() {
+ return R.drawable.stat_sys_battery_min;
+ }
+ public int getIconStyleChargeMin() {
+ return R.drawable.stat_sys_battery_charge_min;
+ }
+
+ protected int getBatteryStyle() {
+ return mBatteryStyle;
+ }
+
+ protected int getBatteryStatus() {
+ return mBatteryStatus;
+ }
+
+ protected boolean isBatteryPlugged() {
+ return mBatteryPlugged;
+ }
+
+ protected boolean isBatteryPresent() {
+ // the battery widget always is shown.
+ return true;
+ }
+
+ private boolean isBatteryStatusUnknown() {
+ return getBatteryStatus() == BatteryManager.BATTERY_STATUS_UNKNOWN;
+ }
+
+ private boolean isBatteryStatusCharging() {
+ return getBatteryStatus() == BatteryManager.BATTERY_STATUS_CHARGING;
+ }
+
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
- final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
- BatteryManager.BATTERY_STATUS_UNKNOWN);
-
- boolean plugged = false;
- switch (status) {
- case BatteryManager.BATTERY_STATUS_CHARGING:
- case BatteryManager.BATTERY_STATUS_FULL:
- plugged = true;
- break;
- }
+ mBatteryPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
+ mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ updateViews(level);
+ updateBattery();
+ }
+ }
- final int icon = plugged ? R.drawable.stat_sys_battery_charge
- : R.drawable.stat_sys_battery;
+ protected void updateViews(int level) {
+ int N = mIconViews.size();
+ for (int i=0; i<N; i++) {
+ ImageView v = mIconViews.get(i);
+ v.setImageLevel(level);
+ v.setContentDescription(mContext.getString(R.string.accessibility_battery_level,
+ level));
+ }
+ N = mLabelViews.size();
+ for (int i=0; i<N; i++) {
+ TextView v = mLabelViews.get(i);
+ v.setText(mContext.getString(BATTERY_TEXT_STYLE_MIN,
+ level));
+ }
- int N = mIconViews.size();
- for (int i=0; i<N; i++) {
- ImageView v = mIconViews.get(i);
- v.setImageResource(icon);
- v.setImageLevel(level);
- v.setContentDescription(mContext.getString(R.string.accessibility_battery_level,
- level));
- }
- N = mLabelViews.size();
- for (int i=0; i<N; i++) {
- TextView v = mLabelViews.get(i);
- v.setText(mContext.getString(R.string.status_bar_settings_battery_meter_format,
- level));
- }
+ for (BatteryStateChangeCallback cb : mChangeCallbacks) {
+ cb.onBatteryLevelChanged(level, isBatteryStatusCharging());
+ }
+ }
- for (BatteryStateChangeCallback cb : mChangeCallbacks) {
- cb.onBatteryLevelChanged(level, plugged);
+ protected void updateBattery() {
+ int mIcon = View.GONE;
+ int mText = View.GONE;
+ int mIconStyle = getIconStyleNormal();
+
+ if (isBatteryPresent()) {
+ if ( isBatteryStatusUnknown() &&
+ (mBatteryStyle == BATTERY_STYLE_NORMAL || mBatteryStyle == BATTERY_STYLE_PERCENT)) {
+ // Unknown status doesn't relies on any style
+ mIcon = (View.VISIBLE);
+ mIconStyle = getIconStyleUnknown();
+ } else if (mBatteryStyle == BATTERY_STYLE_NORMAL) {
+ mIcon = (View.VISIBLE);
+ mIconStyle = isBatteryStatusCharging() ?
+ getIconStyleCharge() : getIconStyleNormal();
+ } else if (mBatteryStyle == BATTERY_STYLE_PERCENT) {
+ mIcon = (View.VISIBLE);
+ mText = (View.VISIBLE);
+ mIconStyle = isBatteryStatusCharging() ?
+ getIconStyleChargeMin() : getIconStyleNormalMin();
}
}
+
+ int N = mIconViews.size();
+ for (int i=0; i<N; i++) {
+ ImageView v = mIconViews.get(i);
+ v.setVisibility(mIcon);
+ v.setImageResource(mIconStyle);
+ }
+ N = mLabelViews.size();
+ for (int i=0; i<N; i++) {
+ TextView v = mLabelViews.get(i);
+ v.setVisibility(mText);
+ }
+ }
+
+ private void updateSettings() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mBatteryStyle = (Settings.System.getInt(resolver,
+ Settings.System.STATUS_BAR_BATTERY, BATTERY_STYLE_NORMAL));
+ updateBattery();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java
new file mode 100644
index 0000000..01178c0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2012 Sven Dawitz for the CyanogenMod 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.systemui.statusbar.policy;
+
+import android.view.ViewGroup.LayoutParams;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.android.internal.R;
+
+/***
+ * Note about CircleBattery Implementation:
+ *
+ * Unfortunately, we cannot use BatteryController here,
+ * since communication between controller and this view is not possible without
+ * huge changes. As a result, this Class is doing everything by itself,
+ * monitoring battery level and battery settings.
+ */
+
+public class CircleBattery extends ImageView {
+ private Handler mHandler;
+ private Context mContext;
+ private BatteryReceiver mBatteryReceiver = null;
+
+ // state variables
+ private boolean mAttached; // whether or not attached to a window
+ private boolean mActivated; // whether or not activated due to system settings
+ private boolean mPercentage; // whether or not to show percentage number
+ private boolean mBatteryPlugged;// whether or not battery is currently plugged
+ private int mBatteryStatus; // current battery status
+ private int mLevel; // current battery level
+ private int mAnimOffset; // current level of charging animation
+ private boolean mIsAnimating; // stores charge-animation status to reliably remove callbacks
+
+ private int mCircleSize; // draw size of circle. read rather complicated from
+ // another status bar icon, so it fits the icon size
+ // no matter the dps and resolution
+ private RectF mRectLeft; // contains the precalculated rect used in drawArc(), derived from mCircleSize
+ private Float mTextLeftX; // precalculated x position for drawText() to appear centered
+ private Float mTextY; // precalculated y position for drawText() to appear vertical-centered
+
+ // quiet a lot of paint variables. helps to move cpu-usage from actual drawing to initialization
+ private Paint mPaintFont;
+ private Paint mPaintGray;
+ private Paint mPaintSystem;
+ private Paint mPaintRed;
+
+ // runnable to invalidate view via mHandler.postDelayed() call
+ private final Runnable mInvalidate = new Runnable() {
+ public void run() {
+ if(mActivated && mAttached) {
+ invalidate();
+ }
+ }
+ };
+
+ // observes changes in system battery settings and enables/disables view accordingly
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ public void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_BATTERY), false, this);
+ onChange(true);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ int batteryStyle = (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_BATTERY, 0));
+
+ mActivated = (batteryStyle == BatteryController.BATTERY_STYLE_CIRCLE || batteryStyle == BatteryController.BATTERY_STYLE_CIRCLE_PERCENT);
+ mPercentage = (batteryStyle == BatteryController.BATTERY_STYLE_CIRCLE_PERCENT);
+
+ setVisibility(mActivated && isBatteryPresent() ? View.VISIBLE : View.GONE);
+ if (mBatteryReceiver != null) {
+ mBatteryReceiver.updateRegistration();
+ }
+
+ if (mActivated && mAttached) {
+ invalidate();
+ }
+ }
+ }
+
+ // keeps track of current battery level and charger-plugged-state
+ class BatteryReceiver extends BroadcastReceiver {
+ private boolean mIsRegistered = false;
+
+ public BatteryReceiver(Context context) {
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ onBatteryStatusChange(intent);
+
+ int visibility = mActivated && isBatteryPresent() ? View.VISIBLE : View.GONE;
+ if (getVisibility() != visibility) {
+ setVisibility(visibility);
+ }
+
+ if (mActivated && mAttached) {
+ LayoutParams l = getLayoutParams();
+ l.width = mCircleSize + getPaddingLeft();
+ setLayoutParams(l);
+
+ invalidate();
+ }
+ }
+ }
+
+ private void registerSelf() {
+ if (!mIsRegistered) {
+ mIsRegistered = true;
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ mContext.registerReceiver(mBatteryReceiver, filter);
+ }
+ }
+
+ private void unregisterSelf() {
+ if (mIsRegistered) {
+ mIsRegistered = false;
+ mContext.unregisterReceiver(this);
+ }
+ }
+
+ private void updateRegistration() {
+ if (mActivated && mAttached) {
+ registerSelf();
+ } else {
+ unregisterSelf();
+ }
+ }
+ }
+
+ /***
+ * Start of CircleBattery implementation
+ */
+ public CircleBattery(Context context) {
+ this(context, null);
+ }
+
+ public CircleBattery(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public CircleBattery(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mContext = context;
+ mHandler = new Handler();
+
+ SettingsObserver settingsObserver = new SettingsObserver(mHandler);
+ settingsObserver.observe();
+ mBatteryReceiver = new BatteryReceiver(mContext);
+
+ // initialize and setup all paint variables
+ // stroke width is later set in initSizeBasedStuff()
+ Resources res = getResources();
+
+ mPaintFont = new Paint();
+ mPaintFont.setAntiAlias(true);
+ mPaintFont.setDither(true);
+ mPaintFont.setStyle(Paint.Style.STROKE);
+
+ mPaintGray = new Paint(mPaintFont);
+ mPaintSystem = new Paint(mPaintFont);
+ mPaintRed = new Paint(mPaintFont);
+
+ mPaintGray.setStrokeCap(Paint.Cap.BUTT);
+ mPaintSystem.setStrokeCap(Paint.Cap.BUTT);
+ mPaintRed.setStrokeCap(Paint.Cap.BUTT);
+
+ mPaintFont.setColor(res.getColor(R.color.holo_blue_dark));
+ mPaintSystem.setColor(res.getColor(R.color.holo_blue_dark));
+ // could not find the darker definition anywhere in resources
+ // do not want to use static 0x404040 color value. would break theming.
+ mPaintGray.setColor(res.getColor(R.color.darker_gray));
+ mPaintRed.setColor(res.getColor(R.color.holo_red_light));
+
+ // font needs some extra settings
+ mPaintFont.setTextAlign(Align.CENTER);
+ mPaintFont.setFakeBoldText(true);
+ }
+
+ protected int getLevel() {
+ return mLevel;
+ }
+
+ protected int getBatteryStatus() {
+ return mBatteryStatus;
+ }
+
+ protected boolean isBatteryPlugged() {
+ return mBatteryPlugged;
+ }
+
+ protected boolean isBatteryPresent() {
+ // the battery widget always is shown.
+ return true;
+ }
+
+ private boolean isBatteryStatusUnknown() {
+ return getBatteryStatus() == BatteryManager.BATTERY_STATUS_UNKNOWN;
+ }
+
+ private boolean isBatteryStatusCharging() {
+ return getBatteryStatus() == BatteryManager.BATTERY_STATUS_CHARGING;
+ }
+
+ protected void onBatteryStatusChange(Intent intent) {
+ mLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ mBatteryPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
+ mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!mAttached) {
+ mAttached = true;
+ mBatteryReceiver.updateRegistration();
+ mHandler.postDelayed(mInvalidate, 250);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mAttached) {
+ mAttached = false;
+ mBatteryReceiver.updateRegistration();
+ mRectLeft = null; // makes sure, size based variables get
+ // recalculated on next attach
+ mCircleSize = 0; // makes sure, mCircleSize is reread from icons on
+ // next attach
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (mCircleSize == 0) {
+ initSizeMeasureIconHeight();
+ }
+
+ setMeasuredDimension(mCircleSize + getPaddingLeft(), mCircleSize);
+ }
+
+ protected void drawCircle(Canvas canvas, int level, int animOffset, float textX, RectF drawRect) {
+ Paint usePaint = mPaintSystem;
+ int internalLevel = level;
+ boolean unknownStatus = isBatteryStatusUnknown();
+ // turn red at 14% - same level android battery warning appears
+ if (unknownStatus) {
+ usePaint = mPaintGray;
+ internalLevel = 100; // Draw all the circle;
+ } else if (internalLevel <= 14) {
+ usePaint = mPaintRed;
+ }
+
+ // pad circle percentage to 100% once it reaches 97%
+ // for one, the circle looks odd with a too small gap,
+ // for another, some phones never reach 100% due to hardware design
+ int padLevel = internalLevel;
+ if (padLevel >= 97) {
+ padLevel = 100;
+ }
+
+ // draw thin gray ring first
+ canvas.drawArc(drawRect, 270, 360, false, mPaintGray);
+ // draw colored arc representing charge level
+ canvas.drawArc(drawRect, 270 + animOffset, 3.6f * padLevel, false, usePaint);
+ // if chosen by options, draw percentage text in the middle
+ // always skip percentage when 100, so layout doesnt break
+ if (unknownStatus) {
+ mPaintFont.setColor(usePaint.getColor());
+ canvas.drawText("?", textX, mTextY, mPaintFont);
+ } else if (internalLevel < 100 && mPercentage) {
+ mPaintFont.setColor(usePaint.getColor());
+ canvas.drawText(Integer.toString(internalLevel), textX, mTextY, mPaintFont);
+ }
+
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mRectLeft == null) {
+ initSizeBasedStuff();
+ }
+
+ updateChargeAnim();
+
+ drawCircle(canvas,
+ getLevel(),
+ (isBatteryStatusCharging() ? mAnimOffset : 0), mTextLeftX, mRectLeft);
+ }
+
+ /***
+ * updates the animation counter
+ * cares for timed callbacks to continue animation cycles
+ * uses mInvalidate for delayed invalidate() callbacks
+ */
+ private void updateChargeAnim() {
+ if (!isBatteryStatusCharging() || getLevel() >= 97) {
+ if (mIsAnimating) {
+ mIsAnimating = false;
+ mAnimOffset = 0;
+ mHandler.removeCallbacks(mInvalidate);
+ }
+ return;
+ }
+
+ mIsAnimating = true;
+
+ if (mAnimOffset > 360) {
+ mAnimOffset = 0;
+ } else {
+ mAnimOffset += 3;
+ }
+
+ mHandler.removeCallbacks(mInvalidate);
+ mHandler.postDelayed(mInvalidate, 50);
+ }
+
+ /***
+ * initializes all size dependent variables
+ * sets stroke width and text size of all involved paints
+ * YES! i think the method name is appropriate
+ */
+ private void initSizeBasedStuff() {
+ if (mCircleSize == 0) {
+ initSizeMeasureIconHeight();
+ }
+
+ mPaintFont.setTextSize(mCircleSize / 2f);
+
+ float strokeWidth = mCircleSize / 6.5f;
+ mPaintRed.setStrokeWidth(strokeWidth);
+ mPaintSystem.setStrokeWidth(strokeWidth);
+ mPaintGray.setStrokeWidth(strokeWidth / 3.5f);
+
+ // calculate rectangle for drawArc calls
+ int pLeft = getPaddingLeft();
+ mRectLeft = new RectF(pLeft + strokeWidth / 2.0f, 0 + strokeWidth / 2.0f, mCircleSize
+ - strokeWidth / 2.0f + pLeft, mCircleSize - strokeWidth / 2.0f);
+
+ // calculate Y position for text
+ Rect bounds = new Rect();
+ mPaintFont.getTextBounds("99", 0, "99".length(), bounds);
+ mTextLeftX = mCircleSize / 2.0f + getPaddingLeft();
+ // the +1 at end of formular balances out rounding issues. works out on all resolutions
+ mTextY = mCircleSize / 2.0f + (bounds.bottom - bounds.top) / 2.0f - strokeWidth / 2.0f + 1;
+
+ // force new measurement for wrap-content xml tag
+ onMeasure(0, 0);
+ }
+
+ /***
+ * we need to measure the size of the circle battery by checking another
+ * resource. unfortunately, those resources have transparent/empty borders
+ * so we have to count the used pixel manually and deduct the size from
+ * it. quiet complicated, but the only way to fit properly into the
+ * statusbar for all resolutions
+ */
+ private void initSizeMeasureIconHeight() {
+ final Bitmap measure = BitmapFactory.decodeResource(getResources(),
+ com.android.systemui.R.drawable.stat_sys_wifi_signal_4_fully);
+ final int x = measure.getWidth() / 2;
+
+ mCircleSize = 0;
+ for (int y = 0; y < measure.getHeight(); y++) {
+ int alpha = Color.alpha(measure.getPixel(x, y));
+ if (alpha > 5) {
+ mCircleSize++;
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleDockBattery.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleDockBattery.java
new file mode 100644
index 0000000..dba10b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleDockBattery.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod 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.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.BatteryManager;
+import android.util.AttributeSet;
+
+import com.android.systemui.R;
+
+/***
+ * Implementation of the CircleBattery widget adapted for listening dock battery status
+ * @see CircleBattery
+ */
+
+public class CircleDockBattery extends CircleBattery {
+
+ private int mLevel;
+ private int mDockBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ private boolean mBatteryPlugged = false;
+ private boolean mBatteryPresent = false;
+
+ private final Context mContext;
+ private boolean mAttached;
+
+ private Bitmap mDockIcon;
+ private Paint mPaint;
+
+ /***
+ * Start of CircleDockBattery implementation
+ */
+ public CircleDockBattery(Context context) {
+ this(context, null);
+ }
+
+ public CircleDockBattery(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public CircleDockBattery(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mContext = context;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ if (!mAttached) {
+ // Load the resource to display as dock icon
+ mDockIcon = BitmapFactory.decodeResource(
+ mContext.getResources(),
+ R.drawable.stat_sys_kb_battery_icon);
+
+ // Use an anti-alias while drawing the dock icon
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setFilterBitmap(true);
+ mPaint.setDither(true);
+
+ mAttached = true;
+ }
+ super.onAttachedToWindow();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mDockIcon != null) {
+ mDockIcon.recycle();
+ }
+ mDockIcon = null;
+ mPaint = null;
+ mAttached = false;
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ protected int getLevel() {
+ return mLevel;
+ }
+
+ @Override
+ protected int getBatteryStatus() {
+ return mDockBatteryStatus;
+ }
+
+ @Override
+ protected boolean isBatteryPlugged() {
+ return mBatteryPlugged;
+ }
+
+ @Override
+ protected boolean isBatteryPresent() {
+ return mBatteryPresent;
+ }
+
+ @Override
+ protected void onBatteryStatusChange(Intent intent) {
+ mLevel = intent.getIntExtra(BatteryManager.EXTRA_DOCK_LEVEL, 0);
+ mDockBatteryStatus = intent.getIntExtra(
+ BatteryManager.EXTRA_DOCK_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ mBatteryPlugged = intent.getIntExtra(BatteryManager.EXTRA_DOCK_PLUGGED, 0) != 0;
+ mBatteryPresent = intent.getBooleanExtra(BatteryManager.EXTRA_DOCK_PRESENT, false);
+ }
+
+ @Override
+ protected void drawCircle(Canvas canvas, int level, int animOffset, float textX, RectF drawRect) {
+ super.drawCircle(canvas, level, animOffset, textX, drawRect);
+ if (mDockIcon != null) {
+ Rect src = new Rect(0, 0, mDockIcon.getWidth(), mDockIcon.getHeight());
+ float h = getHeight() - getPaddingBottom();
+ float w = getWidth() - getPaddingLeft() - getPaddingRight();
+ RectF dst = new RectF(
+ getPaddingLeft() + (w / 2) - (src.width() / 2),
+ h - src.height(),
+ getWidth() - getPaddingRight() - (w / 2) + (src.width() / 2),
+ h);
+ canvas.drawBitmap(mDockIcon, src, dst, mPaint);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index e41de47..2b7360c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -16,39 +16,40 @@
package com.android.systemui.statusbar.policy;
+import android.app.ActivityManagerNative;
+import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.AlarmClock;
+import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
import android.text.style.CharacterStyle;
-import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
-import android.text.style.RelativeSizeSpan;
-import android.text.style.StyleSpan;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
import android.widget.TextView;
+import com.android.internal.R;
+
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
-import com.android.internal.R;
-
/**
* Digital clock for the status bar.
*/
-public class Clock extends TextView {
+public class Clock extends TextView implements OnClickListener, OnLongClickListener {
private boolean mAttached;
private Calendar mCalendar;
private String mClockFormatString;
@@ -59,7 +60,28 @@ public class Clock extends TextView {
private static final int AM_PM_STYLE_SMALL = 1;
private static final int AM_PM_STYLE_GONE = 2;
- private static final int AM_PM_STYLE = AM_PM_STYLE_GONE;
+ private int mAmPmStyle = AM_PM_STYLE_GONE;
+ private boolean mShowClock;
+
+ Handler mHandler;
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_AM_PM), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_CLOCK), false, this);
+ }
+
+ @Override public void onChange(boolean selfChange) {
+ updateSettings();
+ }
+ }
public Clock(Context context) {
this(context, null);
@@ -71,6 +93,15 @@ public class Clock extends TextView {
public Clock(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+
+ mHandler = new Handler();
+ SettingsObserver settingsObserver = new SettingsObserver(mHandler);
+ settingsObserver.observe();
+ if(isClickable()){
+ setOnClickListener(this);
+ setOnLongClickListener(this);
+ }
+ updateSettings();
}
@Override
@@ -157,7 +188,7 @@ public class Clock extends TextView {
* add dummy characters around it to let us find it again after
* formatting and change its size.
*/
- if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) {
+ if (mAmPmStyle != AM_PM_STYLE_NORMAL) {
int a = -1;
boolean quoted = false;
for (int i = 0; i < format.length(); i++) {
@@ -189,15 +220,15 @@ public class Clock extends TextView {
}
String result = sdf.format(mCalendar.getTime());
- if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) {
+ if (mAmPmStyle != AM_PM_STYLE_NORMAL) {
int magic1 = result.indexOf(MAGIC1);
int magic2 = result.indexOf(MAGIC2);
if (magic1 >= 0 && magic2 > magic1) {
SpannableStringBuilder formatted = new SpannableStringBuilder(result);
- if (AM_PM_STYLE == AM_PM_STYLE_GONE) {
+ if (mAmPmStyle == AM_PM_STYLE_GONE) {
formatted.delete(magic1, magic2+1);
} else {
- if (AM_PM_STYLE == AM_PM_STYLE_SMALL) {
+ if (mAmPmStyle == AM_PM_STYLE_SMALL) {
CharacterStyle style = new RelativeSizeSpan(0.7f);
formatted.setSpan(style, magic1, magic2,
Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
@@ -208,9 +239,70 @@ public class Clock extends TextView {
return formatted;
}
}
-
+
return result;
}
+
+ private void updateSettings(){
+ ContentResolver resolver = mContext.getContentResolver();
+
+ int amPmStyle = (Settings.System.getInt(resolver,
+ Settings.System.STATUS_BAR_AM_PM, 2));
+
+ if (mAmPmStyle != amPmStyle) {
+ mAmPmStyle = amPmStyle;
+ mClockFormatString = "";
+
+ if (mAttached) {
+ updateClock();
+ }
+ }
+
+ mShowClock = (Settings.System.getInt(resolver,
+ Settings.System.STATUS_BAR_CLOCK, 1) == 1);
+
+ if(mShowClock)
+ setVisibility(View.VISIBLE);
+ else
+ setVisibility(View.GONE);
+ }
+
+ private void collapseStartActivity(Intent what) {
+ // collapse status bar
+ StatusBarManager statusBarManager = (StatusBarManager) getContext().getSystemService(
+ Context.STATUS_BAR_SERVICE);
+ statusBarManager.collapsePanels();
+
+ // dismiss keyguard in case it was active and no passcode set
+ try {
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (Exception ex) {
+ // no action needed here
+ }
+
+ // start activity
+ what.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(what);
+ }
+
+ @Override
+ public void onClick(View v) {
+ // start com.android.deskclock/.DeskClock
+ ComponentName clock = new ComponentName("com.android.deskclock",
+ "com.android.deskclock.DeskClock");
+ Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
+ .setComponent(clock);
+ collapseStartActivity(intent);
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM);
+ collapseStartActivity(intent);
+
+ // consume event
+ return true;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index 1d6b3d1..26b1eb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -16,23 +16,34 @@
package com.android.systemui.statusbar.policy;
+import android.app.ActivityManagerNative;
+import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.graphics.Canvas;
+import android.net.Uri;
+import android.provider.CalendarContract;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
import android.view.ViewParent;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.systemui.R;
import java.util.Date;
-public class DateView extends TextView {
+public class DateView extends TextView implements OnClickListener, OnLongClickListener {
private static final String TAG = "DateView";
+ private RelativeLayout mParent;
+
private boolean mAttachedToWindow;
private boolean mWindowVisible;
private boolean mUpdating;
@@ -51,6 +62,8 @@ public class DateView extends TextView {
public DateView(Context context, AttributeSet attrs) {
super(context, attrs);
+ setOnClickListener(this);
+ setOnLongClickListener(this);
}
@Override
@@ -59,15 +72,31 @@ public class DateView extends TextView {
mAttachedToWindow = true;
setUpdates();
}
-
+
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAttachedToWindow = false;
+ if (mParent != null) {
+ mParent.setOnClickListener(null);
+ mParent.setOnLongClickListener(null);
+ mParent = null;
+ }
setUpdates();
}
@Override
+ protected void onDraw(Canvas canvas) {
+ if (mParent == null) {
+ mParent = (RelativeLayout) getParent();
+ mParent.setOnClickListener(this);
+ mParent.setOnLongClickListener(this);
+ }
+
+ super.onDraw(canvas);
+ }
+
+ @Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
mWindowVisible = visibility == VISIBLE;
@@ -87,7 +116,7 @@ public class DateView extends TextView {
}
protected void updateClock() {
- final String dateFormat = getContext().getString(R.string.abbrev_wday_month_day_no_year);
+ final String dateFormat = getContext().getString(R.string.full_wday_month_day_no_year_split);
setText(DateFormat.format(dateFormat, new Date()));
}
@@ -123,4 +152,44 @@ public class DateView extends TextView {
}
}
}
+
+ private void collapseStartActivity(Intent what) {
+ // collapse status bar
+ StatusBarManager statusBarManager = (StatusBarManager) getContext().getSystemService(
+ Context.STATUS_BAR_SERVICE);
+ statusBarManager.collapsePanels();
+
+ // dismiss keyguard in case it was active and no passcode set
+ try {
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (Exception ex) {
+ // no action needed here
+ }
+
+ // start activity
+ what.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(what);
+ }
+
+ @Override
+ public void onClick(View v) {
+ long nowMillis = System.currentTimeMillis();
+
+ Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
+ builder.appendPath("time");
+ ContentUris.appendId(builder, nowMillis);
+ Intent intent = new Intent(Intent.ACTION_VIEW)
+ .setData(builder.build());
+ collapseStartActivity(intent);
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ Intent intent = new Intent("android.settings.DATE_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ collapseStartActivity(intent);
+
+ // consume event
+ return true;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java
new file mode 100644
index 0000000..fae6572
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.BatteryManager;
+
+import com.android.systemui.R;
+
+public class DockBatteryController extends BatteryController {
+ private static final String TAG = "StatusBar.DockBatteryController";
+
+ private int mDockBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ private boolean mBatteryPlugged = false;
+ private boolean mBatteryPresent = false;
+
+ public DockBatteryController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ final int level = intent.getIntExtra(BatteryManager.EXTRA_DOCK_LEVEL, 0);
+ mDockBatteryStatus = intent.getIntExtra(
+ BatteryManager.EXTRA_DOCK_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ mBatteryPlugged = intent.getIntExtra(BatteryManager.EXTRA_DOCK_PLUGGED, 0) != 0;
+ mBatteryPresent = intent.getBooleanExtra(BatteryManager.EXTRA_DOCK_PRESENT, false);
+ updateViews(level);
+ updateBattery();
+ }
+ }
+
+ @Override
+ public int getIconStyleUnknown() {
+ return R.drawable.stat_sys_kb_battery_unknown;
+ }
+ @Override
+ public int getIconStyleNormal() {
+ return R.drawable.stat_sys_kb_battery;
+ }
+ @Override
+ public int getIconStyleCharge() {
+ return R.drawable.stat_sys_kb_battery_charge;
+ }
+ @Override
+ public int getIconStyleNormalMin() {
+ return R.drawable.stat_sys_kb_battery_min;
+ }
+ @Override
+ public int getIconStyleChargeMin() {
+ return R.drawable.stat_sys_kb_battery_charge_min;
+ }
+
+ @Override
+ protected int getBatteryStatus() {
+ return mDockBatteryStatus;
+ }
+
+ @Override
+ protected boolean isBatteryPlugged() {
+ return mBatteryPlugged;
+ }
+
+ @Override
+ protected boolean isBatteryPresent() {
+ return mBatteryPresent;
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 82d6a99..a9a1560 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -19,18 +19,15 @@ package com.android.systemui.statusbar.policy;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.hardware.input.InputManager;
-import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.ServiceManager;
import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityEvent;
import android.view.HapticFeedbackConstants;
-import android.view.IWindowManager;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -38,9 +35,14 @@ import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
+import com.android.internal.util.ArrayUtils;
import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.NavbarEditor;
+import com.android.systemui.statusbar.phone.NavbarEditor.ButtonInfo;
+import com.android.systemui.statusbar.phone.NavigationBarView;
public class KeyButtonView extends ImageView {
private static final String TAG = "StatusBar.KeyButtonView";
@@ -171,7 +173,7 @@ public class KeyButtonView extends ImageView {
// also invalidate our immediate parent to help avoid situations where nearby glows
// interfere
- ((View)getParent()).invalidate();
+ ((View)getParent().getParent()).invalidate();
}
}
@@ -207,7 +209,42 @@ public class KeyButtonView extends ImageView {
super.setPressed(pressed);
}
+ public void setInfo (String itemKey, boolean isVertical) {
+ ButtonInfo item = NavbarEditor.buttonMap.get(itemKey);
+ setTag(itemKey);
+ final Resources res = getResources();
+ setContentDescription(res.getString(item.contentDescription));
+ mCode = item.keyCode;
+ boolean isSmallButton = ArrayUtils.contains(NavbarEditor.smallButtonIds, getId());
+ Drawable keyD;
+ if (isSmallButton) {
+ keyD = res.getDrawable(item.sideResource);
+ } else if (!isVertical) {
+ keyD = res.getDrawable(item.portResource);
+ } else {
+ keyD = res.getDrawable(item.landResource);
+ }
+ //Reason for setImageDrawable vs setImageResource is because setImageResource calls relayout() w/o
+ //any checks. setImageDrawable performs size checks and only calls relayout if necessary. We rely on this
+ //because otherwise the setX/setY attributes which are post layout cause it to mess up the layout.
+ setImageDrawable(keyD);
+ if (itemKey.equals(NavbarEditor.NAVBAR_EMPTY)) {
+ if (isSmallButton) {
+ setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.INVISIBLE);
+ } else {
+ setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.GONE);
+ }
+ } else if (itemKey.equals(NavbarEditor.NAVBAR_CONDITIONAL_MENU)) {
+ setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.INVISIBLE);
+ } else if (itemKey.equals(NavbarEditor.NAVBAR_HOME)) {
+ mSupportsLongpress = false;
+ }
+ }
+
public boolean onTouchEvent(MotionEvent ev) {
+ if (NavigationBarView.getEditMode()) {
+ return false;
+ }
final int action = ev.getAction();
int x, y;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index bbb90c8..19d9f8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -613,7 +613,6 @@ public class NetworkController extends BroadcastReceiver {
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
- case TelephonyManager.NETWORK_TYPE_HSPAP:
if (mHspaDataDistinguishable) {
mDataIconList = TelephonyIcons.DATA_H[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_data_connected_h;
@@ -628,6 +627,12 @@ public class NetworkController extends BroadcastReceiver {
R.string.accessibility_data_connection_3g);
}
break;
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ mDataIconList = TelephonyIcons.DATA_HP[mInetCondition];
+ mDataTypeIconId = R.drawable.stat_sys_data_connected_hp;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_HP);
+ break;
case TelephonyManager.NETWORK_TYPE_CDMA:
if (!mShowAtLeastThreeGees) {
// display 1xRTT for IS95A/B
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 3b953a0..db2be1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -111,6 +111,18 @@ class TelephonyIcons {
R.drawable.stat_sys_data_fully_connected_h }
};
+ //HPSPA+
+ static final int[][] DATA_HP = {
+ { R.drawable.stat_sys_data_connected_hp,
+ R.drawable.stat_sys_data_connected_hp,
+ R.drawable.stat_sys_data_connected_hp,
+ R.drawable.stat_sys_data_connected_hp },
+ { R.drawable.stat_sys_data_fully_connected_hp,
+ R.drawable.stat_sys_data_fully_connected_hp,
+ R.drawable.stat_sys_data_fully_connected_hp,
+ R.drawable.stat_sys_data_fully_connected_hp }
+ };
+
//CDMA
// Use 3G icons for EVDO data and 1x icons for 1XRTT data
static final int[][] DATA_1X = {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AirplaneButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AirplaneButton.java
new file mode 100644
index 0000000..8d005c4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AirplaneButton.java
@@ -0,0 +1,65 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.provider.Settings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AirplaneButton extends PowerButton {
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON));
+ }
+
+ public AirplaneButton() { mType = BUTTON_AIRPLANE; }
+
+ @Override
+ protected void updateState(Context context) {
+ if (getState(context)) {
+ mIcon = R.drawable.stat_airplane_on;
+ mState = STATE_ENABLED;
+ } else {
+ mIcon = R.drawable.stat_airplane_off;
+ mState = STATE_DISABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ boolean state = getState(context);
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, state ? 0 : 1);
+ // notify change
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ // Reverse state when sending the intent, since we grabbed it before the toggle.
+ intent.putExtra("state", !state);
+ context.sendBroadcast(intent);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.AIRPLANE_MODE_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ private boolean getState(Context context) {
+ return Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON,0) == 1;
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AutoRotateButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AutoRotateButton.java
new file mode 100644
index 0000000..af08d24
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/AutoRotateButton.java
@@ -0,0 +1,60 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Settings;
+
+import com.android.internal.view.RotationPolicy;
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AutoRotateButton extends PowerButton {
+
+ private static final String TAG = "AutoRotateButton";
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION));
+ }
+
+ public AutoRotateButton() { mType = BUTTON_AUTOROTATE; }
+
+ @Override
+ protected void updateState(Context context) {
+ if (getAutoRotation(context)) {
+ mIcon = R.drawable.stat_orientation_on;
+ mState = STATE_ENABLED;
+ } else {
+ mIcon = R.drawable.stat_orientation_off;
+ mState = STATE_DISABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ RotationPolicy.setRotationLock(context, getAutoRotation(context));
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.DISPLAY_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ private boolean getAutoRotation(Context context) {
+ return !RotationPolicy.isRotationLocked(context);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BluetoothButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BluetoothButton.java
new file mode 100644
index 0000000..6b1a2a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BluetoothButton.java
@@ -0,0 +1,132 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+
+public class BluetoothButton extends PowerButton {
+
+ private static final StateTracker sBluetoothState = new BluetoothStateTracker();
+
+ private static final class BluetoothStateTracker extends StateTracker {
+
+ @Override
+ public int getActualState(Context context) {
+ BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mBluetoothAdapter == null) {
+ return STATE_UNKNOWN; // On emulator?
+ }
+ return bluetoothStateToFiveState(mBluetoothAdapter
+ .getState());
+ }
+
+ @Override
+ protected void requestStateChange(Context context,
+ final boolean desiredState) {
+ // Actually request the Bluetooth change and persistent
+ // settings write off the UI thread, as it can take a
+ // user-noticeable amount of time, especially if there's
+ // disk contention.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {
+ BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if(mBluetoothAdapter.isEnabled()) {
+ mBluetoothAdapter.disable();
+ } else {
+ mBluetoothAdapter.enable();
+ }
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActualStateChange(Context context, Intent intent) {
+ if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent
+ .getAction())) {
+ return;
+ }
+ int bluetoothState = intent.getIntExtra(
+ BluetoothAdapter.EXTRA_STATE, -1);
+ setCurrentState(context, bluetoothStateToFiveState(bluetoothState));
+ }
+
+ /**
+ * Converts BluetoothAdapter's state values into our
+ * Wifi/Bluetooth-common state values.
+ */
+ private static int bluetoothStateToFiveState(int bluetoothState) {
+ switch (bluetoothState) {
+ case BluetoothAdapter.STATE_OFF:
+ return STATE_DISABLED;
+ case BluetoothAdapter.STATE_ON:
+ return STATE_ENABLED;
+ case BluetoothAdapter.STATE_TURNING_ON:
+ return STATE_TURNING_ON;
+ case BluetoothAdapter.STATE_TURNING_OFF:
+ return STATE_TURNING_OFF;
+ default:
+ return STATE_UNKNOWN;
+ }
+ }
+ }
+
+ public BluetoothButton() { mType = BUTTON_BLUETOOTH; }
+
+ @Override
+ protected void updateState(Context context) {
+ mState = sBluetoothState.getTriState(context);
+ switch (mState) {
+ case STATE_DISABLED:
+ mIcon = R.drawable.stat_bluetooth_off;
+ break;
+ case STATE_ENABLED:
+ mIcon = R.drawable.stat_bluetooth_on;
+ break;
+ case STATE_INTERMEDIATE:
+ // In the transitional state, the bottom green bar
+ // shows the tri-state (on, off, transitioning), but
+ // the top dark-gray-or-bright-white logo shows the
+ // user's intent. This is much easier to see in
+ // sunlight.
+ if (sBluetoothState.isTurningOn()) {
+ mIcon = R.drawable.stat_bluetooth_on;
+ } else {
+ mIcon = R.drawable.stat_bluetooth_off;
+ }
+ break;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ sBluetoothState.toggleState(context);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.BLUETOOTH_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ sBluetoothState.onActualStateChange(context, intent);
+ }
+
+ @Override
+ protected IntentFilter getBroadcastIntentFilter() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ return filter;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BrightnessButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BrightnessButton.java
new file mode 100644
index 0000000..ff8e3d4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/BrightnessButton.java
@@ -0,0 +1,196 @@
+
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.server.power.PowerManagerService;
+import com.android.systemui.R;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IPowerManager;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BrightnessButton extends PowerButton {
+
+ private static final String TAG = "BrightnessButton";
+
+ /**
+ * Minimum and maximum brightnesses. Don't go to 0 since that makes the
+ * display unusable
+ */
+ private static final int MIN_BACKLIGHT = (PowerManager.BRIGHTNESS_ON/10) + 5;
+ private static final int MAX_BACKLIGHT = PowerManager.BRIGHTNESS_ON;
+
+ // Auto-backlight level
+ private static final int AUTO_BACKLIGHT = -1;
+ // Mid-range brightness values + thresholds
+ private static final int LOW_BACKLIGHT = (int) (MAX_BACKLIGHT * 0.25f);
+ private static final int MID_BACKLIGHT = (int) (MAX_BACKLIGHT * 0.5f);
+ private static final int HIGH_BACKLIGHT = (int) (MAX_BACKLIGHT * 0.75f);
+
+ // Defaults for now. MIN_BACKLIGHT will be replaced later
+ private static final int[] BACKLIGHTS = new int[] {
+ AUTO_BACKLIGHT, MIN_BACKLIGHT, LOW_BACKLIGHT, MID_BACKLIGHT, HIGH_BACKLIGHT,
+ MAX_BACKLIGHT
+ };
+
+ private static final Uri BRIGHTNESS_URI = Settings.System
+ .getUriFor(Settings.System.SCREEN_BRIGHTNESS);
+ private static final Uri BRIGHTNESS_MODE_URI = Settings.System
+ .getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE);
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(BRIGHTNESS_URI);
+ OBSERVED_URIS.add(BRIGHTNESS_MODE_URI);
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.LIGHT_SENSOR_CUSTOM));
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.LIGHT_SCREEN_DIM));
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.EXPANDED_BRIGHTNESS_MODE));
+ }
+
+ private boolean mAutoBrightnessSupported = false;
+
+ private boolean mAutoBrightness = false;
+
+ private int mCurrentBrightness;
+
+ private int mCurrentBacklightIndex = 0;
+
+ private int[] mBacklightValues = new int[] {
+ 0, 1, 2, 3, 4, 5
+ };
+
+ public BrightnessButton() {
+ mType = BUTTON_BRIGHTNESS;
+ }
+
+ @Override
+ protected void setupButton(View view) {
+ super.setupButton(view);
+ if (mView != null) {
+ Context context = mView.getContext();
+ mAutoBrightnessSupported = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_automatic_brightness_available);
+ updateSettings(context.getContentResolver());
+ }
+ }
+
+ @Override
+ protected void updateState(Context context) {
+ if (mAutoBrightness) {
+ mIcon = R.drawable.stat_brightness_auto;
+ mState = STATE_ENABLED;
+ } else if (mCurrentBrightness <= LOW_BACKLIGHT) {
+ mIcon = R.drawable.stat_brightness_off;
+ mState = STATE_DISABLED;
+ } else if (mCurrentBrightness <= MID_BACKLIGHT) {
+ mIcon = R.drawable.stat_brightness_mid;
+ mState = STATE_INTERMEDIATE;
+ } else {
+ mIcon = R.drawable.stat_brightness_on;
+ mState = STATE_ENABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ PowerManager power = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ ContentResolver resolver = context.getContentResolver();
+
+ mCurrentBacklightIndex++;
+ if (mCurrentBacklightIndex > mBacklightValues.length - 1) {
+ mCurrentBacklightIndex = 0;
+ }
+
+ int backlightIndex = mBacklightValues[mCurrentBacklightIndex];
+ int brightness = BACKLIGHTS[backlightIndex];
+
+ if (brightness == AUTO_BACKLIGHT) {
+ Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ } else {
+ if (mAutoBrightnessSupported) {
+ Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+ }
+ if (power != null) {
+ power.setBacklightBrightness(brightness);
+ }
+ Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
+ }
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.DISPLAY_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ @Override
+ protected void onChangeUri(ContentResolver resolver, Uri uri) {
+ if (BRIGHTNESS_URI.equals(uri)) {
+ mCurrentBrightness = Settings.System.getInt(resolver,
+ Settings.System.SCREEN_BRIGHTNESS, 0);
+ } else if (BRIGHTNESS_MODE_URI.equals(uri)) {
+ mAutoBrightness = (Settings.System.getInt(resolver,
+ Settings.System.SCREEN_BRIGHTNESS_MODE, 0) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ } else {
+ updateSettings(resolver);
+ }
+ }
+
+ private void updateSettings(ContentResolver resolver) {
+ boolean lightSensorCustom = (Settings.System.getInt(resolver,
+ Settings.System.LIGHT_SENSOR_CUSTOM, 0) != 0);
+ if (lightSensorCustom) {
+ BACKLIGHTS[1] = Settings.System.getInt(resolver, Settings.System.LIGHT_SCREEN_DIM,
+ MIN_BACKLIGHT);
+ } else {
+ BACKLIGHTS[1] = MIN_BACKLIGHT;
+ }
+
+ String[] modes = parseStoredValue(Settings.System.getString(
+ resolver, Settings.System.EXPANDED_BRIGHTNESS_MODE));
+ if (modes == null || modes.length == 0) {
+ mBacklightValues = new int[] {
+ 0, 1, 2, 3, 4, 5
+ };
+ } else {
+ mBacklightValues = new int[modes.length];
+ for (int i = 0; i < modes.length; i++) {
+ mBacklightValues[i] = Integer.valueOf(modes[i]);
+ }
+ }
+
+ mAutoBrightness = (Settings.System.getInt(resolver, Settings.System.SCREEN_BRIGHTNESS_MODE,
+ 0) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ if (mAutoBrightness) {
+ mCurrentBrightness = AUTO_BACKLIGHT;
+ } else {
+ mCurrentBrightness = Settings.System.getInt(resolver,
+ Settings.System.SCREEN_BRIGHTNESS, -1);
+ for (int i = 0; i < BACKLIGHTS.length; i++) {
+ if (mCurrentBrightness == BACKLIGHTS[i]) {
+ mCurrentBacklightIndex = i;
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/FlashlightButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/FlashlightButton.java
new file mode 100644
index 0000000..cf8ed2d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/FlashlightButton.java
@@ -0,0 +1,58 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Settings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlashlightButton extends PowerButton {
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.TORCH_STATE));
+ }
+
+ public FlashlightButton() { mType = BUTTON_FLASHLIGHT; }
+
+ @Override
+ protected void updateState(Context context) {
+ boolean enabled = Settings.System.getInt(context.getContentResolver(), Settings.System.TORCH_STATE, 0) == 1;
+ if(enabled) {
+ mIcon = R.drawable.stat_flashlight_on;
+ mState = STATE_ENABLED;
+ } else {
+ mIcon = R.drawable.stat_flashlight_off;
+ mState = STATE_DISABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ boolean bright = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_FLASH_MODE, 0) == 1;
+ Intent i = new Intent("net.cactii.flash2.TOGGLE_FLASHLIGHT");
+ i.putExtra("bright", bright);
+ context.sendBroadcast(i);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ // it may be better to make an Intent action for the Torch
+ // we may want to look at that option later
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("net.cactii.flash2", "net.cactii.flash2.MainActivity");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/GPSButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/GPSButton.java
new file mode 100644
index 0000000..579d1d9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/GPSButton.java
@@ -0,0 +1,62 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.location.LocationManager;
+import android.net.Uri;
+import android.provider.Settings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GPSButton extends PowerButton {
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+ }
+
+ public GPSButton() { mType = BUTTON_GPS; }
+
+ @Override
+ protected void updateState(Context context) {
+ if (getGpsState(context)) {
+ mIcon = R.drawable.stat_gps_on;
+ mState = STATE_ENABLED;
+ } else {
+ mIcon = R.drawable.stat_gps_off;
+ mState = STATE_DISABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ ContentResolver resolver = context.getContentResolver();
+ boolean enabled = getGpsState(context);
+ Settings.Secure.setLocationProviderEnabled(resolver,
+ LocationManager.GPS_PROVIDER, !enabled);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.LOCATION_SOURCE_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ private boolean getGpsState(Context context) {
+ ContentResolver resolver = context.getContentResolver();
+ return Settings.Secure.isLocationProviderEnabled(resolver,
+ LocationManager.GPS_PROVIDER);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LTEButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LTEButton.java
new file mode 100644
index 0000000..ea8bf79
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LTEButton.java
@@ -0,0 +1,89 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.Phone;
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LTEButton extends PowerButton{
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE));
+ }
+
+ public LTEButton() { mType = BUTTON_LTE; }
+
+ @Override
+ protected void updateState(Context context) {
+ int network = getCurrentPreferredNetworkMode(context);
+ switch(network) {
+ case Phone.NT_MODE_GLOBAL:
+ case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+ case Phone.NT_MODE_LTE_GSM_WCDMA:
+ case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+ case Phone.NT_MODE_LTE_ONLY:
+ case Phone.NT_MODE_LTE_WCDMA:
+ mIcon = R.drawable.stat_lte_on;
+ mState = STATE_ENABLED;
+ break;
+ default:
+ mIcon = R.drawable.stat_lte_off;
+ mState = STATE_DISABLED;
+ break;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ TelephonyManager tm = (TelephonyManager)
+ context.getSystemService(Context.TELEPHONY_SERVICE);
+ int network = getCurrentPreferredNetworkMode(context);
+ switch(network) {
+ case Phone.NT_MODE_GLOBAL:
+ case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+ case Phone.NT_MODE_LTE_GSM_WCDMA:
+ case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+ case Phone.NT_MODE_LTE_ONLY:
+ case Phone.NT_MODE_LTE_WCDMA:
+ tm.toggleLTE(false);
+ break;
+ default:
+ tm.toggleLTE(true);
+ break;
+ }
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.phone", "com.android.phone.Settings");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ private static int getCurrentPreferredNetworkMode(Context context) {
+ int network = -1;
+ try {
+ network = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.PREFERRED_NETWORK_MODE);
+ } catch (SettingNotFoundException e) {
+ e.printStackTrace();
+ }
+ return network;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LockScreenButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LockScreenButton.java
new file mode 100644
index 0000000..2c7a8f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/LockScreenButton.java
@@ -0,0 +1,78 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import android.app.KeyguardManager;
+import android.app.KeyguardManager.KeyguardLock;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.view.View;
+
+import com.android.systemui.R;
+
+public class LockScreenButton extends PowerButton {
+ private static final String KEY_DISABLED = "lockscreen_disabled";
+
+ private KeyguardLock mLock = null;
+ private boolean mDisabledLockscreen = false;
+
+ public LockScreenButton() { mType = BUTTON_LOCKSCREEN; }
+
+ @Override
+ protected void updateState(Context context) {
+ if (!mDisabledLockscreen) {
+ mIcon = R.drawable.stat_lock_screen_on;
+ mState = STATE_ENABLED;
+ } else {
+ mIcon = R.drawable.stat_lock_screen_off;
+ mState = STATE_DISABLED;
+ }
+ }
+
+ @Override
+ protected void setupButton(View view) {
+ super.setupButton(view);
+
+ if (view == null && mDisabledLockscreen) {
+ mLock.reenableKeyguard();
+ mLock = null;
+ } else if (view != null) {
+ Context context = view.getContext();
+ mDisabledLockscreen = getPreferences(context).getBoolean(KEY_DISABLED, false);
+ applyState(context);
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ mDisabledLockscreen = !mDisabledLockscreen;
+
+ SharedPreferences.Editor editor = getPreferences(context).edit();
+ editor.putBoolean(KEY_DISABLED, mDisabledLockscreen);
+ editor.apply();
+
+ applyState(context);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.SECURITY_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ private void applyState(Context context) {
+ if (mLock == null) {
+ KeyguardManager keyguardManager = (KeyguardManager)
+ context.getSystemService(Context.KEYGUARD_SERVICE);
+ mLock = keyguardManager.newKeyguardLock("PowerWidget");
+ }
+ if (mDisabledLockscreen) {
+ mLock.disableKeyguard();
+ } else {
+ mLock.reenableKeyguard();
+ }
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaKeyEventButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaKeyEventButton.java
new file mode 100644
index 0000000..0e66500
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaKeyEventButton.java
@@ -0,0 +1,57 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.IAudioService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.KeyEvent;
+
+public abstract class MediaKeyEventButton extends PowerButton {
+ private static final String TAG = "MediaKeyEventButton";
+
+ private AudioManager mAM = null;
+ private IAudioService mAS = null;
+
+ protected void sendMediaKeyEvent(Context context, int code) {
+ long eventtime = SystemClock.uptimeMillis();
+ KeyEvent key = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, code, 0);
+ dispatchMediaKeyWithWakeLockToAudioService(key);
+ dispatchMediaKeyWithWakeLockToAudioService(KeyEvent.changeAction(key, KeyEvent.ACTION_UP));
+ }
+
+ void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
+ if (ActivityManagerNative.isSystemReady()) {
+ IAudioService audioService = getAudioService();
+ if (audioService != null) {
+ try {
+ audioService.dispatchMediaKeyEventUnderWakelock(event);
+ } catch (RemoteException e) {
+ Log.e(TAG, "dispatchMediaKeyEvent threw exception " + e);
+ }
+ }
+ }
+ }
+
+ IAudioService getAudioService() {
+ if (mAS == null) {
+ mAS = IAudioService.Stub.asInterface(
+ ServiceManager.checkService(Context.AUDIO_SERVICE));
+ if (mAS == null) {
+ Log.w(TAG, "Unable to find IAudioService interface.");
+ }
+ }
+ return mAS;
+ }
+
+ protected AudioManager getAudioManager(Context context) {
+ if (mAM == null) {
+ mAM = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ }
+
+ return mAM;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaNextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaNextButton.java
new file mode 100644
index 0000000..c5c0791
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaNextButton.java
@@ -0,0 +1,26 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.view.KeyEvent;
+
+public class MediaNextButton extends MediaKeyEventButton {
+ public MediaNextButton() { mType = BUTTON_MEDIA_NEXT; }
+
+ @Override
+ protected void updateState(Context context) {
+ mIcon = R.drawable.stat_media_next;
+ mState = STATE_DISABLED;
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ sendMediaKeyEvent(context, KeyEvent.KEYCODE_MEDIA_NEXT);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPlayPauseButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPlayPauseButton.java
new file mode 100644
index 0000000..9a6ec71
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPlayPauseButton.java
@@ -0,0 +1,57 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.view.KeyEvent;
+
+public class MediaPlayPauseButton extends MediaKeyEventButton {
+ public MediaPlayPauseButton() { mType = BUTTON_MEDIA_PLAY_PAUSE; }
+
+ private static final int MEDIA_STATE_UNKNOWN = -1;
+ private static final int MEDIA_STATE_INACTIVE = 0;
+ private static final int MEDIA_STATE_ACTIVE = 1;
+
+ private int mCurrentState = MEDIA_STATE_UNKNOWN;
+
+ @Override
+ protected void updateState(Context context) {
+ mState = STATE_DISABLED;
+ if (isMusicActive(context)) {
+ mIcon = R.drawable.stat_media_pause;
+ } else {
+ mIcon = R.drawable.stat_media_play;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ sendMediaKeyEvent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+
+ mCurrentState = (isMusicActive(context) ? MEDIA_STATE_INACTIVE : MEDIA_STATE_ACTIVE);
+
+ update(context);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ return false;
+ }
+
+ private boolean isMusicActive(Context context) {
+ if (mCurrentState == MEDIA_STATE_UNKNOWN) {
+ mCurrentState = MEDIA_STATE_INACTIVE;
+ AudioManager am = getAudioManager(context);
+ if (am != null) {
+ mCurrentState = (am.isMusicActive() ? MEDIA_STATE_ACTIVE : MEDIA_STATE_INACTIVE);
+ }
+
+ return (mCurrentState == MEDIA_STATE_ACTIVE);
+ } else {
+ boolean active = (mCurrentState == MEDIA_STATE_ACTIVE);
+ mCurrentState = MEDIA_STATE_UNKNOWN;
+ return active;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPreviousButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPreviousButton.java
new file mode 100644
index 0000000..362b1f7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MediaPreviousButton.java
@@ -0,0 +1,26 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.view.KeyEvent;
+
+public class MediaPreviousButton extends MediaKeyEventButton {
+ public MediaPreviousButton() { mType = BUTTON_MEDIA_PREVIOUS; }
+
+ @Override
+ protected void updateState(Context context) {
+ mIcon = R.drawable.stat_media_previous;
+ mState = STATE_DISABLED;
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ sendMediaKeyEvent(context, KeyEvent.KEYCODE_MEDIA_PREVIOUS);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MobileDataButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MobileDataButton.java
new file mode 100644
index 0000000..e53d1fa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/MobileDataButton.java
@@ -0,0 +1,68 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.provider.Settings;
+
+import com.android.internal.telephony.TelephonyIntents;
+
+public class MobileDataButton extends PowerButton {
+
+ public static final String ACTION_MODIFY_NETWORK_MODE = "com.android.internal.telephony.MODIFY_NETWORK_MODE";
+ public static final String EXTRA_NETWORK_MODE = "networkMode";
+
+ public MobileDataButton() { mType = BUTTON_MOBILEDATA; }
+
+ @Override
+ protected void updateState(Context context) {
+ if (getDataState(context)) {
+ mIcon = R.drawable.stat_data_on;
+ mState = STATE_ENABLED;
+ } else {
+ mIcon = R.drawable.stat_data_off;
+ mState = STATE_DISABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ boolean enabled = getDataState(context);
+
+ ConnectivityManager cm = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (enabled) {
+ cm.setMobileDataEnabled(false);
+ } else {
+ cm.setMobileDataEnabled(true);
+ }
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ // it may be better to make an Intent action for this or find the appropriate one
+ // we may want to look at that option later
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.phone", "com.android.phone.Settings");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected IntentFilter getBroadcastIntentFilter() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
+ return filter;
+ }
+
+ private boolean getDataState(Context context) {
+ ConnectivityManager cm = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ return cm.getMobileDataEnabled();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/NetworkModeButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/NetworkModeButton.java
new file mode 100644
index 0000000..c4ee5d2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/NetworkModeButton.java
@@ -0,0 +1,194 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.provider.Settings.SettingNotFoundException;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class NetworkModeButton extends PowerButton{
+ private static final String TAG = "NetworkModeButton";
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.Secure.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE));
+ }
+
+ // retrieved from Phone.apk
+ public static final String ACTION_NETWORK_MODE_CHANGED = "com.android.internal.telephony.NETWORK_MODE_CHANGED";
+ public static final String ACTION_REQUEST_NETWORK_MODE = "com.android.internal.telephony.REQUEST_NETWORK_MODE";
+ public static final String ACTION_MODIFY_NETWORK_MODE = "com.android.internal.telephony.MODIFY_NETWORK_MODE";
+ public static final String EXTRA_NETWORK_MODE = "networkMode";
+
+ private static final int NO_NETWORK_MODE_YET = -99;
+ private static final int NETWORK_MODE_UNKNOWN = -100;
+
+ private static final int CM_MODE_3G2G = 0;
+ private static final int CM_MODE_3GONLY = 1;
+ private static final int CM_MODE_BOTH = 2;
+
+ private int mMode = NO_NETWORK_MODE_YET;
+ private int mIntendedMode = NO_NETWORK_MODE_YET;
+ private int mInternalState = STATE_INTERMEDIATE;
+
+ public NetworkModeButton() { mType = BUTTON_NETWORKMODE; }
+
+ @Override
+ protected void updateState(Context context) {
+ mMode = get2G3G(context);
+ mState = networkModeToState(context);
+
+ switch (mState) {
+ case STATE_DISABLED:
+ mIcon = R.drawable.stat_2g3g_off;
+ break;
+ case STATE_ENABLED:
+ if (mMode == Phone.NT_MODE_WCDMA_ONLY) {
+ mIcon = R.drawable.stat_3g_on;
+ } else {
+ mIcon = R.drawable.stat_2g3g_on;
+ }
+ break;
+ case STATE_INTERMEDIATE:
+ // In the transitional state, the bottom green bar
+ // shows the tri-state (on, off, transitioning), but
+ // the top dark-gray-or-bright-white logo shows the
+ // user's intent. This is much easier to see in
+ // sunlight.
+ if (mInternalState == STATE_TURNING_ON) {
+ if (mIntendedMode == Phone.NT_MODE_WCDMA_ONLY) {
+ mIcon = R.drawable.stat_3g_on;
+ } else {
+ mIcon = R.drawable.stat_2g3g_on;
+ }
+ } else {
+ mIcon = R.drawable.stat_2g3g_off;
+ }
+ break;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ int currentMode = getCurrentCMMode(context);
+
+ Intent intent = new Intent(ACTION_MODIFY_NETWORK_MODE);
+ switch (mMode) {
+ case Phone.NT_MODE_WCDMA_PREF:
+ case Phone.NT_MODE_GSM_UMTS:
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_GSM_ONLY);
+ mInternalState = STATE_TURNING_OFF;
+ mIntendedMode = Phone.NT_MODE_GSM_ONLY;
+ break;
+ case Phone.NT_MODE_WCDMA_ONLY:
+ if (currentMode == CM_MODE_3GONLY) {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_GSM_ONLY);
+ mInternalState = STATE_TURNING_OFF;
+ mIntendedMode = Phone.NT_MODE_GSM_ONLY;
+ } else {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF);
+ mInternalState = STATE_TURNING_ON;
+ mIntendedMode = Phone.NT_MODE_WCDMA_PREF;
+ }
+ break;
+ case Phone.NT_MODE_GSM_ONLY:
+ if (currentMode == CM_MODE_3GONLY || currentMode == CM_MODE_BOTH) {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_WCDMA_ONLY);
+ mInternalState = STATE_TURNING_ON;
+ mIntendedMode = Phone.NT_MODE_WCDMA_ONLY;
+ } else {
+ intent.putExtra(EXTRA_NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF);
+ mInternalState = STATE_TURNING_ON;
+ mIntendedMode = Phone.NT_MODE_WCDMA_PREF;
+ }
+ break;
+ }
+
+ mMode = NETWORK_MODE_UNKNOWN;
+ context.sendBroadcast(intent);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ // it may be better to make an Intent action for this or find the appropriate one
+ // we may want to look at that option later
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.phone", "com.android.phone.Settings");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getExtras() != null) {
+ mMode = intent.getExtras().getInt(EXTRA_NETWORK_MODE);
+ //Update to actual state
+ mIntendedMode = mMode;
+ }
+
+ //need to clear intermediate states
+ mInternalState = STATE_ENABLED;
+ mInternalState = networkModeToState(context);
+ }
+
+ @Override
+ protected IntentFilter getBroadcastIntentFilter() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_NETWORK_MODE_CHANGED);
+ return filter;
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ private static int get2G3G(Context context) {
+ int state = 99;
+ try {
+ state = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.PREFERRED_NETWORK_MODE);
+ } catch (SettingNotFoundException e) {
+ }
+ return state;
+ }
+
+ private int networkModeToState(Context context) {
+ if (mInternalState == STATE_TURNING_ON || mInternalState == STATE_TURNING_OFF) {
+ return STATE_INTERMEDIATE;
+ }
+
+ switch (mMode) {
+ case Phone.NT_MODE_WCDMA_PREF:
+ case Phone.NT_MODE_WCDMA_ONLY:
+ case Phone.NT_MODE_GSM_UMTS:
+ return STATE_ENABLED;
+ case Phone.NT_MODE_GSM_ONLY:
+ return STATE_DISABLED;
+ case Phone.NT_MODE_CDMA:
+ case Phone.NT_MODE_CDMA_NO_EVDO:
+ case Phone.NT_MODE_EVDO_NO_CDMA:
+ case Phone.NT_MODE_GLOBAL:
+ // need to check wtf is going on
+ Log.d(TAG, "Unexpected network mode (" + mMode + ")");
+ return STATE_DISABLED;
+ }
+ return STATE_INTERMEDIATE;
+ }
+
+ private static int getCurrentCMMode(Context context) {
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_NETWORK_MODE,
+ CM_MODE_3G2G);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java
new file mode 100644
index 0000000..2ff3161
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerButton.java
@@ -0,0 +1,194 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import android.app.ActivityManagerNative;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.graphics.PorterDuff.Mode;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.Vibrator;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class PowerButton {
+ public static final String TAG = "PowerButton";
+
+ public static final int STATE_ENABLED = 1;
+ public static final int STATE_DISABLED = 2;
+ public static final int STATE_TURNING_ON = 3;
+ public static final int STATE_TURNING_OFF = 4;
+ public static final int STATE_INTERMEDIATE = 5;
+ public static final int STATE_UNKNOWN = 6;
+
+ public static final String BUTTON_WIFI = "toggleWifi";
+ public static final String BUTTON_GPS = "toggleGPS";
+ public static final String BUTTON_BLUETOOTH = "toggleBluetooth";
+ public static final String BUTTON_BRIGHTNESS = "toggleBrightness";
+ public static final String BUTTON_SOUND = "toggleSound";
+ public static final String BUTTON_SYNC = "toggleSync";
+ public static final String BUTTON_WIFIAP = "toggleWifiAp";
+ public static final String BUTTON_SCREENTIMEOUT = "toggleScreenTimeout";
+ public static final String BUTTON_MOBILEDATA = "toggleMobileData";
+ public static final String BUTTON_LOCKSCREEN = "toggleLockScreen";
+ public static final String BUTTON_NETWORKMODE = "toggleNetworkMode";
+ public static final String BUTTON_AUTOROTATE = "toggleAutoRotate";
+ public static final String BUTTON_AIRPLANE = "toggleAirplane";
+ public static final String BUTTON_FLASHLIGHT = "toggleFlashlight";
+ public static final String BUTTON_SLEEP = "toggleSleepMode";
+ public static final String BUTTON_MEDIA_PLAY_PAUSE = "toggleMediaPlayPause";
+ public static final String BUTTON_MEDIA_PREVIOUS = "toggleMediaPrevious";
+ public static final String BUTTON_MEDIA_NEXT = "toggleMediaNext";
+ public static final String BUTTON_LTE = "toggleLte";
+ public static final String BUTTON_WIMAX = "toggleWimax";
+ public static final String BUTTON_UNKNOWN = "unknown";
+ private static final String SEPARATOR = "OV=I=XseparatorX=I=VO";
+ private static final Mode MASK_MODE = Mode.SCREEN;
+
+ protected int mIcon;
+ protected int mState;
+ protected View mView;
+ protected String mType = BUTTON_UNKNOWN;
+
+ private ImageView mIconView;
+
+ private View.OnClickListener mExternalClickListener;
+ private View.OnLongClickListener mExternalLongClickListener;
+
+ protected boolean mHapticFeedback;
+ protected Vibrator mVibrator;
+ private long[] mClickPattern;
+ private long[] mLongClickPattern;
+
+ // we use this to ensure we update our views on the UI thread
+ private Handler mViewUpdateHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (mIconView != null) {
+ mIconView.setImageResource(mIcon);
+ }
+ }
+ };
+
+ protected abstract void updateState(Context context);
+ protected abstract void toggleState(Context context);
+ protected abstract boolean handleLongClick(Context context);
+
+ protected void update(Context context) {
+ updateState(context);
+ updateView();
+ }
+
+ public String[] parseStoredValue(CharSequence val) {
+ if (TextUtils.isEmpty(val)) {
+ return null;
+ } else {
+ return val.toString().split(SEPARATOR);
+ }
+ }
+
+ protected void onReceive(Context context, Intent intent) {
+ // do nothing as a standard, override this if the button needs to respond
+ // to broadcast events from the StatusBarService broadcast receiver
+ }
+
+ protected void onChangeUri(ContentResolver resolver, Uri uri) {
+ // do nothing as a standard, override this if the button needs to respond
+ // to a changed setting
+ }
+
+ /* package */ void setHapticFeedback(boolean enabled,
+ long[] clickPattern, long[] longClickPattern) {
+ mHapticFeedback = enabled;
+ mClickPattern = clickPattern;
+ mLongClickPattern = longClickPattern;
+ }
+
+ protected IntentFilter getBroadcastIntentFilter() {
+ return new IntentFilter();
+ }
+
+ protected List<Uri> getObservedUris() {
+ return new ArrayList<Uri>();
+ }
+
+ protected void setupButton(View view) {
+ mView = view;
+ if (mView != null) {
+ mView.setTag(mType);
+ mView.setOnClickListener(mClickListener);
+ mView.setOnLongClickListener(mLongClickListener);
+
+ mIconView = (ImageView) mView.findViewById(R.id.power_widget_button_image);
+ mVibrator = (Vibrator) mView.getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ } else {
+ mIconView = null;
+ }
+ }
+
+ protected void updateView() {
+ mViewUpdateHandler.sendEmptyMessage(0);
+ }
+
+ private View.OnClickListener mClickListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ if (mHapticFeedback && mClickPattern != null) {
+ if (mClickPattern.length == 1) {
+ // One-shot vibration
+ mVibrator.vibrate(mClickPattern[0]);
+ } else {
+ // Pattern vibration
+ mVibrator.vibrate(mClickPattern, -1);
+ }
+ }
+ toggleState(v.getContext());
+ update(v.getContext());
+
+ if (mExternalClickListener != null) {
+ mExternalClickListener.onClick(v);
+ }
+ }
+ };
+
+ private View.OnLongClickListener mLongClickListener = new View.OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ boolean result = handleLongClick(v.getContext());
+
+ if (result && mHapticFeedback && mLongClickPattern != null) {
+ mVibrator.vibrate(mLongClickPattern, -1);
+ }
+
+ try {
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ }
+
+ if (result && mExternalLongClickListener != null) {
+ mExternalLongClickListener.onLongClick(v);
+ }
+ return result;
+ }
+ };
+
+ void setExternalClickListener(View.OnClickListener listener) {
+ mExternalClickListener = listener;
+ }
+
+ void setExternalLongClickListener(View.OnLongClickListener listener) {
+ mExternalLongClickListener = listener;
+ }
+
+ protected SharedPreferences getPreferences(Context context) {
+ return context.getSharedPreferences("PowerButton-" + mType, Context.MODE_PRIVATE);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerWidget.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerWidget.java
new file mode 100644
index 0000000..ae63720
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/PowerWidget.java
@@ -0,0 +1,536 @@
+/*
+ * 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.systemui.statusbar.powerwidget;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.net.wimax.WimaxHelper;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class PowerWidget extends FrameLayout {
+ private static final String TAG = "PowerWidget";
+
+ public static final String BUTTON_DELIMITER = "|";
+
+ private static final String BUTTONS_DEFAULT = PowerButton.BUTTON_WIFI
+ + BUTTON_DELIMITER + PowerButton.BUTTON_BLUETOOTH
+ + BUTTON_DELIMITER + PowerButton.BUTTON_GPS
+ + BUTTON_DELIMITER + PowerButton.BUTTON_SOUND;
+
+ private static final FrameLayout.LayoutParams WIDGET_LAYOUT_PARAMS = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, // width = match_parent
+ ViewGroup.LayoutParams.WRAP_CONTENT // height = wrap_content
+ );
+
+ private static final LinearLayout.LayoutParams BUTTON_LAYOUT_PARAMS = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, // width = wrap_content
+ ViewGroup.LayoutParams.MATCH_PARENT, // height = match_parent
+ 1.0f // weight = 1
+ );
+
+ private static final int LAYOUT_SCROLL_BUTTON_THRESHOLD = 6;
+
+ // this is a list of all possible buttons and their corresponding classes
+ private static final HashMap<String, Class<? extends PowerButton>> sPossibleButtons =
+ new HashMap<String, Class<? extends PowerButton>>();
+
+ static {
+ sPossibleButtons.put(PowerButton.BUTTON_WIFI, WifiButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_GPS, GPSButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_BLUETOOTH, BluetoothButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_BRIGHTNESS, BrightnessButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_SOUND, SoundButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_SYNC, SyncButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_WIFIAP, WifiApButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_SCREENTIMEOUT, ScreenTimeoutButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_MOBILEDATA, MobileDataButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_LOCKSCREEN, LockScreenButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_NETWORKMODE, NetworkModeButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_AUTOROTATE, AutoRotateButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_AIRPLANE, AirplaneButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_FLASHLIGHT, FlashlightButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_SLEEP, SleepButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_MEDIA_PLAY_PAUSE, MediaPlayPauseButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_MEDIA_PREVIOUS, MediaPreviousButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_MEDIA_NEXT, MediaNextButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_WIMAX, WimaxButton.class);
+ sPossibleButtons.put(PowerButton.BUTTON_LTE, LTEButton.class);
+ }
+
+ // this is a list of our currently loaded buttons
+ private final HashMap<String, PowerButton> mButtons = new HashMap<String, PowerButton>();
+ private final ArrayList<String> mButtonNames = new ArrayList<String>();
+
+ private View.OnClickListener mAllButtonClickListener;
+ private View.OnLongClickListener mAllButtonLongClickListener;
+
+ private Context mContext;
+ private Handler mHandler;
+ private LayoutInflater mInflater;
+ private WidgetBroadcastReceiver mBroadcastReceiver = null;
+ private WidgetSettingsObserver mObserver = null;
+
+ private long[] mShortPressVibePattern;
+ private long[] mLongPressVibePattern;
+
+ private LinearLayout mButtonLayout;
+ private SnappingScrollView mScrollView;
+
+ public PowerWidget(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ mContext = context;
+ mHandler = new Handler();
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ mShortPressVibePattern = getLongIntArray(mContext.getResources(),
+ com.android.internal.R.array.config_virtualKeyVibePattern);
+ mLongPressVibePattern = getLongIntArray(mContext.getResources(),
+ com.android.internal.R.array.config_longPressVibePattern);
+
+ // get an initial width
+ updateButtonLayoutWidth();
+ setupWidget();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ updateVisibility();
+ }
+
+ static long[] getLongIntArray(Resources r, int resid) {
+ int[] ar = r.getIntArray(resid);
+ if (ar == null) {
+ return null;
+ }
+ long[] out = new long[ar.length];
+ for (int i=0; i < ar.length; i++) {
+ out[i] = ar[i];
+ }
+ return out;
+ }
+
+ public void destroyWidget() {
+ Log.i(TAG, "Clearing any old widget stuffs");
+ // remove all views from the layout
+ removeAllViews();
+
+ // unregister our content receiver
+ if (mBroadcastReceiver != null) {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ }
+ // unobserve our content
+ if (mObserver != null) {
+ mObserver.unobserve();
+ }
+
+ // clear the button instances
+ unloadAllButtons();
+ }
+
+ public void setupWidget() {
+ destroyWidget();
+
+ Log.i(TAG, "Setting up widget");
+
+ String buttons = Settings.System.getString(mContext.getContentResolver(), Settings.System.WIDGET_BUTTONS);
+ if (buttons == null) {
+ Log.i(TAG, "Default buttons being loaded");
+ buttons = BUTTONS_DEFAULT;
+ // Add the WiMAX button if it's supported
+ if (WimaxHelper.isWimaxSupported(mContext)) {
+ buttons += BUTTON_DELIMITER + PowerButton.BUTTON_WIMAX;
+ }
+ }
+ Log.i(TAG, "Button list: " + buttons);
+
+ for (String button : buttons.split("\\|")) {
+ if (loadButton(button)) {
+ mButtonNames.add(button);
+ } else {
+ Log.e(TAG, "Error setting up button: " + button);
+ }
+ }
+ recreateButtonLayout();
+ updateHapticFeedbackSetting();
+
+ // set up a broadcast receiver for our intents, based off of what our power buttons have been loaded
+ setupBroadcastReceiver();
+ IntentFilter filter = getMergedBroadcastIntentFilter();
+ // we add this so we can update views and such if the settings for our widget change
+ //filter.addAction(Settings.SETTINGS_CHANGED);
+ // we need to detect orientation changes and update the static button width value appropriately
+ filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ // register the receiver
+ mContext.registerReceiver(mBroadcastReceiver, filter);
+ // register our observer
+ mObserver = new WidgetSettingsObserver(mHandler);
+ mObserver.observe();
+ }
+
+ private boolean loadButton(String key) {
+ // first make sure we have a valid button
+ if (!sPossibleButtons.containsKey(key)) {
+ return false;
+ }
+
+ if (mButtons.containsKey(key)) {
+ return true;
+ }
+
+ try {
+ // we need to instantiate a new button and add it
+ PowerButton pb = sPossibleButtons.get(key).newInstance();
+ pb.setExternalClickListener(mAllButtonClickListener);
+ pb.setExternalLongClickListener(mAllButtonLongClickListener);
+ // save it
+ mButtons.put(key, pb);
+ } catch (Exception e) {
+ Log.e(TAG, "Error loading button: " + key, e);
+ return false;
+ }
+
+ return true;
+ }
+
+ private void unloadButton(String key) {
+ // first make sure we have a valid button
+ if (mButtons.containsKey(key)) {
+ // wipe out the button view
+ mButtons.get(key).setupButton(null);
+ // remove the button from our list of loaded ones
+ mButtons.remove(key);
+ }
+ }
+
+ private void unloadAllButtons() {
+ // cycle through setting the buttons to null
+ for (PowerButton pb : mButtons.values()) {
+ pb.setupButton(null);
+ }
+
+ // clear our list
+ mButtons.clear();
+ mButtonNames.clear();
+ }
+
+ static class SnappingScrollView extends HorizontalScrollView {
+
+ private boolean mSnapTrigger = false;
+
+ public SnappingScrollView(Context context) {
+ super(context);
+ }
+
+ Runnable mSnapRunnable = new Runnable(){
+ @Override
+ public void run() {
+ int mSelectedItem = ((getScrollX() + (BUTTON_LAYOUT_PARAMS.width / 2)) / BUTTON_LAYOUT_PARAMS.width);
+ int scrollTo = mSelectedItem * BUTTON_LAYOUT_PARAMS.width;
+ smoothScrollTo(scrollTo, 0);
+ mSnapTrigger = false;
+ }
+ };
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ if (Math.abs(oldl - l) <= 1 && mSnapTrigger) {
+ removeCallbacks(mSnapRunnable);
+ postDelayed(mSnapRunnable, 100);
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ int action = ev.getAction();
+ if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+ mSnapTrigger = true;
+ }
+ return super.onTouchEvent(ev);
+ }
+
+ }
+
+ private void recreateButtonLayout() {
+ removeAllViews();
+
+ // create a linearlayout to hold our buttons
+ mButtonLayout = new LinearLayout(mContext);
+ mButtonLayout.setOrientation(LinearLayout.HORIZONTAL);
+ mButtonLayout.setGravity(Gravity.CENTER_HORIZONTAL);
+
+ for (String button : mButtonNames) {
+ PowerButton pb = mButtons.get(button);
+ if (pb != null) {
+ View buttonView = mInflater.inflate(R.layout.power_widget_button, null, false);
+ pb.setupButton(buttonView);
+ mButtonLayout.addView(buttonView, BUTTON_LAYOUT_PARAMS);
+ }
+ }
+
+ // we determine if we're using a horizontal scroll view based on a threshold of button counts
+ if (mButtonLayout.getChildCount() > LAYOUT_SCROLL_BUTTON_THRESHOLD) {
+ // we need our horizontal scroll view to wrap the linear layout
+ mScrollView = new SnappingScrollView(mContext);
+ // make the fading edge the size of a button (makes it more noticible that we can scroll
+ mScrollView.setFadingEdgeLength(mContext.getResources().getDisplayMetrics().widthPixels / LAYOUT_SCROLL_BUTTON_THRESHOLD);
+ mScrollView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
+ mScrollView.setOverScrollMode(View.OVER_SCROLL_NEVER);
+ mScrollView.addView(mButtonLayout, WIDGET_LAYOUT_PARAMS);
+ updateScrollbar();
+ addView(mScrollView, WIDGET_LAYOUT_PARAMS);
+ } else {
+ // not needed, just add the linear layout
+ addView(mButtonLayout, WIDGET_LAYOUT_PARAMS);
+ }
+ }
+
+ public void updateAllButtons() {
+ // cycle through our buttons and update them
+ for (PowerButton pb : mButtons.values()) {
+ pb.update(mContext);
+ }
+ }
+
+ private IntentFilter getMergedBroadcastIntentFilter() {
+ IntentFilter filter = new IntentFilter();
+
+ for (PowerButton button : mButtons.values()) {
+ IntentFilter tmp = button.getBroadcastIntentFilter();
+
+ // cycle through these actions, and see if we need them
+ int num = tmp.countActions();
+ for (int i = 0; i < num; i++) {
+ String action = tmp.getAction(i);
+ if(!filter.hasAction(action)) {
+ filter.addAction(action);
+ }
+ }
+ }
+
+ // return our merged filter
+ return filter;
+ }
+
+ private List<Uri> getAllObservedUris() {
+ List<Uri> uris = new ArrayList<Uri>();
+
+ for (PowerButton button : mButtons.values()) {
+ List<Uri> tmp = button.getObservedUris();
+
+ for (Uri uri : tmp) {
+ if (!uris.contains(uri)) {
+ uris.add(uri);
+ }
+ }
+ }
+
+ return uris;
+ }
+
+ public void setGlobalButtonOnClickListener(View.OnClickListener listener) {
+ mAllButtonClickListener = listener;
+ for (PowerButton pb : mButtons.values()) {
+ pb.setExternalClickListener(listener);
+ }
+ }
+
+ public void setGlobalButtonOnLongClickListener(View.OnLongClickListener listener) {
+ mAllButtonLongClickListener = listener;
+ for (PowerButton pb : mButtons.values()) {
+ pb.setExternalLongClickListener(listener);
+ }
+ }
+
+ private void setupBroadcastReceiver() {
+ if (mBroadcastReceiver == null) {
+ mBroadcastReceiver = new WidgetBroadcastReceiver();
+ }
+ }
+
+ private void updateButtonLayoutWidth() {
+ // use our context to set a valid button width
+ BUTTON_LAYOUT_PARAMS.width = mContext.getResources().getDisplayMetrics().widthPixels / LAYOUT_SCROLL_BUTTON_THRESHOLD;
+ }
+
+ public void updateVisibility() {
+ // now check if we need to display the widget still
+ boolean displayPowerWidget = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_VIEW_WIDGET, 0) == 1;
+ if(!displayPowerWidget) {
+ setVisibility(View.GONE);
+ } else {
+ setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void updateScrollbar() {
+ if (mScrollView == null) return;
+ boolean hideScrollBar = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_HIDE_SCROLLBAR, 0) == 1;
+ mScrollView.setHorizontalScrollBarEnabled(!hideScrollBar);
+ }
+
+ private void updateHapticFeedbackSetting() {
+ ContentResolver cr = mContext.getContentResolver();
+ int expandedHapticFeedback = Settings.System.getInt(cr,
+ Settings.System.EXPANDED_HAPTIC_FEEDBACK, 2);
+ long[] clickPattern = null, longClickPattern = null;
+ boolean hapticFeedback;
+
+ if (expandedHapticFeedback == 2) {
+ hapticFeedback = Settings.System.getInt(cr,
+ Settings.System.HAPTIC_FEEDBACK_ENABLED, 1) == 1;
+ } else {
+ hapticFeedback = (expandedHapticFeedback == 1);
+ }
+
+ if (hapticFeedback) {
+ clickPattern = mShortPressVibePattern;
+ longClickPattern = mLongPressVibePattern;
+ }
+
+ for (PowerButton button : mButtons.values()) {
+ button.setHapticFeedback(hapticFeedback, clickPattern, longClickPattern);
+ }
+ }
+
+ // our own broadcast receiver :D
+ private class WidgetBroadcastReceiver extends BroadcastReceiver {
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
+ updateButtonLayoutWidth();
+ recreateButtonLayout();
+ } else {
+ // handle the intent through our power buttons
+ for (PowerButton button : mButtons.values()) {
+ // call "onReceive" on those that matter
+ if (button.getBroadcastIntentFilter().hasAction(action)) {
+ button.onReceive(context, intent);
+ }
+ }
+ }
+
+ // update our widget
+ updateAllButtons();
+ }
+ };
+
+ // our own settings observer :D
+ private class WidgetSettingsObserver extends ContentObserver {
+ public WidgetSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ public void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+
+ // watch for display widget
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.EXPANDED_VIEW_WIDGET),
+ false, this);
+
+ // watch for scrollbar hiding
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.EXPANDED_HIDE_SCROLLBAR),
+ false, this);
+
+ // watch for haptic feedback
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.EXPANDED_HAPTIC_FEEDBACK),
+ false, this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED),
+ false, this);
+
+ // watch for changes in buttons
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.WIDGET_BUTTONS),
+ false, this);
+
+ // watch for power-button specific stuff that has been loaded
+ for(Uri uri : getAllObservedUris()) {
+ resolver.registerContentObserver(uri, false, this);
+ }
+ }
+
+ public void unobserve() {
+ ContentResolver resolver = mContext.getContentResolver();
+
+ resolver.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ ContentResolver resolver = mContext.getContentResolver();
+ Resources res = mContext.getResources();
+
+ // first check if our widget buttons have changed
+ if(uri.equals(Settings.System.getUriFor(Settings.System.WIDGET_BUTTONS))) {
+ setupWidget();
+ // now check if we change visibility
+ } else if(uri.equals(Settings.System.getUriFor(Settings.System.EXPANDED_VIEW_WIDGET))) {
+ updateVisibility();
+ // now check for scrollbar hiding
+ } else if(uri.equals(Settings.System.getUriFor(Settings.System.EXPANDED_HIDE_SCROLLBAR))) {
+ updateScrollbar();
+ }
+
+ if (uri.equals(Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED))
+ || uri.equals(Settings.System.getUriFor(Settings.System.EXPANDED_HAPTIC_FEEDBACK))) {
+ updateHapticFeedbackSetting();
+ }
+
+ // do whatever the individual buttons must
+ for (PowerButton button : mButtons.values()) {
+ if (button.getObservedUris().contains(uri)) {
+ button.onChangeUri(resolver, uri);
+ }
+ }
+
+ // something happened so update the widget
+ updateAllButtons();
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/ScreenTimeoutButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/ScreenTimeoutButton.java
new file mode 100644
index 0000000..15f4977
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/ScreenTimeoutButton.java
@@ -0,0 +1,175 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.provider.Settings;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScreenTimeoutButton extends PowerButton {
+
+ // timeout values
+ private static final int SCREEN_TIMEOUT_MIN = 15000;
+ private static final int SCREEN_TIMEOUT_LOW = 30000;
+ private static final int SCREEN_TIMEOUT_NORMAL = 60000;
+ private static final int SCREEN_TIMEOUT_HIGH = 120000;
+ private static final int SCREEN_TIMEOUT_MAX = 300000;
+
+ // cm modes
+ private static final int CM_MODE_15_60_300 = 0;
+ private static final int CM_MODE_30_120_300 = 1;
+
+ private Toast mToast = null;
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT));
+ }
+
+ public ScreenTimeoutButton() { mType = BUTTON_SCREENTIMEOUT; }
+
+ @Override
+ protected void setupButton(View view) {
+ super.setupButton(view);
+ if (view == null && mToast != null) {
+ mToast.cancel();
+ mToast = null;
+ }
+ }
+
+ @Override
+ protected void updateState(Context context) {
+ int timeout = getScreenTimeout(context);
+
+ if (timeout <= SCREEN_TIMEOUT_LOW) {
+ mIcon = R.drawable.stat_screen_timeout_off;
+ mState = STATE_DISABLED;
+ } else if (timeout <= SCREEN_TIMEOUT_HIGH) {
+ mIcon = R.drawable.stat_screen_timeout_off;
+ mState = STATE_INTERMEDIATE;
+ } else {
+ mIcon = R.drawable.stat_screen_timeout_on;
+ mState = STATE_ENABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ int screenTimeout = getScreenTimeout(context);
+ int currentMode = getCurrentCMMode(context);
+
+ if (screenTimeout < SCREEN_TIMEOUT_MIN) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_MIN;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_LOW;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_LOW) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_NORMAL;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_LOW;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_NORMAL) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_NORMAL;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_HIGH;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_HIGH) {
+ if (currentMode == CM_MODE_15_60_300) {
+ screenTimeout = SCREEN_TIMEOUT_MAX;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_HIGH;
+ }
+ } else if (screenTimeout < SCREEN_TIMEOUT_MAX) {
+ screenTimeout = SCREEN_TIMEOUT_MAX;
+ } else if (currentMode == CM_MODE_30_120_300) {
+ screenTimeout = SCREEN_TIMEOUT_LOW;
+ } else {
+ screenTimeout = SCREEN_TIMEOUT_MIN;
+ }
+
+ Settings.System.putInt(
+ context.getContentResolver(),
+ Settings.System.SCREEN_OFF_TIMEOUT, screenTimeout);
+
+ // cancel any previous toast
+ if (mToast != null) {
+ mToast.cancel();
+ }
+
+ // inform users of how long the timeout is now
+ final String toast = makeTimeoutToastString(context, screenTimeout);
+ mToast = Toast.makeText(context, toast, Toast.LENGTH_LONG);
+ mToast.setGravity(Gravity.CENTER, mToast.getXOffset() / 2, mToast.getYOffset() / 2);
+ mToast.show();
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.DISPLAY_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ private String makeTimeoutToastString(Context context, int timeout) {
+ Resources res = context.getResources();
+ int resId;
+
+ /* ms -> seconds */
+ timeout /= 1000;
+
+ if (timeout >= 60 && timeout % 60 == 0) {
+ /* seconds -> minutes */
+ timeout /= 60;
+ if (timeout >= 60 && timeout % 60 == 0) {
+ /* minutes -> hours */
+ timeout /= 60;
+ resId = timeout == 1
+ ? com.android.internal.R.string.hour
+ : com.android.internal.R.string.hours;
+ } else {
+ resId = timeout == 1
+ ? com.android.internal.R.string.minute
+ : com.android.internal.R.string.minutes;
+ }
+ } else {
+ resId = timeout == 1
+ ? com.android.internal.R.string.second
+ : com.android.internal.R.string.seconds;
+ }
+
+ return res.getString(R.string.powerwidget_screen_timeout_toast,
+ timeout, res.getString(resId));
+ }
+
+ private static int getScreenTimeout(Context context) {
+ return Settings.System.getInt(
+ context.getContentResolver(),
+ Settings.System.SCREEN_OFF_TIMEOUT, 0);
+ }
+
+ private static int getCurrentCMMode(Context context) {
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_SCREENTIMEOUT_MODE,
+ CM_MODE_15_60_300);
+ }
+}
+
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SleepButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SleepButton.java
new file mode 100644
index 0000000..e137de5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SleepButton.java
@@ -0,0 +1,34 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.PowerManager;
+import android.os.SystemClock;
+
+import com.android.systemui.R;
+
+public class SleepButton extends PowerButton {
+ public SleepButton() { mType = BUTTON_SLEEP; }
+
+ @Override
+ protected void updateState(Context context) {
+ mIcon = R.drawable.stat_sleep;
+ mState = STATE_DISABLED;
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ PowerManager pm = (PowerManager)
+ context.getSystemService(Context.POWER_SERVICE);
+ pm.goToSleep(SystemClock.uptimeMillis());
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.DISPLAY_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SoundButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SoundButton.java
new file mode 100644
index 0000000..7f54ba3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SoundButton.java
@@ -0,0 +1,207 @@
+
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SoundButton extends PowerButton {
+
+ private static final String TAG = "SoundButton";
+
+ private static final IntentFilter INTENT_FILTER = new IntentFilter();
+ static {
+ INTENT_FILTER.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ }
+
+ private static final List<Uri> OBSERVED_URIS = new ArrayList<Uri>();
+ static {
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.EXPANDED_RING_MODE));
+ OBSERVED_URIS.add(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING));
+ }
+
+ private final Ringer mSilentRinger = new Ringer(AudioManager.RINGER_MODE_SILENT, false);
+ private final Ringer mVibrateRinger = new Ringer(AudioManager.RINGER_MODE_VIBRATE, true);
+ private final Ringer mSoundRinger = new Ringer(AudioManager.RINGER_MODE_NORMAL, false);
+ private final Ringer mSoundVibrateRinger = new Ringer(AudioManager.RINGER_MODE_NORMAL, true);
+ private final Ringer[] mRingers = new Ringer[] {
+ mSilentRinger, mVibrateRinger, mSoundRinger, mSoundVibrateRinger
+ };
+ private int mRingersIndex;
+ private int[] mRingerValues = new int[] {
+ 0, 1, 2, 3
+ };
+ private int mRingerValuesIndex;
+ private AudioManager mAudioManager;
+
+ public SoundButton() {
+ mType = BUTTON_SOUND;
+ }
+
+ @Override
+ protected void setupButton(View view) {
+ super.setupButton(view);
+ if (mView != null) {
+ Context context = mView.getContext();
+ updateSettings(context.getContentResolver());
+ }
+ }
+
+ @Override
+ protected void updateState(Context context) {
+ findCurrentState(context);
+ switch (mRingersIndex) {
+ case 0:
+ mIcon = R.drawable.stat_silent;
+ mState = STATE_DISABLED;
+ break;
+ case 1:
+ mIcon = R.drawable.stat_vibrate_off;
+ mState = STATE_DISABLED;
+ break;
+ case 2:
+ mIcon = R.drawable.stat_ring_on;
+ mState = STATE_ENABLED;
+ break;
+ case 3:
+ mIcon = R.drawable.stat_ring_vibrate_on;
+ mState = STATE_ENABLED;
+ break;
+ }
+ for (int i = 0; i < mRingerValues.length; i++) {
+ if (mRingersIndex == mRingerValues[i]) {
+ mRingerValuesIndex = i;
+ break;
+ }
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ mRingerValuesIndex++;
+ if (mRingerValuesIndex > mRingerValues.length - 1) {
+ mRingerValuesIndex = 0;
+ }
+ mRingersIndex = mRingerValues[mRingerValuesIndex];
+ if (mRingersIndex > mRingers.length - 1) {
+ mRingersIndex = 0;
+ }
+ Ringer ringer = mRingers[mRingersIndex];
+ ringer.execute(context);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.SOUND_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ protected void onChangeUri(ContentResolver cr, Uri uri) {
+ updateSettings(cr);
+ }
+
+ @Override
+ protected List<Uri> getObservedUris() {
+ return OBSERVED_URIS;
+ }
+
+ @Override
+ protected IntentFilter getBroadcastIntentFilter() {
+ return INTENT_FILTER;
+ }
+
+ private void updateSettings(ContentResolver resolver) {
+ String[] modes = parseStoredValue(Settings.System.getString(
+ resolver, Settings.System.EXPANDED_RING_MODE));
+ if (modes == null || modes.length == 0) {
+ mRingerValues = new int[] {
+ 0, 1, 2, 3
+ };
+ } else {
+ mRingerValues = new int[modes.length];
+ for (int i = 0; i < modes.length; i++) {
+ mRingerValues[i] = Integer.valueOf(modes[i]);
+ }
+ }
+ }
+
+ private void findCurrentState(Context context) {
+ ensureAudioManager(context);
+
+ ContentResolver resolver = context.getContentResolver();
+ boolean vibrateWhenRinging = Settings.System.getInt(resolver,
+ Settings.System.VIBRATE_WHEN_RINGING, 0) == 1;
+ int ringerMode = mAudioManager.getRingerMode();
+ Ringer ringer = new Ringer(ringerMode, vibrateWhenRinging);
+ for (int i = 0; i < mRingers.length; i++) {
+ if (mRingers[i].equals(ringer)) {
+ mRingersIndex = i;
+ break;
+ }
+ }
+ }
+
+ private void ensureAudioManager(Context context) {
+ if (mAudioManager == null) {
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ }
+ }
+
+ private class Ringer {
+ final boolean mVibrateWhenRinging;
+ final int mRingerMode;
+
+
+ Ringer( int ringerMode, boolean vibrateWhenRinging) {
+ mVibrateWhenRinging = vibrateWhenRinging;
+ mRingerMode = ringerMode;
+ }
+
+ void execute(Context context) {
+ // If we are setting a vibrating state, vibrate to indicate it
+ if (mVibrateWhenRinging) {
+ Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ vibrator.vibrate(250);
+ }
+
+ // Set the desired state
+ ContentResolver resolver = context.getContentResolver();
+ Settings.System.putInt(resolver, Settings.System.VIBRATE_WHEN_RINGING,
+ (mVibrateWhenRinging ? 1 : 0));
+ mAudioManager.setRingerMode(mRingerMode);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ if (o.getClass() != getClass()) {
+ return false;
+ }
+ Ringer r = (Ringer) o;
+ if ((mRingerMode == AudioManager.RINGER_MODE_SILENT || mRingerMode == AudioManager.RINGER_MODE_VIBRATE)
+ && (r.mRingerMode == mRingerMode))
+ return true;
+ return r.mVibrateWhenRinging == mVibrateWhenRinging
+ && r.mRingerMode == mRingerMode;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/StateTracker.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/StateTracker.java
new file mode 100644
index 0000000..0a3603d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/StateTracker.java
@@ -0,0 +1,155 @@
+
+package com.android.systemui.statusbar.powerwidget;
+
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * The state machine for Wifi and Bluetooth toggling, tracking reality versus
+ * the user's intent. This is necessary because reality moves relatively slowly
+ * (turning on &amp; off radio drivers), compared to user's expectations.
+ */
+public abstract class StateTracker {
+ // Is the state in the process of changing?
+ private boolean mInTransition = false;
+
+ private Boolean mActualState = null; // initially not set
+
+ private Boolean mIntendedState = null; // initially not set
+
+ // Did a toggle request arrive while a state update was
+ // already in-flight? If so, the mIntendedState needs to be
+ // requested when the other one is done, unless we happened to
+ // arrive at that state already.
+ private boolean mDeferredStateChangeRequestNeeded = false;
+
+ /**
+ * User pressed a button to change the state. Something should immediately
+ * appear to the user afterwards, even if we effectively do nothing. Their
+ * press must be heard.
+ */
+ public final void toggleState(Context context) {
+ int currentState = getTriState(context);
+ boolean newState = false;
+ switch (currentState) {
+ case PowerButton.STATE_ENABLED:
+ newState = false;
+ break;
+ case PowerButton.STATE_DISABLED:
+ newState = true;
+ break;
+ case PowerButton.STATE_INTERMEDIATE:
+ if (mIntendedState != null) {
+ newState = !mIntendedState;
+ }
+ break;
+ }
+ mIntendedState = newState;
+ if (mInTransition) {
+ // We don't send off a transition request if we're
+ // already transitioning. Makes our state tracking
+ // easier, and is probably nicer on lower levels.
+ // (even though they should be able to take it...)
+ mDeferredStateChangeRequestNeeded = true;
+ } else {
+ mInTransition = true;
+ requestStateChange(context, newState);
+ }
+ }
+
+ /**
+ * Update internal state from a broadcast state change.
+ */
+ public abstract void onActualStateChange(Context context, Intent intent);
+
+ /**
+ * Sets the value that we're now in. To be called from onActualStateChange.
+ *
+ * @param newState one of STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON,
+ * STATE_TURNING_OFF, STATE_UNKNOWN
+ */
+ protected final void setCurrentState(Context context, int newState) {
+ final boolean wasInTransition = mInTransition;
+ switch (newState) {
+ case PowerButton.STATE_DISABLED:
+ mInTransition = false;
+ mActualState = false;
+ break;
+ case PowerButton.STATE_ENABLED:
+ mInTransition = false;
+ mActualState = true;
+ break;
+ case PowerButton.STATE_TURNING_ON:
+ mInTransition = true;
+ mActualState = false;
+ break;
+ case PowerButton.STATE_TURNING_OFF:
+ mInTransition = true;
+ mActualState = true;
+ break;
+ }
+
+ if (wasInTransition && !mInTransition) {
+ if (mDeferredStateChangeRequestNeeded) {
+ Log.v("StateTracker", "processing deferred state change");
+ if (mActualState != null && mIntendedState != null
+ && mIntendedState.equals(mActualState)) {
+ Log.v("StateTracker", "... but intended state matches, so no changes.");
+ } else if (mIntendedState != null) {
+ mInTransition = true;
+ requestStateChange(context, mIntendedState);
+ }
+ mDeferredStateChangeRequestNeeded = false;
+ }
+ }
+ }
+
+ /**
+ * If we're in a transition mode, this returns true if we're transitioning
+ * towards being enabled.
+ */
+ public final boolean isTurningOn() {
+ return mIntendedState != null && mIntendedState;
+ }
+
+ /**
+ * Returns simplified 3-state value from underlying 5-state.
+ *
+ * @param context
+ * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE
+ */
+ public final int getTriState(Context context) {
+ /*
+ * if (mInTransition) { // If we know we just got a toggle request
+ * recently // (which set mInTransition), don't even ask the //
+ * underlying interface for its state. We know we're // changing. This
+ * avoids blocking the UI thread // during UI refresh post-toggle if the
+ * underlying // service state accessor has coarse locking on its //
+ * state (to be fixed separately). return
+ * PowerButton.STATE_INTERMEDIATE; }
+ */
+ switch (getActualState(context)) {
+ case PowerButton.STATE_DISABLED:
+ return PowerButton.STATE_DISABLED;
+ case PowerButton.STATE_ENABLED:
+ return PowerButton.STATE_ENABLED;
+ default:
+ return PowerButton.STATE_INTERMEDIATE;
+ }
+ }
+
+ /**
+ * Gets underlying actual state.
+ *
+ * @param context
+ * @return STATE_ENABLED, STATE_DISABLED, STATE_ENABLING, STATE_DISABLING,
+ * or or STATE_UNKNOWN.
+ */
+ public abstract int getActualState(Context context);
+
+ /**
+ * Actually make the desired change to the underlying radio API.
+ */
+ protected abstract void requestStateChange(Context context, boolean desiredState);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SyncButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SyncButton.java
new file mode 100644
index 0000000..c95477d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/SyncButton.java
@@ -0,0 +1,75 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncStatusObserver;
+import android.net.ConnectivityManager;
+import android.util.Log;
+import android.view.View;
+
+public class SyncButton extends PowerButton {
+ private static final String TAG = "SyncButton";
+
+ public SyncButton() { mType = BUTTON_SYNC; }
+
+ private SyncStatusObserver mSyncObserver = new SyncStatusObserver() {
+ public void onStatusChanged(int which) {
+ // update state/view if something happened
+ if (mView != null) {
+ update(mView.getContext());
+ }
+ }
+ };
+ private Object mSyncObserverHandle = null;
+
+ @Override
+ protected void setupButton(View view) {
+ super.setupButton(view);
+
+ if(mView == null && mSyncObserverHandle != null) {
+ Log.i(TAG, "Unregistering sync state listener");
+ ContentResolver.removeStatusChangeListener(mSyncObserverHandle);
+ mSyncObserverHandle = null;
+ } else if(mView != null && mSyncObserverHandle == null) {
+ Log.i(TAG, "Registering sync state listener");
+ mSyncObserverHandle = ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, mSyncObserver);
+ }
+ }
+
+ @Override
+ protected void updateState(Context context) {
+ if (getSyncState(context)) {
+ mIcon = R.drawable.stat_sync_on;
+ mState = STATE_ENABLED;
+ } else {
+ mIcon = R.drawable.stat_sync_off;
+ mState = STATE_DISABLED;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ // If ON turn OFF else turn ON
+ if (getSyncState(context)) {
+ ContentResolver.setMasterSyncAutomatically(false);
+ } else {
+ ContentResolver.setMasterSyncAutomatically(true);
+ }
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.SYNC_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ private boolean getSyncState(Context context) {
+ return ContentResolver.getMasterSyncAutomatically();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiApButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiApButton.java
new file mode 100644
index 0000000..f90fb87
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiApButton.java
@@ -0,0 +1,153 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class WifiApButton extends PowerButton {
+
+ private static final StateTracker sWifiApState = new WifiApStateTracker();
+
+ /**
+ * Subclass of StateTracker to get/set Wifi AP state.
+ */
+ private static final class WifiApStateTracker extends StateTracker {
+ @Override
+ public int getActualState(Context context) {
+ WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager != null) {
+ return wifiApStateToFiveState(wifiManager.getWifiApState());
+ }
+ return STATE_UNKNOWN;
+ }
+
+ @Override
+ protected void requestStateChange(Context context,
+ final boolean desiredState) {
+
+ final WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager == null) {
+ Log.d("WifiAPManager", "No wifiManager.");
+ return;
+ }
+ Log.i("WifiAp", "Setting: " + desiredState);
+
+ // Actually request the Wi-Fi AP change and persistent
+ // settings write off the UI thread, as it can take a
+ // user-noticeable amount of time, especially if there's
+ // disk contention.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {
+ /**
+ * Disable Wif if enabling tethering
+ */
+ int wifiState = wifiManager.getWifiState();
+ if (desiredState
+ && ((wifiState == WifiManager.WIFI_STATE_ENABLING) || (wifiState == WifiManager.WIFI_STATE_ENABLED))) {
+ wifiManager.setWifiEnabled(false);
+ }
+
+ wifiManager.setWifiApEnabled(null, desiredState);
+ Log.i("WifiAp", "Async Setting: " + desiredState);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActualStateChange(Context context, Intent intent) {
+
+ if (!WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent
+ .getAction())) {
+ return;
+ }
+ int wifiState = intent
+ .getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, -1);
+ int widgetState=wifiApStateToFiveState(wifiState);
+ setCurrentState(context, widgetState);
+ }
+
+ /**
+ * Converts WifiManager's state values into our Wifi/WifiAP/Bluetooth-common
+ * state values.
+ */
+ private static int wifiApStateToFiveState(int wifiState) {
+ switch (wifiState) {
+ case WifiManager.WIFI_AP_STATE_DISABLED:
+ return STATE_DISABLED;
+ case WifiManager.WIFI_AP_STATE_ENABLED:
+ return STATE_ENABLED;
+ case WifiManager.WIFI_AP_STATE_DISABLING:
+ return STATE_TURNING_OFF;
+ case WifiManager.WIFI_AP_STATE_ENABLING:
+ return STATE_TURNING_ON;
+ default:
+ return STATE_UNKNOWN;
+ }
+ }
+ }
+
+ public WifiApButton() { mType = BUTTON_WIFIAP; }
+
+ @Override
+ protected void updateState(Context context) {
+ mState = sWifiApState.getTriState(context);
+ switch (mState) {
+ case STATE_DISABLED:
+ mIcon = R.drawable.stat_wifi_ap_off;
+ break;
+ case STATE_ENABLED:
+ mIcon = R.drawable.stat_wifi_ap_on;
+ break;
+ case STATE_INTERMEDIATE:
+ // In the transitional state, the bottom green bar
+ // shows the tri-state (on, off, transitioning), but
+ // the top dark-gray-or-bright-white logo shows the
+ // user's intent. This is much easier to see in
+ // sunlight.
+ if (sWifiApState.isTurningOn()) {
+ mIcon = R.drawable.stat_wifi_ap_on;
+ } else {
+ mIcon = R.drawable.stat_wifi_ap_off;
+ }
+ break;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ sWifiApState.toggleState(context);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ // it may be better to make an Intent action for the WifiAp settings
+ // we may want to look at that option later
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName("com.android.settings", "com.android.settings.TetherSettings");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ sWifiApState.onActualStateChange(context, intent);
+ }
+
+ @Override
+ protected IntentFilter getBroadcastIntentFilter() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+ return filter;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiButton.java
new file mode 100644
index 0000000..b55ba36
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WifiButton.java
@@ -0,0 +1,147 @@
+package com.android.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class WifiButton extends PowerButton{
+
+ private static final StateTracker sWifiState = new WifiStateTracker();
+
+ /**
+ * Subclass of StateTracker to get/set Wifi state.
+ */
+ private static final class WifiStateTracker extends StateTracker {
+ @Override
+ public int getActualState(Context context) {
+ WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager != null) {
+ return wifiStateToFiveState(wifiManager.getWifiState());
+ }
+ return STATE_UNKNOWN;
+ }
+
+ @Override
+ protected void requestStateChange(Context context,
+ final boolean desiredState) {
+ final WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager == null) {
+ Log.d("WifiButton", "No wifiManager.");
+ return;
+ }
+
+ // Actually request the wifi change and persistent
+ // settings write off the UI thread, as it can take a
+ // user-noticeable amount of time, especially if there's
+ // disk contention.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {
+ /**
+ * Disable tethering if enabling Wifi
+ */
+ int wifiApState = wifiManager.getWifiApState();
+ if (desiredState
+ && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) || (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
+ wifiManager.setWifiApEnabled(null, false);
+ }
+
+ wifiManager.setWifiEnabled(desiredState);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActualStateChange(Context context, Intent intent) {
+ if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent
+ .getAction())) {
+ return;
+ }
+ int wifiState = intent
+ .getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
+ int widgetState=wifiStateToFiveState(wifiState);
+ setCurrentState(context, widgetState);
+ }
+
+ /**
+ * Converts WifiManager's state values into our Wifi/Bluetooth-common
+ * state values.
+ */
+ private static int wifiStateToFiveState(int wifiState) {
+ switch (wifiState) {
+ case WifiManager.WIFI_STATE_DISABLED:
+ return STATE_DISABLED;
+ case WifiManager.WIFI_STATE_ENABLED:
+ return STATE_ENABLED;
+ case WifiManager.WIFI_STATE_DISABLING:
+ return STATE_TURNING_OFF;
+ case WifiManager.WIFI_STATE_ENABLING:
+ return STATE_TURNING_ON;
+ default:
+ return STATE_UNKNOWN;
+ }
+ }
+ }
+
+ public WifiButton() { mType = BUTTON_WIFI; }
+
+ @Override
+ protected void updateState(Context context) {
+ mState = sWifiState.getTriState(context);
+ switch (mState) {
+ case STATE_DISABLED:
+ mIcon = R.drawable.stat_wifi_off;
+ break;
+ case STATE_ENABLED:
+ mIcon = R.drawable.stat_wifi_on;
+ break;
+ case STATE_INTERMEDIATE:
+ // In the transitional state, the bottom green bar
+ // shows the tri-state (on, off, transitioning), but
+ // the top dark-gray-or-bright-white logo shows the
+ // user's intent. This is much easier to see in
+ // sunlight.
+ if (sWifiState.isTurningOn()) {
+ mIcon = R.drawable.stat_wifi_on;
+ } else {
+ mIcon = R.drawable.stat_wifi_off;
+ }
+ break;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ sWifiState.toggleState(context);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.settings.WIFI_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ sWifiState.onActualStateChange(context, intent);
+ }
+
+ @Override
+ protected IntentFilter getBroadcastIntentFilter() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ return filter;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WimaxButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WimaxButton.java
new file mode 100644
index 0000000..6f065b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/powerwidget/WimaxButton.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 The CyanogenMod 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.systemui.statusbar.powerwidget;
+
+import com.android.systemui.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wimax.WimaxHelper;
+import android.net.wimax.WimaxManagerConstants;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class WimaxButton extends PowerButton {
+
+ private static final StateTracker sWimaxState = new WimaxStateTracker();
+
+ /**
+ * Subclass of StateTracker to get/set WiMAX state.
+ */
+ private static final class WimaxStateTracker extends StateTracker {
+ @Override
+ public int getActualState(Context context) {
+ if (WimaxHelper.isWimaxSupported(context)) {
+ return wimaxStateToFiveState(WimaxHelper.getWimaxState(context));
+ }
+ return STATE_UNKNOWN;
+ }
+
+ @Override
+ protected void requestStateChange(final Context context,
+ final boolean desiredState) {
+ if (!WimaxHelper.isWimaxSupported(context)) {
+ Log.e(TAG, "WiMAX is not supported");
+ return;
+ }
+
+ // Actually request the wifi change and persistent
+ // settings write off the UI thread, as it can take a
+ // user-noticeable amount of time, especially if there's
+ // disk contention.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {
+ WimaxHelper.setWimaxEnabled(context, desiredState);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActualStateChange(Context context, Intent intent) {
+ String action = intent.getAction();
+ int wimaxState;
+
+ if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION)) {
+ wimaxState = intent.getIntExtra(WimaxManagerConstants.EXTRA_4G_STATE,
+ WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
+ } else if (action.equals(WimaxManagerConstants.WIMAX_ENABLED_CHANGED_ACTION)) {
+ wimaxState = intent.getIntExtra(WimaxManagerConstants.CURRENT_WIMAX_ENABLED_STATE,
+ WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
+ } else {
+ return;
+ }
+ int widgetState = wimaxStateToFiveState(wimaxState);
+ setCurrentState(context, widgetState);
+ }
+
+ /**
+ * Converts Wimax4GManager's state values into our
+ * WiMAX-common state values.
+ * Also compatible with WimaxController state values.
+ */
+ private static int wimaxStateToFiveState(int wimaxState) {
+ switch (wimaxState) {
+ case WimaxManagerConstants.NET_4G_STATE_DISABLED:
+ return STATE_DISABLED;
+ case WimaxManagerConstants.NET_4G_STATE_ENABLED:
+ return STATE_ENABLED;
+ case WimaxManagerConstants.NET_4G_STATE_ENABLING:
+ return STATE_TURNING_ON;
+ case WimaxManagerConstants.NET_4G_STATE_DISABLING:
+ return STATE_TURNING_OFF;
+ default:
+ return STATE_UNKNOWN;
+ }
+ }
+ }
+
+ public WimaxButton() { mType = BUTTON_WIMAX; }
+
+ @Override
+ protected void updateState(Context context) {
+ mState = sWimaxState.getTriState(context);
+ switch (mState) {
+ case STATE_DISABLED:
+ mIcon = R.drawable.stat_wimax_off;
+ break;
+ case STATE_ENABLED:
+ mIcon = R.drawable.stat_wimax_on;
+ break;
+ case STATE_INTERMEDIATE:
+ // In the transitional state, the bottom green bar
+ // shows the tri-state (on, off, transitioning), but
+ // the top dark-gray-or-bright-white logo shows the
+ // user's intent. This is much easier to see in
+ // sunlight.
+ if (sWimaxState.isTurningOn()) {
+ mIcon = R.drawable.stat_wimax_on;
+ } else {
+ mIcon = R.drawable.stat_wimax_off;
+ }
+ break;
+ }
+ }
+
+ @Override
+ protected void toggleState(Context context) {
+ sWimaxState.toggleState(context);
+ }
+
+ @Override
+ protected boolean handleLongClick(Context context) {
+ Intent intent = new Intent("android.intent.action.MAIN");
+ intent.setClassName("com.android.settings.wimax", "com.android.settings.wimax.WimaxSettings");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ return true;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ sWimaxState.onActualStateChange(context, intent);
+ }
+
+ @Override
+ protected IntentFilter getBroadcastIntentFilter() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION);
+ filter.addAction(WimaxManagerConstants.WIMAX_ENABLED_CHANGED_ACTION);
+ return filter;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 86c247a..246c7b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -24,11 +24,13 @@ import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.content.res.CustomTheme;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -38,7 +40,10 @@ import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
import android.text.TextUtils;
+import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.Gravity;
@@ -53,6 +58,7 @@ import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
+import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
@@ -174,6 +180,9 @@ public class TabletStatusBar extends BaseStatusBar implements
private InputMethodsPanel mInputMethodsPanel;
private CompatModePanel mCompatModePanel;
+ // clock
+ private boolean mShowClock;
+
private int mSystemUiVisibility = 0;
private int mNavigationIconHints = 0;
@@ -236,6 +245,12 @@ public class TabletStatusBar extends BaseStatusBar implements
mWindowManager.addView(sb, lp);
}
+ // last theme that was applied in order to detect theme change (as opposed
+ // to some other configuration change).
+ CustomTheme mCurrentTheme;
+ private boolean mRecreating = false;
+
+
protected void addPanelWindows() {
final Context context = mContext;
final Resources res = mContext.getResources();
@@ -379,8 +394,49 @@ public class TabletStatusBar extends BaseStatusBar implements
super.start(); // will add the main bar view
}
+ private static void copyNotifications(ArrayList<Pair<IBinder, StatusBarNotification>> dest,
+ NotificationData source) {
+ int N = source.size();
+ for (int i = 0; i < N; i++) {
+ NotificationData.Entry entry = source.get(i);
+ dest.add(Pair.create(entry.key, entry.notification));
+ }
+ }
+
+ private void recreateStatusBar() {
+ mRecreating = true;
+ mStatusBarContainer.removeAllViews();
+
+ // extract notifications.
+ int nNotifs = mNotificationData.size();
+ ArrayList<Pair<IBinder, StatusBarNotification>> notifications =
+ new ArrayList<Pair<IBinder, StatusBarNotification>>(nNotifs);
+ copyNotifications(notifications, mNotificationData);
+ mNotificationData.clear();
+
+ mStatusBarContainer.addView(makeStatusBarView());
+
+ // recreate notifications.
+ for (int i = 0; i < nNotifs; i++) {
+ Pair<IBinder, StatusBarNotification> notifData = notifications.get(i);
+ addNotificationViews(notifData.first, notifData.second);
+ }
+
+ setAreThereNotifications();
+
+ mRecreating = false;
+ }
+
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
+ // detect theme change.
+ CustomTheme newTheme = mContext.getResources().getConfiguration().customTheme;
+ if (newTheme != null &&
+ (mCurrentTheme == null || !mCurrentTheme.equals(newTheme))) {
+ mCurrentTheme = (CustomTheme)newTheme.clone();
+ recreateStatusBar();
+ }
loadDimens();
mNotificationPanelParams.height = getNotificationPanelHeight();
mWindowManager.updateViewLayout(mNotificationPanel, mNotificationPanelParams);
@@ -443,6 +499,11 @@ public class TabletStatusBar extends BaseStatusBar implements
protected View makeStatusBarView() {
final Context context = mContext;
+ CustomTheme currentTheme = mContext.getResources().getConfiguration().customTheme;
+ if (currentTheme != null) {
+ mCurrentTheme = (CustomTheme)currentTheme.clone();
+ }
+
loadDimens();
final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
@@ -684,14 +745,14 @@ public class TabletStatusBar extends BaseStatusBar implements
public void onBarHeightChanged(int height) {
final WindowManager.LayoutParams lp
- = (WindowManager.LayoutParams)mStatusBarView.getLayoutParams();
+ = (WindowManager.LayoutParams)mStatusBarContainer.getLayoutParams();
if (lp == null) {
// haven't been added yet
return;
}
if (lp.height != height) {
lp.height = height;
- mWindowManager.updateViewLayout(mStatusBarView, lp);
+ mWindowManager.updateViewLayout(mStatusBarContainer, lp);
}
}
@@ -861,7 +922,7 @@ public class TabletStatusBar extends BaseStatusBar implements
notification.notification.fullScreenIntent.send();
} catch (PendingIntent.CanceledException e) {
}
- } else {
+ } else if (!mRecreating) {
tick(key, notification, true);
}
@@ -876,10 +937,13 @@ public class TabletStatusBar extends BaseStatusBar implements
}
public void showClock(boolean show) {
+ ContentResolver resolver = mContext.getContentResolver();
View clock = mBarContents.findViewById(R.id.clock);
View network_text = mBarContents.findViewById(R.id.network_text);
+ mShowClock = (Settings.System.getInt(resolver,
+ Settings.System.STATUS_BAR_CLOCK, 1) == 1);
if (clock != null) {
- clock.setVisibility(show ? View.VISIBLE : View.GONE);
+ clock.setVisibility(show ? (mShowClock ? View.VISIBLE : View.GONE) : View.GONE);
}
if (network_text != null) {
network_text.setVisibility((!show) ? View.VISIBLE : View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 06696fe..dfea5f5 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -129,6 +129,7 @@ public class StorageNotification extends StorageEventListener {
}
private void onStorageStateChangedAsync(String path, String oldState, String newState) {
+ boolean isPrimary = mStorageManager.getPrimaryVolume().getPath().equals(path);
if (DEBUG) Slog.i(TAG, String.format(
"Media {%s} state changed from {%s} -> {%s}", path, oldState, newState));
if (newState.equals(Environment.MEDIA_SHARED)) {
@@ -206,6 +207,8 @@ public class StorageNotification extends StorageEventListener {
*/
Intent intent = new Intent();
intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
+ // send the volume's path through to the formatting activity
+ intent.putExtra(com.android.internal.app.ExternalMediaFormatActivity.FORMAT_PATH, path);
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
setMediaStorageNotification(
@@ -220,6 +223,8 @@ public class StorageNotification extends StorageEventListener {
*/
Intent intent = new Intent();
intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
+ // send the volume's path through to the formatting activity
+ intent.putExtra(com.android.internal.app.ExternalMediaFormatActivity.FORMAT_PATH, path);
PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
setMediaStorageNotification(
@@ -230,25 +235,25 @@ public class StorageNotification extends StorageEventListener {
} else if (newState.equals(Environment.MEDIA_REMOVED)) {
/*
* Storage has been removed. Show nomedia media notification,
- * and disable UMS notification regardless of connection state.
+ * and disable UMS notification if the removed storage is the primary storage.
*/
setMediaStorageNotification(
com.android.internal.R.string.ext_media_nomedia_notification_title,
com.android.internal.R.string.ext_media_nomedia_notification_message,
com.android.internal.R.drawable.stat_notify_sdcard_usb,
- true, false, null);
- updateUsbMassStorageNotification(false);
+ true, !isPrimary, null);
+ updateUsbMassStorageNotification(isPrimary ? false : mUmsAvailable);
} else if (newState.equals(Environment.MEDIA_BAD_REMOVAL)) {
/*
* Storage has been removed unsafely. Show bad removal media notification,
- * and disable UMS notification regardless of connection state.
+ * and disable UMS notification if the removed storage is the primary storage.
*/
setMediaStorageNotification(
com.android.internal.R.string.ext_media_badremoval_notification_title,
com.android.internal.R.string.ext_media_badremoval_notification_message,
com.android.internal.R.drawable.stat_sys_warning,
true, true, null);
- updateUsbMassStorageNotification(false);
+ updateUsbMassStorageNotification(isPrimary ? false : mUmsAvailable);
} else {
Slog.w(TAG, String.format("Ignoring unknown state {%s}", newState));
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
index e61ef8a..9ae39ad 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
@@ -188,7 +188,7 @@ public class UsbStorageActivity extends Activity
super.onPause();
unregisterReceiver(mUsbStateReceiver);
- if (mStorageManager == null && mStorageListener != null) {
+ if (mStorageManager != null && mStorageListener != null) {
mStorageManager.unregisterListener(mStorageListener);
}
}
diff --git a/packages/VpnDialogs/res/values-cs/strings.xml b/packages/VpnDialogs/res/values-cs/strings.xml
index 28e861f..1fcc65b 100644
--- a/packages/VpnDialogs/res/values-cs/strings.xml
+++ b/packages/VpnDialogs/res/values-cs/strings.xml
@@ -16,15 +16,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="prompt" msgid="8359175999006833462">"Aplikace <xliff:g id="APP">%s</xliff:g> se pokouší připojit k síti VPN."</string>
- <string name="warning" msgid="5470743576660160079">"Pokračováním souhlasíte s tím, aby aplikace sledovala veškerou vaši síťovou aktivitu. "<b>" Pokud aplikaci nevěříte, nepokračujte."</b>" V opačném případě riskujete vystavení svých dat škodlivému softwaru."</string>
+ <string name="prompt" msgid="8359175999006833462">"Aplikace <xliff:g id="APP">%s</xliff:g> se pokouší vytvořit VPN spojení."</string>
+ <string name="warning" msgid="5470743576660160079">"Pokračováním souhlasíte s tím, aby aplikace zachytávala veškerou vaši síťovou aktivitu. "<b>"Pokud aplikaci nevěříte, nepokračujte."</b>" V opačném případě riskujete vystavení svých dat škodlivému softwaru."</string>
<string name="accept" msgid="2889226408765810173">"Této aplikaci věřím."</string>
+
<string name="legacy_title" msgid="192936250066580964">"Síť VPN je připojena"</string>
- <string name="configure" msgid="4905518375574791375">"Konfigurovat"</string>
+ <string name="configure" msgid="4905518375574791375">"Nastavit"</string>
<string name="disconnect" msgid="971412338304200056">"Odpojit"</string>
<string name="session" msgid="6470628549473641030">"Relace:"</string>
<string name="duration" msgid="3584782459928719435">"Doba trvání:"</string>
<string name="data_transmitted" msgid="7988167672982199061">"Odesláno:"</string>
<string name="data_received" msgid="4062776929376067820">"Přijato:"</string>
+
<string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajtů / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketů"</string>
</resources>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
index 13d8019..7a1e66c 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
@@ -66,7 +66,7 @@ public class ConfirmDialog extends AlertActivity implements
getString(R.string.prompt, app.loadLabel(pm)));
((CompoundButton) view.findViewById(R.id.check)).setOnCheckedChangeListener(this);
- mAlertParams.mIconId = android.R.drawable.ic_dialog_alert;
+ mAlertParams.mIconAttrId = android.R.attr.alertDialogIcon;
mAlertParams.mTitle = getText(android.R.string.dialog_alert_title);
mAlertParams.mPositiveButtonText = getText(android.R.string.ok);
mAlertParams.mPositiveButtonListener = this;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index d1f8ef1..2c1d250 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2010-2012 CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +26,8 @@ import com.android.internal.R;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.Profile;
+import android.app.ProfileManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@@ -69,8 +72,21 @@ import android.widget.ImageView.ScaleType;
import android.widget.ListView;
import android.widget.TextView;
+import com.android.internal.app.ThemeUtils;
+
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
+
+/**
+ * Needed for takeScreenshot
+ */
+import android.content.ServiceConnection;
+import android.content.ComponentName;
+import android.os.IBinder;
+import android.os.Messenger;
+import android.os.RemoteException;
+
/**
* Helper to show the global actions dialog. Each item is an {@link Action} that
@@ -85,6 +101,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private final Context mContext;
private final WindowManagerFuncs mWindowManagerFuncs;
+
+ private Context mUiContext;
private final AudioManager mAudioManager;
private final IDreamManager mDreamManager;
@@ -93,6 +111,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private Action mSilentModeAction;
private ToggleAction mAirplaneModeOn;
+ private ToggleAction mExpandDesktopModeOn;
private MyAdapter mAdapter;
@@ -102,6 +121,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private boolean mIsWaitingForEcmExit = false;
private boolean mHasTelephony;
private boolean mHasVibrator;
+ private Profile mChosenProfile;
/**
* @param context everything needs a context :(
@@ -120,6 +140,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
context.registerReceiver(mBroadcastReceiver, filter);
+ ThemeUtils.registerThemeChangeReceiver(context, mThemeChangeReceiver);
+
// get notified of phone state changes
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
@@ -142,11 +164,16 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mKeyguardShowing = keyguardShowing;
mDeviceProvisioned = isDeviceProvisioned;
if (mDialog != null) {
+ if (mUiContext != null) {
+ mUiContext = null;
+ }
mDialog.dismiss();
mDialog = null;
+ mDialog = createDialog();
// Show delayed, so that the dismiss of the previous dialog completes
mHandler.sendEmptyMessage(MESSAGE_SHOW);
} else {
+ mDialog = createDialog();
handleShow();
}
}
@@ -165,7 +192,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private void handleShow() {
awakenIfNecessary();
- mDialog = createDialog();
prepareDialog();
WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes();
@@ -175,6 +201,13 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
}
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
+
/**
* Create the global actions dialog.
* @return A new dialog.
@@ -186,6 +219,28 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
} else {
mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
}
+
+ mExpandDesktopModeOn = new ToggleAction(
+ R.drawable.ic_lock_expanded_desktop,
+ R.drawable.ic_lock_expanded_desktop,
+ R.string.global_actions_toggle_expanded_desktop_mode,
+ R.string.global_actions_expanded_desktop_mode_on_status,
+ R.string.global_actions_expanded_desktop_mode_off_status) {
+
+ void onToggle(boolean on) {
+ changeExpandDesktopModeSystemSetting(on);
+ }
+
+ public boolean showDuringKeyguard() {
+ return false;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return false;
+ }
+ };
+ onExpandDesktopModeChanged();
+
mAirplaneModeOn = new ToggleAction(
R.drawable.ic_lock_airplane_mode,
R.drawable.ic_lock_airplane_mode_off,
@@ -242,11 +297,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mWindowManagerFuncs.shutdown(true);
}
- public boolean onLongPress() {
- mWindowManagerFuncs.rebootSafeMode(true);
- return true;
- }
-
public boolean showDuringKeyguard() {
return true;
}
@@ -256,8 +306,89 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
});
+ // next: reboot
+ // only shown if enabled, enabled by default
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POWER_MENU_REBOOT_ENABLED, 1) == 1) {
+ mItems.add(
+ new SinglePressAction(R.drawable.ic_lock_reboot, R.string.global_action_reboot) {
+ public void onPress() {
+ mWindowManagerFuncs.reboot();
+ }
+
+ public boolean onLongPress() {
+ mWindowManagerFuncs.rebootSafeMode(true);
+ return true;
+ }
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ });
+ }
+
+ // next: profile
+ // only shown if both system profiles and the menu item is enabled, enabled by default
+ if ((Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.SYSTEM_PROFILES_ENABLED, 1) == 1) &&
+ (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POWER_MENU_PROFILES_ENABLED, 1) == 1)) {
+ mItems.add(
+ new ProfileChooseAction() {
+ public void onPress() {
+ createProfileDialog();
+ }
+
+ public boolean onLongPress() {
+ return true;
+ }
+
+ public boolean showDuringKeyguard() {
+ return false;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return false;
+ }
+ });
+ }
+
+ // next: screenshot
+ // only shown if enabled, disabled by default
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POWER_MENU_SCREENSHOT_ENABLED, 0) == 1) {
+ mItems.add(
+ new SinglePressAction(R.drawable.ic_lock_screenshot, R.string.global_action_screenshot) {
+ public void onPress() {
+ takeScreenshot();
+ }
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ });
+ }
+
+ // next: expanded desktop toggle
+ // only shown if enabled, disabled by default
+ if(Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POWER_MENU_EXPANDED_DESKTOP_ENABLED, 0) == 1){
+ mItems.add(mExpandDesktopModeOn);
+ }
+
// next: airplane mode
- mItems.add(mAirplaneModeOn);
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POWER_MENU_AIRPLANE_ENABLED, 1) == 1) {
+ mItems.add(mAirplaneModeOn);
+ }
// next: bug report, if enabled
if (Settings.Secure.getInt(mContext.getContentResolver(),
@@ -267,7 +398,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
R.string.global_action_bug_report) {
public void onPress() {
- AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ AlertDialog.Builder builder = new AlertDialog.Builder(getUiContext());
builder.setTitle(com.android.internal.R.string.bugreport_title);
builder.setMessage(com.android.internal.R.string.bugreport_message);
builder.setNegativeButton(com.android.internal.R.string.cancel, null);
@@ -308,24 +439,27 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
});
}
- // last: silent mode
- if (SHOW_SILENT_TOGGLE) {
- mItems.add(mSilentModeAction);
+ // next: optionally add a list of users to switch to
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POWER_MENU_USER_ENABLED, 0) == 1) {
+ addUsersToMenu(mItems);
}
- // one more thing: optionally add a list of users to switch to
- if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {
- addUsersToMenu(mItems);
+ // last: silent mode
+ if ((Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POWER_MENU_SOUND_ENABLED, 1) == 1) &&
+ (SHOW_SILENT_TOGGLE)) {
+ mItems.add(mSilentModeAction);
}
mAdapter = new MyAdapter();
- AlertParams params = new AlertParams(mContext);
+ AlertParams params = new AlertParams(getUiContext());
params.mAdapter = mAdapter;
params.mOnClickListener = this;
params.mForceInverseBackground = true;
- GlobalActionsDialog dialog = new GlobalActionsDialog(mContext, params);
+ GlobalActionsDialog dialog = new GlobalActionsDialog(getUiContext(), params);
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
dialog.getListView().setItemsCanFocus(true);
@@ -338,6 +472,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
return mAdapter.getItem(position).onLongPress();
}
});
+
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
dialog.setOnDismissListener(this);
@@ -385,11 +520,131 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
+ private void createProfileDialog() {
+ final ProfileManager profileManager = (ProfileManager) mContext
+ .getSystemService(Context.PROFILE_SERVICE);
+
+ final Profile[] profiles = profileManager.getProfiles();
+ UUID activeProfile = profileManager.getActiveProfile().getUuid();
+ final CharSequence[] names = new CharSequence[profiles.length];
+
+ int i = 0;
+ int checkedItem = 0;
+
+ for (Profile profile : profiles) {
+ if (profile.getUuid().equals(activeProfile)) {
+ checkedItem = i;
+ mChosenProfile = profile;
+ }
+ names[i++] = profile.getName();
+ }
+
+ final AlertDialog.Builder ab = new AlertDialog.Builder(getUiContext());
+
+ AlertDialog dialog = ab.setSingleChoiceItems(names, checkedItem,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which < 0)
+ return;
+ mChosenProfile = profiles[which];
+ profileManager.setActiveProfile(mChosenProfile.getUuid());
+ dialog.cancel();
+ }
+ }).create();
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+ dialog.show();
+ }
+
+ /**
+ * functions needed for taking screenhots.
+ * This leverages the built in ICS screenshot functionality
+ */
+ final Object mScreenshotLock = new Object();
+ ServiceConnection mScreenshotConnection = null;
+
+ final Runnable mScreenshotTimeout = new Runnable() {
+ @Override public void run() {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != null) {
+ mContext.unbindService(mScreenshotConnection);
+ mScreenshotConnection = null;
+ }
+ }
+ }
+ };
+
+ private void takeScreenshot() {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != null) {
+ return;
+ }
+ ComponentName cn = new ComponentName("com.android.systemui",
+ "com.android.systemui.screenshot.TakeScreenshotService");
+ Intent intent = new Intent();
+ intent.setComponent(cn);
+ ServiceConnection conn = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != this) {
+ return;
+ }
+ Messenger messenger = new Messenger(service);
+ Message msg = Message.obtain(null, 1);
+ final ServiceConnection myConn = this;
+ Handler h = new Handler(mHandler.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection == myConn) {
+ mContext.unbindService(mScreenshotConnection);
+ mScreenshotConnection = null;
+ mHandler.removeCallbacks(mScreenshotTimeout);
+ }
+ }
+ }
+ };
+ msg.replyTo = new Messenger(h);
+ msg.arg1 = msg.arg2 = 0;
+
+ /* remove for the time being
+ if (mStatusBar != null && mStatusBar.isVisibleLw())
+ msg.arg1 = 1;
+ if (mNavigationBar != null && mNavigationBar.isVisibleLw())
+ msg.arg2 = 1;
+ */
+
+ /* wait for the dialog box to close */
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {
+ }
+
+ /* take the screenshot */
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ @Override
+ public void onServiceDisconnected(ComponentName name) {}
+ };
+ if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE, UserHandle.USER_CURRENT)) {
+ mScreenshotConnection = conn;
+ mHandler.postDelayed(mScreenshotTimeout, 10000);
+ }
+ }
+ }
+
private void prepareDialog() {
refreshSilentMode();
mAirplaneModeOn.updateState(mAirplaneState);
mAdapter.notifyDataSetChanged();
mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+
+ mDialog.setTitle(R.string.global_actions);
+
if (SHOW_SILENT_TOGGLE) {
IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
mContext.registerReceiver(mRingerModeReceiver, filter);
@@ -486,7 +741,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
public View getView(int position, View convertView, ViewGroup parent) {
Action action = getItem(position);
- return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+ final Context context = getUiContext();
+ return action.create(context, convertView, parent, LayoutInflater.from(context));
}
}
@@ -587,6 +843,48 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
/**
+ * A single press action maintains no state, just responds to a press
+ * and takes an action.
+ */
+ private abstract class ProfileChooseAction implements Action {
+ private ProfileManager mProfileManager;
+
+ protected ProfileChooseAction() {
+ mProfileManager = (ProfileManager)mContext.getSystemService(Context.PROFILE_SERVICE);
+ }
+
+ public boolean isEnabled() {
+ return true;
+ }
+
+ abstract public void onPress();
+
+ public View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
+ View v = (convertView != null) ?
+ convertView :
+ inflater.inflate(R.layout.global_actions_item, parent, false);
+
+ ImageView icon = (ImageView) v.findViewById(R.id.icon);
+ TextView messageView = (TextView) v.findViewById(R.id.message);
+ TextView statusView = (TextView) v.findViewById(R.id.status);
+ if (statusView != null) {
+ statusView.setVisibility(View.VISIBLE);
+ statusView.setText(mProfileManager.getActiveProfile().getName());
+ }
+
+ if (icon != null) {
+ icon.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_lock_profile));
+ }
+
+ if (messageView != null) {
+ messageView.setText(R.string.global_action_choose_profile);
+ }
+
+ return v;
+ }
+ }
+
+ /**
* A toggle action knows whether it is on or off, and displays an icon
* and status message accordingly.
*/
@@ -832,6 +1130,12 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
};
+ private BroadcastReceiver mThemeChangeReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ };
+
PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
@@ -895,6 +1199,14 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mAirplaneModeOn.updateState(mAirplaneState);
}
+ private void onExpandDesktopModeChanged() {
+ boolean expandDesktopModeOn = Settings.System.getInt(
+ mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STATE,
+ 0) == 1;
+ mExpandDesktopModeOn.updateState(expandDesktopModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
+ }
+
/**
* Change the airplane mode system setting
*/
@@ -912,6 +1224,16 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
+ /**
+ * Change the expand desktop mode system setting
+ */
+ private void changeExpandDesktopModeSystemSetting(boolean on) {
+ Settings.System.putInt(
+ mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STATE,
+ on ? 1 : 0);
+ }
+
private static final class GlobalActionsDialog extends Dialog implements DialogInterface {
private final Context mContext;
private final int mWindowTouchSlop;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index fb515ac..8998d57 100755..100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1,4 +1,5 @@
/*
+ * File modifications copyright (C) 2012 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +17,9 @@
package com.android.internal.policy.impl;
import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.app.UiModeManager;
@@ -25,11 +28,13 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -37,6 +42,7 @@ import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.media.IAudioService;
import android.media.Ringtone;
@@ -50,6 +56,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -60,6 +67,9 @@ import android.os.Vibrator;
import android.provider.Settings;
import com.android.internal.R;
+import com.android.internal.app.ThemeUtils;
+import com.android.internal.os.DeviceKeyHandler;
+import com.android.internal.os.IDeviceHandler;
import com.android.internal.policy.PolicyManager;
import com.android.internal.policy.impl.keyguard.KeyguardViewManager;
import com.android.internal.policy.impl.keyguard.KeyguardViewMediator;
@@ -148,11 +158,17 @@ import android.view.KeyCharacterMap.FallbackAction;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import android.view.VolumePanel;
+import android.widget.Toast;
+import android.media.IAudioService;
+import android.media.AudioService;
+import android.media.AudioManager;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.List;
/**
* WindowManagerPolicy implementation for the Android phone UI. This
@@ -193,6 +209,24 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
+ // Available custom actions to perform on a key press.
+ // Must match values for KEY_HOME_LONG_PRESS_ACTION in:
+ // core/java/android/provider/Settings.java
+ private static final int KEY_ACTION_NOTHING = 0;
+ private static final int KEY_ACTION_MENU = 1;
+ private static final int KEY_ACTION_APP_SWITCH = 2;
+ private static final int KEY_ACTION_SEARCH = 3;
+ private static final int KEY_ACTION_VOICE_SEARCH = 4;
+ private static final int KEY_ACTION_IN_APP_SEARCH = 5;
+
+ // Masks for checking presence of hardware keys.
+ // Must match values in core/res/res/values/config.xml
+ private static final int KEY_MASK_HOME = 0x01;
+ private static final int KEY_MASK_BACK = 0x02;
+ private static final int KEY_MASK_MENU = 0x04;
+ private static final int KEY_MASK_ASSIST = 0x08;
+ private static final int KEY_MASK_APP_SWITCH = 0x10;
+
/**
* These are the system UI flags that, when changing, can cause the layout
* of the screen to change.
@@ -223,6 +257,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
}
+ private final DeviceKeyHandler mDeviceKeyHandler;
+
/**
* Lock protecting internal state. Must not call out into window
* manager with lock held. (This lock will be acquired in places
@@ -231,6 +267,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final Object mLock = new Object();
Context mContext;
+ Context mUiContext;
IWindowManager mWindowManager;
WindowManagerFuncs mWindowManagerFuncs;
PowerManager mPowerManager;
@@ -294,8 +331,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mSystemReady;
boolean mSystemBooted;
boolean mHdmiPlugged;
+ boolean mWifiDisplayConnected;
int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
int mLidOpenRotation;
+ boolean mHasRemovableLid;
int mCarDockRotation;
int mDeskDockRotation;
int mHdmiRotation;
@@ -303,6 +342,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
int mUserRotation = Surface.ROTATION_0;
+ int mUserRotationAngles = -1;
boolean mAccelerometerDefault;
int mAllowAllRotations = -1;
@@ -317,13 +357,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mOrientationSensorEnabled = false;
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
-
+ int mBackKillTimeout;
int mPointerLocationMode = 0; // guarded by mLock
+ int mDeviceHardwareKeys;
+ boolean mHasHomeKey;
+ boolean mHasMenuKey;
+ boolean mHasAssistKey;
+ boolean mHasAppSwitchKey;
// The last window we were told about in focusChanged.
WindowState mFocusedWindow;
IApplicationToken mFocusedApp;
+ // Behavior of volume wake
+ boolean mVolumeWakeScreen;
+
+ // Behavior of volbtn music controls
+ boolean mVolBtnMusicControls;
+ boolean mIsLongPress;
+
private static final class PointerLocationInputEventReceiver extends InputEventReceiver {
private final PointerLocationView mView;
@@ -430,6 +482,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mDreamingLockscreen;
boolean mHomePressed;
boolean mHomeLongPressed;
+ boolean mAppSwitchLongPressed;
Intent mHomeIntent;
Intent mCarDockIntent;
Intent mDeskDockIntent;
@@ -437,6 +490,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mConsumeSearchKeyUp;
boolean mAssistKeyLongPressed;
+ // Used when key is pressed and performing non-default action
+ boolean mMenuDoCustomAction;
+
+ // Tracks user-customisable behavior for certain key events
+ private int mLongPressOnHomeBehavior = -1;
+ private int mPressOnMenuBehavior = -1;
+ private int mLongPressOnMenuBehavior = -1;
+ private int mPressOnAssistBehavior = -1;
+ private int mLongPressOnAssistBehavior = -1;
+ private int mPressOnAppSwitchBehavior = -1;
+ private int mLongPressOnAppSwitchBehavior = -1;
+
+ // To identify simulated keypresses, so we can perform
+ // the default action for that key
+ private boolean mIsVirtualKeypress;
+
+ // Tracks preloading of the recent apps screen
+ private boolean mRecentAppsPreloaded;
+
// support for activating the lock screen while the screen is on
boolean mAllowLockscreenWhenOn;
int mLockScreenTimeout;
@@ -451,23 +523,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Display mDisplay;
+ // Behavior of HOME button during incomming call ring.
+ // (See Settings.Secure.RING_HOME_BUTTON_BEHAVIOR.)
+ int mRingHomeBehavior;
+
int mLandscapeRotation = 0; // default landscape rotation
int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
int mPortraitRotation = 0; // default portrait rotation
int mUpsideDownRotation = 0; // "other" portrait rotation
- // What we do when the user long presses on home
- private int mLongPressOnHomeBehavior = -1;
-
// Screenshot trigger states
// Time to volume and power must be pressed within this interval of each other.
- private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
+ private static final long ACTION_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
// Increase the chord delay when taking a screenshot from the keyguard
private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f;
private boolean mScreenshotChordEnabled;
private boolean mVolumeDownKeyTriggered;
private long mVolumeDownKeyTime;
- private boolean mVolumeDownKeyConsumedByScreenshotChord;
+ private long mVolumeUpKeyTime;
+ private boolean mVolumeDownKeyConsumedByChord;
+ private boolean mVolumeUpKeyConsumedByChord;
private boolean mVolumeUpKeyTriggered;
private boolean mPowerKeyTriggered;
private long mPowerKeyTime;
@@ -485,6 +560,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private static final int MSG_DISABLE_POINTER_LOCATION = 2;
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
+ private static final int MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK = 5;
private class PolicyHandler extends Handler {
@Override
@@ -502,6 +578,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
break;
+ case MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK:
+ mIsLongPress = true;
+ dispatchMediaKeyWithWakeLockToAudioService((KeyEvent)msg.obj);
+ dispatchMediaKeyWithWakeLockToAudioService(KeyEvent.changeAction((KeyEvent)msg.obj, KeyEvent.ACTION_UP));
+ break;
}
}
}
@@ -527,6 +608,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this,
UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.RING_HOME_BUTTON_BEHAVIOR), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.VOLUME_WAKE_SCREEN), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.VOLBTN_MUSIC_CONTROLS), false, this,
+ UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.ACCELEROMETER_ROTATION), false, this,
UserHandle.USER_ALL);
@@ -545,6 +635,29 @@ public class PhoneWindowManager implements WindowManagerPolicy {
resolver.registerContentObserver(Settings.System.getUriFor(
"fancy_rotation_anim"), false, this,
UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.EXPANDED_DESKTOP_STATE), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.ACCELEROMETER_ROTATION_ANGLES), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.KEY_HOME_LONG_PRESS_ACTION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.KEY_MENU_ACTION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.KEY_MENU_LONG_PRESS_ACTION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.KEY_ASSIST_ACTION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.KEY_ASSIST_LONG_PRESS_ACTION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.KEY_APP_SWITCH_ACTION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.HARDWARE_KEY_REBINDING), false, this);
+
updateSettings();
}
@@ -567,6 +680,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
MyOrientationListener mOrientationListener;
+ public PhoneWindowManager(IDeviceHandler device) {
+ mDeviceKeyHandler = (device != null) ? device.getDeviceKeyHandler() : null;
+ }
+
IStatusBarService getStatusBarService() {
synchronized (mServiceAquireLock) {
if (mStatusBarService == null) {
@@ -681,9 +798,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mScreenshotChordEnabled
&& mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) {
final long now = SystemClock.uptimeMillis();
- if (now <= mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
- && now <= mPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
- mVolumeDownKeyConsumedByScreenshotChord = true;
+ if (now <= mVolumeDownKeyTime + ACTION_CHORD_DEBOUNCE_DELAY_MILLIS
+ && now <= mPowerKeyTime + ACTION_CHORD_DEBOUNCE_DELAY_MILLIS) {
+ mVolumeDownKeyConsumedByChord = true;
cancelPendingPowerKeyAction();
mHandler.postDelayed(mScreenshotChordLongPress, getScreenshotChordLongPressDelay());
@@ -705,6 +822,24 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHandler.removeCallbacks(mScreenshotChordLongPress);
}
+ private void interceptRingerChord() {
+ if (mVolumeDownKeyTriggered && !mPowerKeyTriggered && mVolumeUpKeyTriggered) {
+ final long now = SystemClock.uptimeMillis();
+ if (now <= mVolumeDownKeyTime + ACTION_CHORD_DEBOUNCE_DELAY_MILLIS
+ && now <= mVolumeUpKeyTime + ACTION_CHORD_DEBOUNCE_DELAY_MILLIS) {
+ mVolumeDownKeyConsumedByChord = true;
+ mVolumeUpKeyConsumedByChord = true;
+
+ mHandler.postDelayed(mRingerChordLongPress,
+ ViewConfiguration.getGlobalActionKeyTimeout());
+ }
+ }
+ }
+
+ private void cancelPendingRingerChordAction() {
+ mHandler.removeCallbacks(mRingerChordLongPress);
+ }
+
private final Runnable mPowerLongPress = new Runnable() {
@Override
public void run() {
@@ -746,6 +881,70 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
+ private final Runnable mRingerChordLongPress = new Runnable() {
+ public void run() {
+ // Do the switch
+ final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
+ final int ringerMode = am.getRingerMode();
+ final VolumePanel volumePanel = new VolumePanel(ThemeUtils.createUiContext(mContext),
+ (AudioService) getAudioService());
+ if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {
+ boolean vibrateSetting = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
+ am.setRingerMode(vibrateSetting ? AudioManager.RINGER_MODE_VIBRATE :
+ AudioManager.RINGER_MODE_SILENT);
+ } else {
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ }
+ volumePanel.postVolumeChanged(AudioManager.STREAM_RING,AudioManager.FLAG_SHOW_UI
+ | AudioManager.FLAG_VIBRATE);
+ }
+ };
+
+ Runnable mBackLongPress = new Runnable() {
+ public void run() {
+ try {
+ final Intent intent = new Intent(Intent.ACTION_MAIN);
+ String defaultHomePackage = "com.android.launcher";
+ intent.addCategory(Intent.CATEGORY_HOME);
+ final ResolveInfo res = mContext.getPackageManager().resolveActivity(intent, 0);
+ if (res.activityInfo != null && !res.activityInfo.packageName.equals("android")) {
+ defaultHomePackage = res.activityInfo.packageName;
+ }
+ boolean targetKilled = false;
+ IActivityManager am = ActivityManagerNative.getDefault();
+ List<RunningAppProcessInfo> apps = am.getRunningAppProcesses();
+ for (RunningAppProcessInfo appInfo : apps) {
+ int uid = appInfo.uid;
+ // Make sure it's a foreground user application (not system,
+ // root, phone, etc.)
+ if (uid >= Process.FIRST_APPLICATION_UID && uid <= Process.LAST_APPLICATION_UID
+ && appInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
+ if (appInfo.pkgList != null && (appInfo.pkgList.length > 0)) {
+ for (String pkg : appInfo.pkgList) {
+ if (!pkg.equals("com.android.systemui") && !pkg.equals(defaultHomePackage)) {
+ am.forceStopPackage(pkg, UserHandle.USER_CURRENT);
+ targetKilled = true;
+ break;
+ }
+ }
+ } else {
+ Process.killProcess(appInfo.pid);
+ targetKilled = true;
+ }
+ }
+ if (targetKilled) {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ Toast.makeText(mContext, R.string.app_killed_message, Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+ } catch (RemoteException remoteException) {
+ // Do nothing; just let it go.
+ }
+ }
+ };
+
void showGlobalActionsDialog() {
if (mGlobalActions == null) {
mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
@@ -764,39 +963,85 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
}
- private void handleLongPressOnHome() {
- // We can't initialize this in init() since the configuration hasn't been loaded yet.
- if (mLongPressOnHomeBehavior < 0) {
- mLongPressOnHomeBehavior
- = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior);
- if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
- mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
- mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
+ private void triggerVirtualKeypress(final int keyCode) {
+ new Thread(new Runnable() {
+ public void run() {
+ InputManager im = InputManager.getInstance();
+ long now = SystemClock.uptimeMillis();
+
+ final KeyEvent downEvent = new KeyEvent(now, now, KeyEvent.ACTION_DOWN,
+ keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+ KeyEvent.FLAG_FROM_SYSTEM, InputDevice.SOURCE_KEYBOARD);
+ final KeyEvent upEvent = KeyEvent.changeAction(downEvent, KeyEvent.ACTION_UP);
+
+ mIsVirtualKeypress = true;
+ im.injectInputEvent(downEvent, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT);
+ im.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT);
+ mIsVirtualKeypress = false;
}
- }
+ }).start();
+ }
- if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
- performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
+ private void performKeyAction(int behavior) {
+ switch (behavior) {
+ case KEY_ACTION_NOTHING:
+ break;
+ case KEY_ACTION_MENU:
+ triggerVirtualKeypress(KeyEvent.KEYCODE_MENU);
+ break;
+ case KEY_ACTION_APP_SWITCH:
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.toggleRecentApps();
+ mRecentAppsPreloaded = false;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when showing recent apps", e);
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
+ }
+ break;
+ case KEY_ACTION_SEARCH:
+ launchAssistAction();
+ break;
+ case KEY_ACTION_VOICE_SEARCH:
+ launchAssistLongPressAction();
+ break;
+ case KEY_ACTION_IN_APP_SEARCH:
+ triggerVirtualKeypress(KeyEvent.KEYCODE_SEARCH);
+ break;
+ default:
+ break;
+ }
+ }
- // Eat the longpress so it won't dismiss the recent apps dialog when
- // the user lets go of the home key
- mHomeLongPressed = true;
+ private void preloadRecentApps() {
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.preloadRecentApps();
+ mRecentAppsPreloaded = true;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when preloading recent apps", e);
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
}
+ }
- if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
- showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
- } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.toggleRecentApps();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when showing recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
+ private void cancelPreloadRecentApps() {
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.cancelPreloadRecentApps();
+ mRecentAppsPreloaded = false;
}
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when showing recent apps", e);
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
}
}
@@ -899,6 +1144,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
com.android.internal.R.integer.config_lidNavigationAccessibility);
mLidControlsSleep = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_lidControlsSleep);
+ mHasRemovableLid = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_hasRemovableLid);
+ mBackKillTimeout = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_backKillTimeout);
+ mDeviceHardwareKeys = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_deviceHardwareKeys);
+ mHasHomeKey = ((mDeviceHardwareKeys & KEY_MASK_HOME) != 0);
+ mHasMenuKey = ((mDeviceHardwareKeys & KEY_MASK_MENU) != 0);
+ mHasAssistKey = ((mDeviceHardwareKeys & KEY_MASK_ASSIST) != 0);
+ mHasAppSwitchKey = ((mDeviceHardwareKeys & KEY_MASK_APP_SWITCH) != 0);
+
// register for dock events
IntentFilter filter = new IntentFilter();
filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
@@ -924,6 +1180,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
context.registerReceiver(mMultiuserReceiver, filter);
mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
+ // register for WIFI Display intents
+ IntentFilter wifiDisplayFilter = new IntentFilter(
+ Intent.ACTION_WIFI_DISPLAY_VIDEO);
+ Intent wifidisplayIntent = context.registerReceiver(
+ mWifiDisplayReceiver, wifiDisplayFilter);
+
mLongPressVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_longPressVibePattern);
mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(),
@@ -1072,11 +1334,82 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT,
UserHandle.USER_CURRENT);
+ mRingHomeBehavior = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.RING_HOME_BUTTON_BEHAVIOR,
+ Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_DEFAULT,
+ UserHandle.USER_CURRENT);
+ mVolumeWakeScreen = (Settings.System.getIntForUser(resolver,
+ Settings.System.VOLUME_WAKE_SCREEN, 0, UserHandle.USER_CURRENT) == 1);
+ mVolBtnMusicControls = (Settings.System.getIntForUser(resolver,
+ Settings.System.VOLBTN_MUSIC_CONTROLS, 1, UserHandle.USER_CURRENT) == 1);
+
+ boolean keyRebindingEnabled = Settings.System.getInt(resolver,
+ Settings.System.HARDWARE_KEY_REBINDING, 0) == 1;
+
+ if (!keyRebindingEnabled) {
+ if (mHasHomeKey) {
+ if (mHasAppSwitchKey) {
+ mLongPressOnHomeBehavior = KEY_ACTION_NOTHING;
+ } else {
+ mLongPressOnHomeBehavior = KEY_ACTION_APP_SWITCH;
+ }
+ }
+ if (mHasMenuKey) {
+ mPressOnMenuBehavior = KEY_ACTION_MENU;
+ if (mHasAssistKey) {
+ mLongPressOnMenuBehavior = KEY_ACTION_NOTHING;
+ } else {
+ mLongPressOnMenuBehavior = KEY_ACTION_SEARCH;
+ }
+ }
+ if (mHasAssistKey) {
+ mPressOnAssistBehavior = KEY_ACTION_SEARCH;
+ mLongPressOnAssistBehavior = KEY_ACTION_VOICE_SEARCH;
+ }
+ if (mHasAppSwitchKey) {
+ mPressOnAppSwitchBehavior = KEY_ACTION_APP_SWITCH;
+ mLongPressOnAppSwitchBehavior = KEY_ACTION_NOTHING;
+ }
+ } else {
+ if (mHasHomeKey) {
+ if (mHasAppSwitchKey) {
+ mLongPressOnHomeBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_HOME_LONG_PRESS_ACTION, KEY_ACTION_NOTHING);
+ } else {
+ mLongPressOnHomeBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_HOME_LONG_PRESS_ACTION, KEY_ACTION_APP_SWITCH);
+ }
+ }
+ if (mHasMenuKey) {
+ mPressOnMenuBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_MENU_ACTION, KEY_ACTION_MENU);
+ if (mHasAssistKey) {
+ mLongPressOnMenuBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_MENU_LONG_PRESS_ACTION, KEY_ACTION_NOTHING);
+ } else {
+ mLongPressOnMenuBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_MENU_LONG_PRESS_ACTION, KEY_ACTION_SEARCH);
+ }
+ }
+ if (mHasAssistKey) {
+ mPressOnAssistBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_ASSIST_ACTION, KEY_ACTION_SEARCH);
+ mLongPressOnAssistBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_ASSIST_LONG_PRESS_ACTION, KEY_ACTION_VOICE_SEARCH);
+ }
+ if (mHasAppSwitchKey) {
+ mPressOnAppSwitchBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_APP_SWITCH_ACTION, KEY_ACTION_APP_SWITCH);
+ mLongPressOnAppSwitchBehavior = Settings.System.getInt(resolver,
+ Settings.System.KEY_APP_SWITCH_LONG_PRESS_ACTION, KEY_ACTION_NOTHING);
+ }
+ }
// Configure rotation lock.
int userRotation = Settings.System.getIntForUser(resolver,
Settings.System.USER_ROTATION, Surface.ROTATION_0,
UserHandle.USER_CURRENT);
+
if (mUserRotation != userRotation) {
mUserRotation = userRotation;
updateRotation = true;
@@ -1091,6 +1424,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
updateOrientationListenerLp();
}
+ mUserRotationAngles = Settings.System.getInt(resolver,
+ Settings.System.ACCELEROMETER_ROTATION_ANGLES, -1);
+
if (mSystemReady) {
int pointerLocation = Settings.System.getIntForUser(resolver,
Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT);
@@ -1528,15 +1864,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "addStartingWindow " + packageName
+ ": nonLocalizedLabel=" + nonLocalizedLabel + " theme="
+ Integer.toHexString(theme));
- if (theme != context.getThemeResId() || labelRes != 0) {
- try {
- context = context.createPackageContext(packageName, 0);
+
+ try {
+ context = context.createPackageContext(packageName, 0);
+ if (theme != context.getThemeResId()) {
context.setTheme(theme);
- } catch (PackageManager.NameNotFoundException e) {
- // Ignore
}
+ } catch (PackageManager.NameNotFoundException e) {
+ // Ignore
}
+ // Construct the Toast
+
Window win = PolicyManager.makeNewWindow(context);
final TypedArray ta = win.getWindowStyle();
if (ta.getBoolean(
@@ -1791,6 +2130,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final int flags = event.getFlags();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
+ final boolean longPress = (flags & KeyEvent.FLAG_LONG_PRESS) != 0;
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
@@ -1798,26 +2138,43 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ " canceled=" + canceled);
}
- // If we think we might have a volume down & power key chord on the way
+ // If we think we might have a volume down & power/volume-up key chord on the way
// but we're not sure, then tell the dispatcher to wait a little while and
// try again later before dispatching.
if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
- if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {
+ if (mVolumeDownKeyTriggered && !mPowerKeyTriggered && !mVolumeUpKeyTriggered) {
+ final long now = SystemClock.uptimeMillis();
+ final long timeoutTime = mVolumeDownKeyTime + ACTION_CHORD_DEBOUNCE_DELAY_MILLIS;
+ if (now < timeoutTime) {
+ return timeoutTime - now;
+ }
+ } else if (mVolumeUpKeyTriggered && !mVolumeDownKeyTriggered) {
final long now = SystemClock.uptimeMillis();
- final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
+ final long timeoutTime = mVolumeUpKeyTime + ACTION_CHORD_DEBOUNCE_DELAY_MILLIS;
if (now < timeoutTime) {
return timeoutTime - now;
}
}
+
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
- && mVolumeDownKeyConsumedByScreenshotChord) {
+ && mVolumeDownKeyConsumedByChord) {
if (!down) {
- mVolumeDownKeyConsumedByScreenshotChord = false;
+ mVolumeDownKeyConsumedByChord = false;
+ }
+ return -1;
+ } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ && mVolumeUpKeyConsumedByChord) {
+ if (!down) {
+ mVolumeUpKeyConsumedByChord = false;
}
return -1;
}
}
+ if (keyCode == KeyEvent.KEYCODE_BACK && !down) {
+ mHandler.removeCallbacks(mBackLongPress);
+ }
+
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
@@ -1826,44 +2183,36 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
- if (!down) {
+ if (!down && mHomePressed) {
final boolean homeWasLongPressed = mHomeLongPressed;
- mHomePressed = false;
mHomeLongPressed = false;
+ mHomePressed = false;
if (!homeWasLongPressed) {
- if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.cancelPreloadRecentApps();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when showing recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
- }
+ if (mRecentAppsPreloaded) {
+ cancelPreloadRecentApps();
}
-
mHomePressed = false;
if (!canceled) {
- // If an incoming call is ringing, HOME is totally disabled.
- // (The user is already on the InCallScreen at this point,
- // and his ONLY options are to answer or reject the call.)
boolean incomingRinging = false;
try {
ITelephony telephonyService = getTelephonyService();
if (telephonyService != null) {
incomingRinging = telephonyService.isRinging();
}
+ if (incomingRinging) {
+ if ((mRingHomeBehavior
+ & Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_ANSWER) != 0) {
+ Log.i(TAG, "Answering with HOME button.");
+ telephonyService.answerRingingCall();
+ } else {
+ Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
+ }
+ } else {
+ launchHomeFromHotKey();
+ }
} catch (RemoteException ex) {
Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
}
-
- if (incomingRinging) {
- Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
- } else {
- launchHomeFromHotKey();
- }
} else {
Log.i(TAG, "Ignoring HOME; event canceled.");
}
@@ -1890,23 +2239,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
if (down) {
- if (!mHomePressed && mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
- try {
- IStatusBarService statusbar = getStatusBarService();
- if (statusbar != null) {
- statusbar.preloadRecentApps();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when preloading recent apps", e);
- // re-acquire status bar service next time it is needed.
- mStatusBarService = null;
- }
+ if (!mRecentAppsPreloaded && mLongPressOnHomeBehavior == KEY_ACTION_APP_SWITCH) {
+ preloadRecentApps();
}
if (repeatCount == 0) {
mHomePressed = true;
- } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
- if (!keyguardOn) {
- handleLongPressOnHome();
+ } else if (longPress) {
+ if (!keyguardOn && mLongPressOnHomeBehavior != KEY_ACTION_NOTHING) {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ performKeyAction(mLongPressOnHomeBehavior);
+ // Eat the long-press so it won't take us home when the key is released
+ mHomeLongPressed = true;
}
}
}
@@ -1915,27 +2258,59 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON;
- if (down && repeatCount == 0) {
- if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
- Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
- mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
- null, null, null, 0, null, null);
- return -1;
- } else if (SHOW_PROCESSES_ON_ALT_MENU &&
- (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
- Intent service = new Intent();
- service.setClassName(mContext, "com.android.server.LoadAverageService");
- ContentResolver res = mContext.getContentResolver();
- boolean shown = Settings.Global.getInt(
- res, Settings.Global.SHOW_PROCESSES, 0) != 0;
- if (!shown) {
- mContext.startService(service);
- } else {
- mContext.stopService(service);
+ if (down) {
+ if (!mRecentAppsPreloaded && (mPressOnMenuBehavior == KEY_ACTION_APP_SWITCH ||
+ mLongPressOnMenuBehavior == KEY_ACTION_APP_SWITCH)) {
+ preloadRecentApps();
+ }
+ if (repeatCount == 0) {
+ if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
+ Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
+ mContext.sendOrderedBroadcast(intent, null);
+ return -1;
+ } else if (SHOW_PROCESSES_ON_ALT_MENU &&
+ (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
+ Intent service = new Intent();
+ service.setClassName(mContext, "com.android.server.LoadAverageService");
+ ContentResolver res = mContext.getContentResolver();
+ boolean shown = Settings.System.getInt(
+ res, Settings.System.SHOW_PROCESSES, 0) != 0;
+ if (!shown) {
+ mContext.startService(service);
+ } else {
+ mContext.stopService(service);
+ }
+ Settings.System.putInt(
+ res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1);
+ return -1;
+ } else if (mPressOnMenuBehavior != KEY_ACTION_MENU && !mIsVirtualKeypress) {
+ mMenuDoCustomAction = true;
+ return -1;
+ }
+ } else if (longPress) {
+ if (mRecentAppsPreloaded &&
+ mLongPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
+ cancelPreloadRecentApps();
+ }
+ if (!keyguardOn && mLongPressOnMenuBehavior != KEY_ACTION_NOTHING) {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ performKeyAction(mLongPressOnMenuBehavior);
+ // Do not perform action when key is released
+ mMenuDoCustomAction = false;
+ return -1;
+ }
+ }
+ } else {
+ if (mRecentAppsPreloaded && mPressOnMenuBehavior != KEY_ACTION_APP_SWITCH &&
+ mLongPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
+ cancelPreloadRecentApps();
+ }
+ if (mMenuDoCustomAction) {
+ mMenuDoCustomAction = false;
+ if (!canceled && !keyguardOn) {
+ performKeyAction(mPressOnMenuBehavior);
+ return -1;
}
- Settings.Global.putInt(
- res, Settings.Global.SHOW_PROCESSES, shown ? 0 : 1);
- return -1;
}
}
} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
@@ -1953,30 +2328,79 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
return 0;
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
- if (down && repeatCount == 0 && !keyguardOn) {
- showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
+ if (down) {
+ if (!mRecentAppsPreloaded && (mPressOnAppSwitchBehavior == KEY_ACTION_APP_SWITCH ||
+ mLongPressOnAppSwitchBehavior == KEY_ACTION_APP_SWITCH)) {
+ preloadRecentApps();
+ }
+ if (repeatCount == 0) {
+ mAppSwitchLongPressed = false;
+ } else if (longPress) {
+ if (mRecentAppsPreloaded &&
+ mLongPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
+ cancelPreloadRecentApps();
+ }
+ if (!keyguardOn && mLongPressOnAppSwitchBehavior != KEY_ACTION_NOTHING) {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ performKeyAction(mLongPressOnAppSwitchBehavior);
+ mAppSwitchLongPressed = true;
+ }
+ }
+ } else {
+ if (mAppSwitchLongPressed) {
+ mAppSwitchLongPressed = false;
+ } else {
+ if (mRecentAppsPreloaded &&
+ mPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
+ cancelPreloadRecentApps();
+ }
+ if (!canceled && !keyguardOn) {
+ performKeyAction(mPressOnAppSwitchBehavior);
+ }
+ return -1;
+ }
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
if (down) {
+ if (!mRecentAppsPreloaded && (mPressOnAssistBehavior == KEY_ACTION_APP_SWITCH ||
+ mLongPressOnAssistBehavior == KEY_ACTION_APP_SWITCH)) {
+ preloadRecentApps();
+ }
if (repeatCount == 0) {
mAssistKeyLongPressed = false;
- } else if (repeatCount == 1) {
- mAssistKeyLongPressed = true;
- if (!keyguardOn) {
- launchAssistLongPressAction();
+ } else if (longPress) {
+ if (mRecentAppsPreloaded &&
+ mLongPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
+ cancelPreloadRecentApps();
+ }
+ if (!keyguardOn && mLongPressOnAssistBehavior != KEY_ACTION_NOTHING) {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ performKeyAction(mLongPressOnAssistBehavior);
+ mAssistKeyLongPressed = true;
}
}
} else {
if (mAssistKeyLongPressed) {
mAssistKeyLongPressed = false;
} else {
+ if (mRecentAppsPreloaded &&
+ mPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
+ cancelPreloadRecentApps();
+ }
if (!keyguardOn) {
- launchAssistAction();
+ performKeyAction(mPressOnAssistBehavior);
}
}
}
return -1;
+ } else if (keyCode == KeyEvent.KEYCODE_BACK) {
+ if (Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.KILL_APP_LONGPRESS_BACK, 0) == 1) {
+ if (down && repeatCount == 0) {
+ mHandler.postDelayed(mBackLongPress, mBackKillTimeout);
+ }
+ }
}
// Shortcuts are invoked through Search+key, so intercept those here
@@ -2083,6 +2507,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return -1;
}
+ // Specific device key handling
+ if (mDeviceKeyHandler != null) {
+ try {
+ // The device only should consume known keys.
+ if (mDeviceKeyHandler.handleKeyEvent(event)) {
+ return -1;
+ }
+ } catch (Exception e) {
+ Slog.w(TAG, "Could not dispatch event to device key handler", e);
+ }
+ }
+
// Let the application handle the key.
return 0;
}
@@ -2168,7 +2604,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private void launchAssistLongPressAction() {
- performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
// launch the search activity
@@ -2432,6 +2867,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// decided that it can't be hidden (because of the screen aspect ratio),
// then take that into account.
navVisible |= !mCanHideNavigationBar;
+ navVisible &= (Settings.System.getInt(mContext.getContentResolver(), Settings.System.EXPANDED_DESKTOP_STATE, 0) == 0);
if (mNavigationBar != null) {
// Force the navigation bar to its appropriate place and
@@ -3048,7 +3484,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
// has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
// case though.
- if (topIsFullscreen) {
+ if (topIsFullscreen || (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1 &&
+ Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STYLE, 0) == 2)) {
if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
if (mStatusBar.hideLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT;
@@ -3351,7 +3790,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
- final int keyCode = event.getKeyCode();
+ int keyCode = event.getKeyCode();
final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
@@ -3367,8 +3806,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (keyCode == KeyEvent.KEYCODE_POWER) {
policyFlags |= WindowManagerPolicy.FLAG_WAKE;
}
- final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
- | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
+ final boolean isWakeKey = (policyFlags
+ & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTq keycode=" + keyCode
@@ -3402,7 +3841,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (keyguardActive) {
// If the keyguard is showing, let it wake the device when ready.
mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode);
- } else {
+ } else if ((keyCode != KeyEvent.KEYCODE_VOLUME_UP) && (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN)) {
// Otherwise, wake the device ourselves.
result |= ACTION_WAKE_UP;
}
@@ -3411,6 +3850,35 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Handle special keys.
switch (keyCode) {
+ case KeyEvent.KEYCODE_ENDCALL: {
+ result &= ~ACTION_PASS_TO_USER;
+ if (down) {
+ ITelephony telephonyService = getTelephonyService();
+ boolean hungUp = false;
+ if (telephonyService != null) {
+ try {
+ hungUp = telephonyService.endCall();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "ITelephony threw RemoteException", ex);
+ }
+ }
+ interceptPowerKeyDown(!isScreenOn || hungUp);
+ } else {
+ if (interceptPowerKeyUp(canceled)) {
+ if ((mEndcallBehavior
+ & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
+ if (goHome()) {
+ break;
+ }
+ }
+ if ((mEndcallBehavior
+ & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
+ result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
+ }
+ }
+ }
+ break;
+ }
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
@@ -3420,25 +3888,31 @@ public class PhoneWindowManager implements WindowManagerPolicy {
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
mVolumeDownKeyTriggered = true;
mVolumeDownKeyTime = event.getDownTime();
- mVolumeDownKeyConsumedByScreenshotChord = false;
+ mVolumeDownKeyConsumedByChord = false;
cancelPendingPowerKeyAction();
interceptScreenshotChord();
+ interceptRingerChord();
}
} else {
mVolumeDownKeyTriggered = false;
cancelPendingScreenshotChordAction();
+ cancelPendingRingerChordAction();
}
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
if (down) {
if (isScreenOn && !mVolumeUpKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
mVolumeUpKeyTriggered = true;
+ mVolumeUpKeyTime = event.getDownTime();
+ mVolumeUpKeyConsumedByChord = false;
cancelPendingPowerKeyAction();
cancelPendingScreenshotChordAction();
+ interceptRingerChord();
}
} else {
mVolumeUpKeyTriggered = false;
cancelPendingScreenshotChordAction();
+ cancelPendingRingerChordAction();
}
}
if (down) {
@@ -3475,54 +3949,52 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Log.w(TAG, "ITelephony threw RemoteException", ex);
}
}
-
- if (isMusicActive() && (result & ACTION_PASS_TO_USER) == 0) {
- // If music is playing but we decided not to pass the key to the
- // application, handle the volume change here.
- handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode);
- break;
- }
}
- break;
- }
-
- case KeyEvent.KEYCODE_ENDCALL: {
- result &= ~ACTION_PASS_TO_USER;
- if (down) {
- ITelephony telephonyService = getTelephonyService();
- boolean hungUp = false;
- if (telephonyService != null) {
- try {
- hungUp = telephonyService.endCall();
- } catch (RemoteException ex) {
- Log.w(TAG, "ITelephony threw RemoteException", ex);
- }
- }
- interceptPowerKeyDown(!isScreenOn || hungUp);
- } else {
- if (interceptPowerKeyUp(canceled)) {
- if ((mEndcallBehavior
- & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
- if (goHome()) {
+ if (isMusicActive() && (result & ACTION_PASS_TO_USER) == 0) {
+ if (mVolBtnMusicControls && down && (keyCode != KeyEvent.KEYCODE_VOLUME_MUTE)) {
+ mIsLongPress = false;
+ int newKeyCode = event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP ?
+ KeyEvent.KEYCODE_MEDIA_NEXT : KeyEvent.KEYCODE_MEDIA_PREVIOUS;
+ Message msg = mHandler.obtainMessage(MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK,
+ new KeyEvent(event.getDownTime(), event.getEventTime(), event.getAction(), newKeyCode, 0));
+ msg.setAsynchronous(true);
+ mHandler.sendMessageDelayed(msg, ViewConfiguration.getLongPressTimeout());
+ break;
+ } else {
+ if (mVolBtnMusicControls && !down) {
+ mHandler.removeMessages(MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK);
+ if (mIsLongPress) {
break;
}
}
- if ((mEndcallBehavior
- & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
- result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
+ if (!isScreenOn && !mVolumeWakeScreen) {
+ handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode);
}
}
}
- break;
+ if (isScreenOn || !mVolumeWakeScreen) {
+ break;
+ } else if (keyguardActive) {
+ keyCode = KeyEvent.KEYCODE_POWER;
+ mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode);
+ } else {
+ result |= ACTION_WAKE_UP;
+ break;
+ }
}
case KeyEvent.KEYCODE_POWER: {
+ if ((mTopFullscreenOpaqueWindowState.getAttrs().flags
+ & WindowManager.LayoutParams.PREVENT_POWER_KEY) != 0){
+ return result;
+ }
result &= ~ACTION_PASS_TO_USER;
if (down) {
if (isScreenOn && !mPowerKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
mPowerKeyTriggered = true;
mPowerKeyTime = event.getDownTime();
+ cancelPendingRingerChordAction();
interceptScreenshotChord();
}
@@ -3778,6 +4250,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
};
+ BroadcastReceiver mWifiDisplayReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_WIFI_DISPLAY_VIDEO)) {
+ int state = intent.getIntExtra("state", 0);
+ if(state == 1) {
+ mWifiDisplayConnected = true;
+ } else {
+ mWifiDisplayConnected = false;
+ }
+ updateRotation(true);
+ }
+ }
+ };
+
+ BroadcastReceiver mThemeChangeReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ };
@Override
public void screenTurnedOff(int why) {
@@ -3968,8 +4460,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
final int preferredRotation;
- if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
- // Ignore sensor when lid switch is open and rotation is forced.
+ if ((mLidState == LID_OPEN && mLidOpenRotation >= 0)
+ && !(mHasRemovableLid
+ && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED)) {
+ // Ignore sensor when lid switch is open and rotation is forced
+ // and a removable lid was not undocked.
preferredRotation = mLidOpenRotation;
} else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
&& (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
@@ -3987,9 +4482,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// enable 180 degree rotation while docked.
preferredRotation = mDeskDockEnablesAccelerometer
? sensorRotation : mDeskDockRotation;
- } else if (mHdmiPlugged && mHdmiRotationLock) {
+ } else if ((mHdmiPlugged || mWifiDisplayConnected) &&
+ mHdmiRotationLock) {
// Ignore sensor when plugged into HDMI.
- // Note that the dock orientation overrides the HDMI orientation.
+ // or Wifi display is connected
+ // Note that the dock orientation overrides the HDMI/Wifi
+ // orientation.
preferredRotation = mHdmiRotation;
} else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
&& (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
@@ -4007,9 +4505,30 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mAllowAllRotations = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
}
- if (sensorRotation != Surface.ROTATION_180
- || mAllowAllRotations == 1
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) {
+ // Rotation setting bitmask
+ // 1=0 2=90 4=180 8=270
+ boolean allowed = true;
+ if (mUserRotationAngles < 0) {
+ // Not set by user so use these defaults
+ mUserRotationAngles = mAllowAllRotations == 1 ?
+ (1 | 2 | 4 | 8) : // All angles
+ (1 | 2 | 8); // All except 180
+ }
+ switch (sensorRotation) {
+ case Surface.ROTATION_0:
+ allowed = (mUserRotationAngles & 1) != 0;
+ break;
+ case Surface.ROTATION_90:
+ allowed = (mUserRotationAngles & 2) != 0;
+ break;
+ case Surface.ROTATION_180:
+ allowed = (mUserRotationAngles & 4) != 0;
+ break;
+ case Surface.ROTATION_270:
+ allowed = (mUserRotationAngles & 8) != 0;
+ break;
+ }
+ if (allowed) {
preferredRotation = sensorRotation;
} else {
preferredRotation = lastRotation;
@@ -4327,6 +4846,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private void applyLidSwitchState() {
+ mPowerManager.setKeyboardVisibility(isBuiltInKeyboardVisible());
+
if (mLidState == LID_CLOSED && mLidControlsSleep) {
mPowerManager.goToSleep(SystemClock.uptimeMillis());
}
@@ -4700,6 +5221,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
pw.print(prefix); pw.print("mEndcallBehavior="); pw.print(mEndcallBehavior);
pw.print(" mIncallPowerBehavior="); pw.print(mIncallPowerBehavior);
+ pw.print(" mRingHomeBehavior="); pw.print(mRingHomeBehavior);
pw.print(" mLongPressOnHomeBehavior="); pw.println(mLongPressOnHomeBehavior);
pw.print(prefix); pw.print("mLandscapeRotation="); pw.print(mLandscapeRotation);
pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation);
diff --git a/policy/src/com/android/internal/policy/impl/Policy.java b/policy/src/com/android/internal/policy/impl/Policy.java
index 153ef0f..25d653f 100644
--- a/policy/src/com/android/internal/policy/impl/Policy.java
+++ b/policy/src/com/android/internal/policy/impl/Policy.java
@@ -23,6 +23,7 @@ import android.view.LayoutInflater;
import android.view.Window;
import android.view.WindowManagerPolicy;
+import com.android.internal.os.IDeviceHandler;
import com.android.internal.policy.IPolicy;
import com.android.internal.policy.impl.PhoneLayoutInflater;
import com.android.internal.policy.impl.PhoneWindow;
@@ -67,8 +68,8 @@ public class Policy implements IPolicy {
return new PhoneLayoutInflater(context);
}
- public WindowManagerPolicy makeNewWindowManager() {
- return new PhoneWindowManager();
+ public WindowManagerPolicy makeNewWindowManager(IDeviceHandler device) {
+ return new PhoneWindowManager(device);
}
public FallbackEventHandler makeNewFallbackEventHandler(Context context) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
index cc520dc..46dfc34 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
@@ -21,6 +21,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.CountDownTimer;
import android.os.SystemClock;
+import android.provider.Settings;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
@@ -47,6 +48,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
protected View mEcaView;
private Drawable mBouncerFrame;
protected boolean mEnableHaptics;
+ private boolean mQuickUnlock;
// To avoid accidental lockout due to events while the device in in the pocket, ignore
// any passwords with length less than or equal to this length.
@@ -111,6 +113,9 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
}
});
+ mQuickUnlock = (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_QUICK_UNLOCK_CONTROL, 0) == 1);
+
mPasswordEntry.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@@ -122,6 +127,14 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
if (mCallback != null) {
mCallback.userActivity(0);
}
+ if (mQuickUnlock) {
+ String entry = mPasswordEntry.getText().toString();
+ if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT &&
+ mLockPatternUtils.checkPassword(entry)) {
+ mCallback.reportSuccessfulUnlockAttempt();
+ mCallback.dismiss(true);
+ }
+ }
}
});
mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index b05d111..f11d444 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -20,6 +20,8 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AlertDialog;
+import android.app.Profile;
+import android.app.ProfileManager;
import android.app.SearchManager;
import android.app.admin.DevicePolicyManager;
import android.appwidget.AppWidgetHost;
@@ -30,10 +32,14 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
@@ -44,6 +50,7 @@ import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
+import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -68,7 +75,7 @@ public class KeyguardHostView extends KeyguardViewBase {
// Found in KeyguardAppWidgetPickActivity.java
static final int APPWIDGET_HOST_ID = 0x4B455947;
- private final int MAX_WIDGETS = 5;
+ private final int MAX_WIDGETS = 9;
private AppWidgetHost mAppWidgetHost;
private AppWidgetManager mAppWidgetManager;
@@ -76,6 +83,7 @@ public class KeyguardHostView extends KeyguardViewBase {
private KeyguardSecurityViewFlipper mSecurityViewContainer;
private KeyguardSelectorView mKeyguardSelectorView;
private KeyguardTransportControlView mTransportControl;
+ private View mExpandChallengeView;
private boolean mIsVerifyUnlockOnly;
private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
@@ -274,6 +282,7 @@ public class KeyguardHostView extends KeyguardViewBase {
setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
}
+ updateBackground();
addDefaultWidgets();
addWidgetsFromSettings();
@@ -287,6 +296,51 @@ public class KeyguardHostView extends KeyguardViewBase {
showPrimarySecurityScreen(false);
updateSecurityViews();
+
+ mExpandChallengeView = (View) findViewById(R.id.expand_challenge_handle);
+ if (mExpandChallengeView != null) {
+ mExpandChallengeView.setOnLongClickListener(mFastUnlockClickListener);
+ }
+
+ minimizeChallengeIfDesired();
+ }
+
+ private final OnLongClickListener mFastUnlockClickListener = new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (mLockPatternUtils.isTactileFeedbackEnabled()) {
+ v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ }
+ showNextSecurityScreenOrFinish(false);
+ return true;
+ }
+ };
+
+ private void updateBackground() {
+ String background = Settings.System.getStringForUser(getContext().getContentResolver(),
+ Settings.System.LOCKSCREEN_BACKGROUND, UserHandle.USER_CURRENT);
+
+ if (background == null) {
+ return;
+ }
+
+ if (!background.isEmpty()) {
+ try {
+ setBackgroundColor(Integer.parseInt(background));
+ } catch(NumberFormatException e) {
+ Log.e(TAG, "Invalid background color " + background);
+ }
+ } else {
+ try {
+ Context settingsContext = getContext().createPackageContext("com.android.settings", 0);
+ String wallpaperFile = settingsContext.getFilesDir() + "/lockwallpaper";
+ Bitmap backgroundBitmap = BitmapFactory.decodeFile(wallpaperFile);
+ setBackgroundDrawable(new BitmapDrawable(backgroundBitmap));
+ } catch (NameNotFoundException e) {
+ // Do nothing here
+ }
+ }
}
private boolean shouldEnableAddWidget() {
@@ -882,6 +936,7 @@ public class KeyguardHostView extends KeyguardViewBase {
if (mViewStateManager != null) {
mViewStateManager.showUsabilityHints();
}
+ minimizeChallengeIfDesired();
requestFocus();
}
@@ -915,29 +970,11 @@ public class KeyguardHostView extends KeyguardViewBase {
showPrimarySecurityScreen(false);
}
- private boolean isSecure() {
- SecurityMode mode = mSecurityModel.getSecurityMode();
- switch (mode) {
- case Pattern:
- return mLockPatternUtils.isLockPatternEnabled();
- case Password:
- case PIN:
- return mLockPatternUtils.isLockPasswordEnabled();
- case SimPin:
- case SimPuk:
- case Account:
- return true;
- case None:
- return false;
- default:
- throw new IllegalStateException("Unknown security mode " + mode);
- }
- }
@Override
public void wakeWhenReadyTq(int keyCode) {
if (DEBUG) Log.d(TAG, "onWakeKey");
- if (keyCode == KeyEvent.KEYCODE_MENU && isSecure()) {
+ if (keyCode == KeyEvent.KEYCODE_MENU && mSecurityModel.getSecurityMode() != SecurityMode.None) {
if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
showSecurityScreen(SecurityMode.None);
} else {
@@ -969,6 +1006,19 @@ public class KeyguardHostView extends KeyguardViewBase {
}
}
+ private void minimizeChallengeIfDesired() {
+ if (mSlidingChallengeLayout == null) {
+ return;
+ }
+
+ int setting = Settings.System.getIntForUser(getContext().getContentResolver(),
+ Settings.System.LOCKSCREEN_MAXIMIZE_WIDGETS, 0, UserHandle.USER_CURRENT);
+
+ if (setting == 1) {
+ mSlidingChallengeLayout.showChallenge(false);
+ }
+ }
+
private int getSecurityViewIdForMode(SecurityMode securityMode) {
switch (securityMode) {
case None: return R.id.keyguard_selector_view;
@@ -1513,10 +1563,14 @@ public class KeyguardHostView extends KeyguardViewBase {
com.android.internal.R.bool.config_disableMenuKeyInLockScreen);
final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
- return !configDisabled || isTestHarness || fileOverride;
+ final boolean menuOverride = Settings.System.getInt(getContext().getContentResolver(), Settings.System.MENU_UNLOCK_SCREEN, 0) == 1;
+ return !configDisabled || isTestHarness || fileOverride || menuOverride;
}
-
+ private boolean shouldEnableHomeKey() {
+ final boolean homeOverride = Settings.System.getInt(getContext().getContentResolver(), Settings.System.HOME_UNLOCK_SCREEN, 0) == 1;
+ return homeOverride;
+ }
public void goToUserSwitcher() {
mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_multi_user_selector));
@@ -1536,6 +1590,15 @@ public class KeyguardHostView extends KeyguardViewBase {
return false;
}
+ public boolean handleHomeKey() {
+ // The following enables the HOME key to work for testing automation
+ if (shouldEnableHomeKey()) {
+ showNextSecurityScreenOrFinish(false);
+ return true;
+ }
+ return false;
+ }
+
public boolean handleBackKey() {
if (mCurrentSecuritySelection != SecurityMode.None) {
mCallback.dismiss(false);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
index 210312a..c4628c0 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
@@ -41,6 +41,7 @@ import com.android.internal.R;
class KeyguardMessageArea extends TextView {
static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
+ static final int DISCHARGING_ICON = 0; // no icon used in ics+ currently
static final int SECURITY_MESSAGE_DURATION = 5000;
protected static final int FADE_DURATION = 750;
@@ -48,6 +49,9 @@ class KeyguardMessageArea extends TextView {
// are we showing battery information?
boolean mShowingBatteryInfo = false;
+ // always show battery status?
+ boolean mAlwaysShowBattery = false;
+
// is the bouncer up?
boolean mShowingBouncer = false;
@@ -134,12 +138,13 @@ class KeyguardMessageArea extends TextView {
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
- mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow();
mCharging = status.status == BatteryManager.BATTERY_STATUS_CHARGING
|| status.status == BatteryManager.BATTERY_STATUS_FULL;
mBatteryLevel = status.level;
mBatteryCharged = status.isCharged();
mBatteryIsLow = status.isBatteryLow();
+ mAlwaysShowBattery = KeyguardUpdateMonitor.shouldAlwaysShowBatteryInfo(getContext());
+ mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow() || mAlwaysShowBattery;
update();
}
};
@@ -234,9 +239,13 @@ class KeyguardMessageArea extends TextView {
} else if (mBatteryIsLow) {
// Battery is low
string = getContext().getString(
- com.android.internal.R.string.lockscreen_low_battery);
+ com.android.internal.R.string.lockscreen_low_battery, mBatteryLevel);
icon.value = BATTERY_LOW_ICON;
- }
+ } else if (mAlwaysShowBattery) {
+ // Discharging
+ string = getContext().getString(R.string.lockscreen_discharging, mBatteryLevel);
+ icon.value = DISCHARGING_ICON;
+ }
}
return string;
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
index e114b78..8f4414e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -121,6 +121,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
mLockPatternView.setSaveEnabled(false);
mLockPatternView.setFocusable(false);
mLockPatternView.setOnPatternListener(new UnlockPatternListener());
+ mLockPatternView.setLockPatternUtils(mLockPatternUtils);
// stealth mode will be the same for the life of this screen
mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
@@ -128,6 +129,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
// vibrate mode will be the same for the life of this screen
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
+ mLockPatternView.setLockPatternSize(mLockPatternUtils.getLockPatternSize());
+
mForgotPatternButton = (Button) findViewById(R.id.forgot_password_button);
// note: some configurations don't have an emergency call area
if (mForgotPatternButton != null) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
index 7a69586..6ede504 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.policy.impl.keyguard;
+import android.app.Profile;
+import android.app.ProfileManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.telephony.TelephonyManager;
@@ -42,9 +44,13 @@ public class KeyguardSecurityModel {
private Context mContext;
private LockPatternUtils mLockPatternUtils;
+ // We can use the profile manager to override security
+ private ProfileManager mProfileManager;
+
KeyguardSecurityModel(Context context) {
mContext = context;
mLockPatternUtils = new LockPatternUtils(context);
+ mProfileManager = (ProfileManager) context.getSystemService(Context.PROFILE_SERVICE);
}
void setLockPatternUtils(LockPatternUtils utils) {
@@ -82,18 +88,21 @@ public class KeyguardSecurityModel {
} else if (simState == IccCardConstants.State.PUK_REQUIRED
&& mLockPatternUtils.isPukUnlockScreenEnable()) {
mode = SecurityMode.SimPuk;
- } else {
+ } else if (mProfileManager.getActiveProfile().getScreenLockMode() != Profile.LockMode.INSECURE) {
final int security = mLockPatternUtils.getKeyguardStoredPasswordQuality();
switch (security) {
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- mode = mLockPatternUtils.isLockPasswordEnabled() ?
- SecurityMode.PIN : SecurityMode.None;
+ if (mLockPatternUtils.isLockPasswordEnabled()) {
+ mode = SecurityMode.PIN;
+ }
break;
+
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
- mode = mLockPatternUtils.isLockPasswordEnabled() ?
- SecurityMode.Password : SecurityMode.None;
+ if (mLockPatternUtils.isLockPasswordEnabled()) {
+ mode = SecurityMode.Password;
+ }
break;
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
@@ -105,7 +114,7 @@ public class KeyguardSecurityModel {
break;
default:
- throw new IllegalStateException("Unknown unlock mode:" + mode);
+ throw new IllegalStateException("Unknown unlock mode:" + security);
}
}
return mode;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index 76cbbd5..e92ab9f 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -15,13 +15,28 @@
*/
package com.android.internal.policy.impl.keyguard;
+import java.io.File;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
import android.animation.ObjectAnimator;
import android.app.SearchManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.StateListDrawable;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
@@ -35,6 +50,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.multiwaveview.GlowPadView;
import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
import com.android.internal.R;
+import com.android.internal.widget.multiwaveview.TargetDrawable;
public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView {
private static final boolean DEBUG = KeyguardHostView.DEBUG;
@@ -52,16 +68,21 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
private LockPatternUtils mLockPatternUtils;
private SecurityMessageDisplay mSecurityMessageDisplay;
private Drawable mBouncerFrame;
+ private String[] mStoredTargets;
+ private int mTargetOffset;
+ private boolean mIsScreenLarge;
+ private int mCreationOrientation;
OnTriggerListener mOnTriggerListener = new OnTriggerListener() {
public void onTrigger(View v, int target) {
- final int resId = mGlowPadView.getResourceIdForTarget(target);
- switch (resId) {
+ if (mStoredTargets == null) {
+ final int resId = mGlowPadView.getResourceIdForTarget(target);
+ switch (resId) {
case com.android.internal.R.drawable.ic_action_assist_generic:
Intent assistIntent =
- ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (assistIntent != null) {
mActivityLauncher.launchActivity(assistIntent, false, true, null, null);
} else {
@@ -79,7 +100,27 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
case com.android.internal.R.drawable.ic_lockscreen_unlock:
mCallback.userActivity(0);
mCallback.dismiss(false);
- break;
+ break;
+ }
+ } else {
+ final boolean isLand = mCreationOrientation == Configuration.ORIENTATION_LANDSCAPE;
+ if ((target == 0 && (mIsScreenLarge || !isLand)) || (target == 2 && !mIsScreenLarge && isLand)) {
+ mCallback.dismiss(false);
+ } else {
+ target -= 1 + mTargetOffset;
+ if (target < mStoredTargets.length && mStoredTargets[target] != null) {
+ if (mStoredTargets[target].equals(GlowPadView.EMPTY_TARGET)) {
+ mCallback.dismiss(false);
+ } else {
+ try {
+ Intent launchIntent = Intent.parseUri(mStoredTargets[target], 0);
+ mActivityLauncher.launchActivity(launchIntent, false, true, null, null);
+ return;
+ } catch (URISyntaxException e) {
+ }
+ }
+ }
+ }
}
}
@@ -136,6 +177,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
public KeyguardSelectorView(Context context) {
this(context, null);
+ mCreationOrientation = Resources.getSystem().getConfiguration().orientation;
}
public KeyguardSelectorView(Context context, AttributeSet attrs) {
@@ -159,6 +201,35 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
mFadeView = carrierArea;
}
+ public boolean isScreenLarge() {
+ final int screenSize = Resources.getSystem().getConfiguration().screenLayout &
+ Configuration.SCREENLAYOUT_SIZE_MASK;
+ boolean isScreenLarge = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||
+ screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;
+ return isScreenLarge;
+ }
+
+ private StateListDrawable getLayeredDrawable(Drawable back, Drawable front, int inset, boolean frontBlank) {
+ Resources res = getResources();
+ InsetDrawable[] inactivelayer = new InsetDrawable[2];
+ InsetDrawable[] activelayer = new InsetDrawable[2];
+ inactivelayer[0] = new InsetDrawable(res.getDrawable(com.android.internal.R.drawable.ic_lockscreen_lock_pressed), 0, 0, 0, 0);
+ inactivelayer[1] = new InsetDrawable(front, inset, inset, inset, inset);
+ activelayer[0] = new InsetDrawable(back, 0, 0, 0, 0);
+ activelayer[1] = new InsetDrawable(frontBlank ? res.getDrawable(android.R.color.transparent) : front, inset, inset, inset, inset);
+ StateListDrawable states = new StateListDrawable();
+ LayerDrawable inactiveLayerDrawable = new LayerDrawable(inactivelayer);
+ inactiveLayerDrawable.setId(0, 0);
+ inactiveLayerDrawable.setId(1, 1);
+ LayerDrawable activeLayerDrawable = new LayerDrawable(activelayer);
+ activeLayerDrawable.setId(0, 0);
+ activeLayerDrawable.setId(1, 1);
+ states.addState(TargetDrawable.STATE_INACTIVE, inactiveLayerDrawable);
+ states.addState(TargetDrawable.STATE_ACTIVE, activeLayerDrawable);
+ states.addState(TargetDrawable.STATE_FOCUSED, activeLayerDrawable);
+ return states;
+ }
+
public boolean isTargetPresent(int resId) {
return mGlowPadView.getTargetPosition(resId) != -1;
}
@@ -178,8 +249,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
|| secureCameraDisabled;
final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
boolean disabledBySimState = monitor.isSimLocked();
- boolean cameraTargetPresent =
- isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_camera);
+ boolean cameraPresent = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
boolean searchTargetPresent =
isTargetPresent(com.android.internal.R.drawable.ic_action_assist_generic);
@@ -196,7 +266,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
boolean searchActionAvailable =
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
.getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
- mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
+ mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraPresent
|| !currentUserSetup;
mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
|| !currentUserSetup;
@@ -204,31 +274,132 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
}
public void updateResources() {
- // Update the search icon with drawable from the search .apk
- if (!mSearchDisabled) {
- Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
- if (intent != null) {
- // XXX Hack. We need to substitute the icon here but haven't formalized
- // the public API. The "_google" metadata will be going away, so
- // DON'T USE IT!
- ComponentName component = intent.getComponent();
- boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
- ASSIST_ICON_METADATA_NAME + "_google",
- com.android.internal.R.drawable.ic_action_assist_generic);
-
- if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
- ASSIST_ICON_METADATA_NAME,
- com.android.internal.R.drawable.ic_action_assist_generic)) {
- Slog.w(TAG, "Couldn't grab icon from package " + component);
+ String storedVal = Settings.System.getStringForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_TARGETS, UserHandle.USER_CURRENT);
+ if (storedVal == null) {
+ // Update the search icon with drawable from the search .apk
+ if (!mSearchDisabled) {
+ Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ if (intent != null) {
+ // XXX Hack. We need to substitute the icon here but haven't formalized
+ // the public API. The "_google" metadata will be going away, so
+ // DON'T USE IT!
+ ComponentName component = intent.getComponent();
+ boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
+ ASSIST_ICON_METADATA_NAME + "_google",
+ com.android.internal.R.drawable.ic_action_assist_generic);
+
+ if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
+ ASSIST_ICON_METADATA_NAME,
+ com.android.internal.R.drawable.ic_action_assist_generic)) {
+ Slog.w(TAG, "Couldn't grab icon from package " + component);
+ }
}
}
- }
- mGlowPadView.setEnableTarget(com.android.internal.R.drawable
- .ic_lockscreen_camera, !mCameraDisabled);
- mGlowPadView.setEnableTarget(com.android.internal.R.drawable
- .ic_action_assist_generic, !mSearchDisabled);
+ mGlowPadView.setEnableTarget(com.android.internal.R.drawable
+ .ic_lockscreen_camera, !mCameraDisabled);
+ mGlowPadView.setEnableTarget(com.android.internal.R.drawable
+ .ic_action_assist_generic, !mSearchDisabled);
+ } else {
+ mStoredTargets = storedVal.split("\\|");
+ mIsScreenLarge = isScreenLarge();
+ ArrayList<TargetDrawable> storedDraw = new ArrayList<TargetDrawable>();
+ final Resources res = getResources();
+ final int targetInset = res.getDimensionPixelSize(com.android.internal.R.dimen.lockscreen_target_inset);
+ final PackageManager packMan = mContext.getPackageManager();
+ final boolean isLandscape = mCreationOrientation == Configuration.ORIENTATION_LANDSCAPE;
+ final Drawable blankActiveDrawable = res.getDrawable(R.drawable.ic_lockscreen_target_activated);
+ final InsetDrawable activeBack = new InsetDrawable(blankActiveDrawable, 0, 0, 0, 0);
+ //Magnetic target replacement
+ final Drawable blankInActiveDrawable = res.getDrawable(com.android.internal.R.drawable.ic_lockscreen_lock_pressed);
+ final Drawable unlockActiveDrawable = res.getDrawable(com.android.internal.R.drawable.ic_lockscreen_unlock_activated);
+ // Shift targets for landscape lockscreen on phones
+ mTargetOffset = isLandscape && !mIsScreenLarge ? 2 : 0;
+ if (mTargetOffset == 2) {
+ storedDraw.add(new TargetDrawable(res, null));
+ storedDraw.add(new TargetDrawable(res, null));
+ }
+ // Add unlock target
+ storedDraw.add(new TargetDrawable(res, res.getDrawable(R.drawable.ic_lockscreen_unlock)));
+ for (int i = 0; i < 8 - mTargetOffset - 1; i++) {
+ int tmpInset = targetInset;
+ if (i < mStoredTargets.length) {
+ String uri = mStoredTargets[i];
+ if (!uri.equals(GlowPadView.EMPTY_TARGET)) {
+ try {
+ Intent in = Intent.parseUri(uri,0);
+ Drawable front = null;
+ Drawable back = activeBack;
+ boolean frontBlank = false;
+ if (in.hasExtra(GlowPadView.ICON_FILE)) {
+ String fSource = in.getStringExtra(GlowPadView.ICON_FILE);
+ if (fSource != null) {
+ File fPath = new File(fSource);
+ if (fPath.exists()) {
+ front = new BitmapDrawable(res, BitmapFactory.decodeFile(fSource));
+ }
+ }
+ } else if (in.hasExtra(GlowPadView.ICON_RESOURCE)) {
+ String rSource = in.getStringExtra(GlowPadView.ICON_RESOURCE);
+ String rPackage = in.getStringExtra(GlowPadView.ICON_PACKAGE);
+ if (rSource != null) {
+ if (rPackage != null) {
+ try {
+ Context rContext = mContext.createPackageContext(rPackage, 0);
+ int id = rContext.getResources().getIdentifier(rSource, "drawable", rPackage);
+ front = rContext.getResources().getDrawable(id);
+ id = rContext.getResources().getIdentifier(rSource.replaceAll("_normal", "_activated"),
+ "drawable", rPackage);
+ back = rContext.getResources().getDrawable(id);
+ tmpInset = 0;
+ frontBlank = true;
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ } else {
+ front = res.getDrawable(res.getIdentifier(rSource, "drawable", "android"));
+ back = res.getDrawable(res.getIdentifier(
+ rSource.replaceAll("_normal", "_activated"), "drawable", "android"));
+ tmpInset = 0;
+ frontBlank = true;
+ }
+ }
+ }
+ if (front == null || back == null) {
+ ActivityInfo aInfo = in.resolveActivityInfo(packMan, PackageManager.GET_ACTIVITIES);
+ if (aInfo != null) {
+ front = aInfo.loadIcon(packMan);
+ } else {
+ front = res.getDrawable(android.R.drawable.sym_def_app_icon);
+ }
+ }
+ TargetDrawable nDrawable = new TargetDrawable(res, getLayeredDrawable(back,front, tmpInset, frontBlank));
+ ComponentName compName = in.getComponent();
+ if (compName != null) {
+ String cls = compName.getClassName();
+ if (cls.equals("com.android.camera.CameraLauncher")) {
+ nDrawable.setEnabled(!mCameraDisabled);
+ } else if (cls.equals("SearchActivity")) {
+ nDrawable.setEnabled(!mSearchDisabled);
+ }
+ }
+ storedDraw.add(nDrawable);
+ } catch (Exception e) {
+ storedDraw.add(new TargetDrawable(res, 0));
+ }
+ } else {
+ storedDraw.add(new TargetDrawable(res, getLayeredDrawable(unlockActiveDrawable, blankInActiveDrawable, tmpInset, true)));
+ }
+ } else {
+ storedDraw.add(new TargetDrawable(res, 0));
+ }
+ }
+ mGlowPadView.setTargetResources(storedDraw);
+ }
}
void doTransition(View view, float to) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
index 35b8509..c993f33 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
@@ -39,6 +39,7 @@ public class KeyguardStatusView extends GridLayout {
public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
public static final int ALARM_ICON = com.android.internal.R.drawable.ic_lock_idle_alarm;
public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
+ public static final int DISCHARGING_ICON = 0; // no icon used in ics+ currently
public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
private CharSequence mDateFormatString;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index ad6f55c..d446646 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -536,7 +536,7 @@ public class KeyguardUpdateMonitor {
*/
private void handleBatteryUpdate(BatteryStatus status) {
if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
- final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
+ final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status, mContext);
mBatteryStatus = status;
if (batteryUpdateInteresting) {
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -617,7 +617,7 @@ public class KeyguardUpdateMonitor {
return mKeyguardIsVisible;
}
- private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
+ private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current, Context context) {
final boolean nowPluggedIn = current.isPluggedIn();
final boolean wasPluggedIn = old.isPluggedIn();
final boolean stateChangedWhilePluggedIn =
@@ -634,13 +634,19 @@ public class KeyguardUpdateMonitor {
return true;
}
- // change where battery needs charging
- if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
+ // change in battery level while plugged in or always interested
+ if ((nowPluggedIn || shouldAlwaysShowBatteryInfo(context) || current.isBatteryLow()) && old.level != current.level) {
return true;
}
+
return false;
}
+ public static boolean shouldAlwaysShowBatteryInfo(Context context) {
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.LOCKSCREEN_ALWAYS_SHOW_BATTERY, 0) == 1;
+ }
+
/**
* @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
* @return The string to use for the plmn, or null if it should not be shown.
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index b6cf4da..b8f3c10 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -20,15 +20,20 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.appwidget.AppWidgetManager;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PixelFormat;
+import android.media.AudioManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.Vibrator;
+import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -70,6 +75,8 @@ public class KeyguardViewManager {
private boolean mScreenOn = false;
private LockPatternUtils mLockPatternUtils;
+ private boolean mUnlockKeyDown = false;
+
public interface ShowListener {
void onShown(IBinder windowToken);
};
@@ -154,22 +161,148 @@ public class KeyguardViewManager {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (mKeyguardView != null) {
- // Always process back and menu keys, regardless of focus
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- int keyCode = event.getKeyCode();
- if (keyCode == KeyEvent.KEYCODE_BACK && mKeyguardView.handleBackKey()) {
+ int keyCode = event.getKeyCode();
+ int action = event.getAction();
+
+ if (action == KeyEvent.ACTION_DOWN) {
+ if (handleKeyDown(keyCode, event)) {
return true;
- } else if (keyCode == KeyEvent.KEYCODE_MENU && mKeyguardView.handleMenuKey()) {
+ }
+ } else if (action == KeyEvent.ACTION_UP) {
+ if (handleKeyUp(keyCode, event)) {
return true;
}
}
- // Always process media keys, regardless of focus
- if (mKeyguardView.dispatchKeyEvent(event)) {
+ }
+ return super.dispatchKeyEvent(event);
+ }
+ }
+
+ public boolean handleKeyDown(int keyCode, KeyEvent event) {
+ if (event.getRepeatCount() == 0) {
+ mUnlockKeyDown = true;
+ }
+ if (event.isLongPress()) {
+ String action = null;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ action = Settings.System.LOCKSCREEN_LONG_BACK_ACTION;
+ break;
+ case KeyEvent.KEYCODE_HOME:
+ action = Settings.System.LOCKSCREEN_LONG_HOME_ACTION;
+ break;
+ case KeyEvent.KEYCODE_MENU:
+ action = Settings.System.LOCKSCREEN_LONG_MENU_ACTION;
+ break;
+ }
+
+ if (action != null) {
+ mUnlockKeyDown = false;
+ String uri = Settings.System.getString(mContext.getContentResolver(), action);
+ if (uri != null && runAction(mContext, uri)) {
+ long[] pattern = getLongPressVibePattern(mContext);
+ if (pattern != null) {
+ Vibrator v = (Vibrator) mContext.getSystemService(mContext.VIBRATOR_SERVICE);
+ if (pattern.length == 1) {
+ v.vibrate(pattern[0]);
+ } else {
+ v.vibrate(pattern, -1);
+ }
+ }
return true;
}
}
- return super.dispatchKeyEvent(event);
}
+ return false;
+ }
+
+ public boolean handleKeyUp(int keyCode, KeyEvent event) {
+ if (mUnlockKeyDown) {
+ mUnlockKeyDown = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ if (mKeyguardView.handleBackKey()) {
+ return true;
+ }
+ case KeyEvent.KEYCODE_HOME:
+ if (mKeyguardView.handleHomeKey()) {
+ return true;
+ }
+ case KeyEvent.KEYCODE_MENU:
+ if (mKeyguardView.handleMenuKey()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean runAction(Context context, String uri) {
+ if ("FLASHLIGHT".equals(uri)) {
+ context.sendBroadcast(new Intent("net.cactii.flash2.TOGGLE_FLASHLIGHT"));
+ return true;
+ } else if ("NEXT".equals(uri)) {
+ sendMediaButtonEvent(context, KeyEvent.KEYCODE_MEDIA_NEXT);
+ return true;
+ } else if ("PREVIOUS".equals(uri)) {
+ sendMediaButtonEvent(context, KeyEvent.KEYCODE_MEDIA_PREVIOUS);
+ return true;
+ } else if ("PLAYPAUSE".equals(uri)) {
+ sendMediaButtonEvent(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ return true;
+ } else if ("SOUND".equals(uri)) {
+ toggleSilentMode(context);
+ return true;
+ }
+
+ return false;
+ }
+
+ private static void sendMediaButtonEvent(Context context, int code) {
+ long eventtime = SystemClock.uptimeMillis();
+
+ Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+ KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, code, 0);
+ downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
+ context.sendOrderedBroadcast(downIntent, null);
+
+ Intent upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+ KeyEvent upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, code, 0);
+ upIntent.putExtra(Intent.EXTRA_KEY_EVENT, upEvent);
+ context.sendOrderedBroadcast(upIntent, null);
+ }
+
+ private static void toggleSilentMode(Context context) {
+ final AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ final Vibrator vib = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ final boolean hasVib = vib == null ? false : vib.hasVibrator();
+ if (am.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
+ am.setRingerMode(hasVib
+ ? AudioManager.RINGER_MODE_VIBRATE
+ : AudioManager.RINGER_MODE_SILENT);
+ } else {
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ }
+ }
+
+ private static long[] getLongPressVibePattern(Context context) {
+ if (Settings.System.getInt(context.getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0) {
+ return null;
+ }
+
+ int[] defaultPattern = context.getResources().getIntArray(
+ com.android.internal.R.array.config_longPressVibePattern);
+ if (defaultPattern == null) {
+ return null;
+ }
+
+ long[] pattern = new long[defaultPattern.length];
+ for (int i = 0; i < defaultPattern.length; i++) {
+ pattern[i] = defaultPattern[i];
+ }
+
+ return pattern;
}
SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 7d757ff..a39b2f7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -22,6 +22,8 @@ import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.PendingIntent;
+import android.app.Profile;
+import android.app.ProfileManager;
import android.app.SearchManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
@@ -247,6 +249,10 @@ public class KeyguardViewMediator {
private int mUnlockSoundId;
private int mLockSoundStreamId;
+ private ProfileManager mProfileManager;
+
+ private int mSlideLockDelay;
+
/**
* The volume applied to the lock/unlock sounds.
*/
@@ -495,6 +501,8 @@ public class KeyguardViewMediator {
mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
mLockPatternUtils);
+ mProfileManager = (ProfileManager) context.getSystemService(Context.PROFILE_SERVICE);
+
mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);
mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
| Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -567,15 +575,26 @@ public class KeyguardViewMediator {
public void onScreenTurnedOff(int why) {
synchronized (this) {
mScreenOn = false;
+ mSlideLockDelay = why;
if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")");
mKeyguardDonePending = false;
- // Lock immediately based on setting if secure (user has a pin/pattern/password).
- // This also "locks" the device when not secure to provide easy access to the
- // camera while preventing unwanted input.
- final boolean lockImmediately =
- mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
+ // Prepare for handling Lock/Slide lock delay and timeout
+ boolean lockImmediately = false;
+ final ContentResolver cr = mContext.getContentResolver();
+ boolean separateSlideLockTimeoutEnabled = Settings.System.getInt(cr,
+ Settings.System.SCREEN_LOCK_SLIDE_DELAY_TOGGLE, 0) == 1;
+ if (mLockPatternUtils.isSecure()) {
+ // Lock immediately based on setting if secure (user has a pin/pattern/password)
+ // This is retained as-is to ensue AOSP security integrity is maintained
+ lockImmediately = mLockPatternUtils.getPowerButtonInstantlyLocks();
+ } else {
+ // Unless a separate slide lock timeout is enabled, this "locks" the device when
+ // not secure to provide easy access to the camera while preventing unwanted input
+ lockImmediately = separateSlideLockTimeoutEnabled ? false
+ : mLockPatternUtils.getPowerButtonInstantlyLocks();
+ }
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
@@ -615,6 +634,18 @@ public class KeyguardViewMediator {
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
+ // From CyanogenMod specific Settings
+ // If utilizing a secured lock screen, we should not utilize the slide
+ // delay and should let it default to the standard delay
+ boolean separateSlideLockTimeoutEnabled = (mLockPatternUtils.isSecure() ? false
+ : Settings.System.getInt(cr,
+ Settings.System.SCREEN_LOCK_SLIDE_DELAY_TOGGLE, 0) == 1);
+
+ int slideLockTimeoutDelay = (mSlideLockDelay == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT ? Settings.System
+ .getInt(cr, Settings.System.SCREEN_LOCK_SLIDE_TIMEOUT_DELAY,
+ KEYGUARD_LOCK_AFTER_DELAY_DEFAULT) : Settings.System.getInt(cr,
+ Settings.System.SCREEN_LOCK_SLIDE_SCREENOFF_DELAY, 0));
+
// From DevicePolicyAdmin
final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
.getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser());
@@ -625,7 +656,7 @@ public class KeyguardViewMediator {
displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
} else {
- timeout = lockAfterTimeout;
+ timeout = separateSlideLockTimeoutEnabled ? slideLockTimeoutDelay : lockAfterTimeout;
}
if (timeout <= 0) {
@@ -889,6 +920,16 @@ public class KeyguardViewMediator {
return;
}
+ // if the current profile has disabled us, don't show
+ Profile profile = mProfileManager.getActiveProfile();
+ if (profile != null) {
+ if (!lockedOrMissing
+ && profile.getScreenLockMode() == Profile.LockMode.DISABLE) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because of profile override");
+ return;
+ }
+ }
+
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
showLocked(options);
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index b4fe0c7..db87a291 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -51,6 +51,11 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
protected static float OVERSCROLL_MAX_ROTATION = 30;
private static final boolean PERFORM_OVERSCROLL_ROTATION = true;
+ private static final String[] CLOCK_WIDGET_PACKAGES = new String[] {
+ "com.cyanogenmod.lockclock",
+ "com.android.deskclock"
+ };
+
protected KeyguardViewStateManager mViewStateManager;
private LockPatternUtils mLockPatternUtils;
@@ -136,6 +141,16 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
ViewGroup vg = (ViewGroup) newPage;
if (vg.getChildAt(0) instanceof KeyguardStatusView) {
showingStatusWidget = true;
+ } else if (vg.getChildAt(0) instanceof AppWidgetHostView) {
+ AppWidgetProviderInfo info =
+ ((AppWidgetHostView) vg.getChildAt(0)).getAppWidgetInfo();
+ String widgetPackage = info.provider.getPackageName();
+ for (String packageName : CLOCK_WIDGET_PACKAGES) {
+ if (packageName.equals(widgetPackage)) {
+ showingStatusWidget = true;
+ break;
+ }
+ }
}
}
@@ -498,7 +513,8 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
protected void screenScrolled(int screenCenter) {
mScreenCenter = screenCenter;
updatePageAlphaValues(screenCenter);
- for (int i = 0; i < getChildCount(); i++) {
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
KeyguardWidgetFrame v = getWidgetPageAt(i);
if (v == mDragView) continue;
if (v != null) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/PatternUnlockScreen.java
index 6d5706b..1d94f01 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/PatternUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/PatternUnlockScreen.java
@@ -346,7 +346,7 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
mKeyguardStatusViewManager.updateStatusLines(true);
mCallback.keyguardDone(true);
mCallback.reportSuccessfulUnlockAttempt();
- KeyStore.getInstance().password(LockPatternUtils.patternToString(pattern));
+ KeyStore.getInstance().password(mLockPatternUtils.patternToString(pattern));
} else {
boolean reportFailedAttempt = false;
if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
diff --git a/services/input/Android.mk b/services/input/Android.mk
index 159800f..b6fe44f 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -40,6 +40,14 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES := \
external/skia/include/core
+ifeq ($(BOARD_USE_LEGACY_TOUCHSCREEN),true)
+LOCAL_CFLAGS += -DLEGACY_TOUCHSCREEN
+endif
+
+ifeq ($(BOARD_USE_LEGACY_TRACKPAD),true)
+LOCAL_CFLAGS += -DLEGACY_TRACKPAD
+endif
+
LOCAL_MODULE:= libinput
LOCAL_MODULE_TAGS := optional
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index bc8df18..baba77d 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -972,6 +972,7 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) {
ALOGD("Dropped input event while waiting for next input sync.");
#endif
}
+
} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
ALOGI("Detected input event buffer overrun for device %s.", getName().string());
mDropUntilNextSync = true;
@@ -1341,6 +1342,12 @@ void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
break;
}
}
+#ifdef LEGACY_TOUCHSCREEN
+ // set true to mBtnTouch by multi-touch event with pressure more than zero
+ // some touchscreen driver which has BTN_TOUCH feature doesn't send BTN_TOUCH event
+ else if (rawEvent->type == EV_ABS && rawEvent->code == ABS_MT_TOUCH_MAJOR && rawEvent->value > 0)
+ mBtnTouch = true;
+#endif
}
uint32_t TouchButtonAccumulator::getButtonState() const {
@@ -1623,7 +1630,12 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
break;
case ABS_MT_TOUCH_MAJOR:
slot->mInUse = true;
+#ifdef LEGACY_TOUCHSCREEN
+ // emulate ABS_MT_PRESSURE
+ slot->mAbsMTPressure = rawEvent->value;
+#else
slot->mAbsMTTouchMajor = rawEvent->value;
+#endif
break;
case ABS_MT_TOUCH_MINOR:
slot->mInUse = true;
@@ -1632,7 +1644,12 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
break;
case ABS_MT_WIDTH_MAJOR:
slot->mInUse = true;
+#ifdef LEGACY_TOUCHSCREEN
+ // emulate ABS_MT_TOUCH_MAJOR
+ slot->mAbsMTTouchMajor = rawEvent->value;
+#else
slot->mAbsMTWidthMajor = rawEvent->value;
+#endif
break;
case ABS_MT_WIDTH_MINOR:
slot->mInUse = true;
@@ -1669,6 +1686,12 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
}
}
} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
+#ifdef LEGACY_TOUCHSCREEN
+ // don't use the slot with pressure less than or qeual to zero
+ // some touchscreen driver sends multi-touch event for not-in-use pointer
+ if (mSlots[mCurrentSlot].mAbsMTPressure <= 0)
+ mSlots[mCurrentSlot].mInUse = false;
+#endif
// MultiTouch Sync: The driver has returned all data for *one* of the pointers.
mCurrentSlot += 1;
}
@@ -2401,6 +2424,13 @@ void CursorInputMapper::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
sync(rawEvent->when);
}
+#ifdef LEGACY_TRACKPAD
+ // sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
+ // we need to ensure that we report the up/down promptly.
+ else if (rawEvent->type == EV_KEY && rawEvent->code == BTN_MOUSE) {
+ sync(rawEvent->when);
+ }
+#endif
}
void CursorInputMapper::sync(nsecs_t when) {
@@ -2733,7 +2763,8 @@ void TouchInputMapper::configure(nsecs_t when,
bool resetNeeded = false;
if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
| InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
- | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
+ | InputReaderConfiguration::CHANGE_SHOW_TOUCHES
+ | InputReaderConfiguration::CHANGE_STYLUS_ICON_ENABLED))) {
// Configure device sources, surface dimensions, orientation and
// scaling factors.
configureSurface(when, &resetNeeded);
@@ -4293,7 +4324,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
&& (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
|| mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
// Remind the user of where the pointer is after finishing a gesture with spots.
- mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
+ unfadePointer(PointerControllerInterface::TRANSITION_GRADUAL);
}
break;
case PointerGesture::TAP:
@@ -4303,7 +4334,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
case PointerGesture::PRESS:
// Unfade the pointer when the current gesture manipulates the
// area directly under the pointer.
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ unfadePointer(PointerControllerInterface::TRANSITION_IMMEDIATE);
break;
case PointerGesture::SWIPE:
case PointerGesture::FREEFORM:
@@ -5265,6 +5296,7 @@ void TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags)
mPointerSimple.currentProperties.id = 0;
mPointerSimple.currentProperties.toolType =
mCurrentCookedPointerData.pointerProperties[index].toolType;
+ mLastStylusTime = when;
} else {
down = false;
hovering = false;
@@ -5341,12 +5373,17 @@ void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
mPointerController->clearSpots();
mPointerController->setButtonState(mCurrentButtonState);
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ unfadePointer(PointerControllerInterface::TRANSITION_IMMEDIATE);
} else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
}
}
+ if (rejectPalm(when)) { // stylus is currently active
+ mPointerSimple.reset();
+ return;
+ }
+
if (mPointerSimple.down && !down) {
mPointerSimple.down = false;
@@ -5464,6 +5501,9 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32
const PointerProperties* properties, const PointerCoords* coords,
const uint32_t* idToIndex, BitSet32 idBits,
int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
+
+ if (rejectPalm(when)) return;
+
PointerCoords pointerCoords[MAX_POINTERS];
PointerProperties pointerProperties[MAX_POINTERS];
uint32_t pointerCount = 0;
@@ -5537,6 +5577,20 @@ void TouchInputMapper::fadePointer() {
}
}
+void TouchInputMapper::unfadePointer(PointerControllerInterface::Transition transition) {
+ if (mPointerController != NULL &&
+ !(mPointerUsage == POINTER_USAGE_STYLUS && !mConfig.stylusIconEnabled)) {
+ mPointerController->unfade(transition);
+ }
+}
+
+nsecs_t TouchInputMapper::mLastStylusTime = 0;
+
+bool TouchInputMapper::rejectPalm(nsecs_t when) {
+ return (when - mLastStylusTime < mConfig.stylusPalmRejectionTime) &&
+ mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_STYLUS;
+}
+
bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
&& y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
@@ -5984,12 +6038,20 @@ void MultiTouchInputMapper::configureRawPointerAxes() {
getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
+#ifdef LEGACY_TOUCHSCREEN
+ getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.touchMajor);
+#else
getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
+#endif
getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
+#ifdef LEGACY_TOUCHSCREEN
+ getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.pressure);
+#else
getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
+#endif
getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 61b21e2..ab452c8 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -137,6 +137,9 @@ struct InputReaderConfiguration {
// The device name alias supplied by the may have changed for some devices.
CHANGE_DEVICE_ALIAS = 1 << 5,
+ // Stylus icon option changed.
+ CHANGE_STYLUS_ICON_ENABLED = 1 << 6,
+
// All devices must be reopened.
CHANGE_MUST_REOPEN = 1 << 31,
};
@@ -224,6 +227,12 @@ struct InputReaderConfiguration {
// True to show the location of touches on the touch screen as spots.
bool showTouches;
+ // True to show the pointer icon when a stylus is used.
+ bool stylusIconEnabled;
+
+ // Ignore finger touches this long after the stylus has been used (including hover)
+ nsecs_t stylusPalmRejectionTime;
+
InputReaderConfiguration() :
virtualKeyQuietTime(0),
pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
@@ -240,7 +249,10 @@ struct InputReaderConfiguration {
pointerGestureSwipeMaxWidthRatio(0.25f),
pointerGestureMovementSpeedRatio(0.8f),
pointerGestureZoomSpeedRatio(0.3f),
- showTouches(false) { }
+ showTouches(false),
+ stylusIconEnabled(false),
+ stylusPalmRejectionTime(50 * 10000000LL) // 50 ms
+ { }
bool getDisplayInfo(bool external, DisplayViewport* outViewport) const;
void setDisplayInfo(bool external, const DisplayViewport& viewport);
@@ -1610,6 +1622,9 @@ private:
VelocityControl mWheelXVelocityControl;
VelocityControl mWheelYVelocityControl;
+ // The time the stylus event was processed by any TouchInputMapper
+ static nsecs_t mLastStylusTime;
+
void sync(nsecs_t when);
bool consumeRawTouches(nsecs_t when, uint32_t policyFlags);
@@ -1662,6 +1677,10 @@ private:
const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
void assignPointerIds();
+
+ void unfadePointer(PointerControllerInterface::Transition transition);
+
+ bool rejectPalm(nsecs_t when);
};
diff --git a/services/java/com/android/server/AppsLaunchFailureReceiver.java b/services/java/com/android/server/AppsLaunchFailureReceiver.java
new file mode 100644
index 0000000..6ef07aa
--- /dev/null
+++ b/services/java/com/android/server/AppsLaunchFailureReceiver.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010, T-Mobile USA, Inc.
+ *
+ * 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.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.CustomTheme;
+import android.util.Log;
+import android.app.ActivityManager;
+import android.os.SystemClock;
+
+public class AppsLaunchFailureReceiver extends BroadcastReceiver {
+
+ private static final int FAILURES_THRESHOLD = 5;
+ private static final int EXPIRATION_TIME_IN_MILLISECONDS = 30000; // 30 seconds
+
+ private int mFailuresCount = 0;
+ private long mStartTime = 0;
+
+ // This function implements the following logic.
+ // If after a theme was applied the number of application launch failures
+ // at any moment was equal to FAILURES_THRESHOLD
+ // in less than EXPIRATION_TIME_IN_MILLISECONDS
+ // the default theme is applied unconditionally.
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_APP_LAUNCH_FAILURE)) {
+ long currentTime = SystemClock.uptimeMillis();
+ if (currentTime - mStartTime > EXPIRATION_TIME_IN_MILLISECONDS) {
+ // reset both the count and the timer
+ mStartTime = currentTime;
+ mFailuresCount = 0;
+ }
+ if (mFailuresCount <= FAILURES_THRESHOLD) {
+ mFailuresCount++;
+ if (mFailuresCount == FAILURES_THRESHOLD) {
+ CustomTheme defaultTheme = CustomTheme.getSystemTheme();
+ ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
+ Configuration currentConfig = am.getConfiguration();
+ currentConfig.customTheme = new CustomTheme(
+ defaultTheme.getThemeId(),
+ defaultTheme.getThemePackageName());
+ am.updateConfiguration(currentConfig);
+ }
+ }
+ } else if (action.equals(Intent.ACTION_APP_LAUNCH_FAILURE_RESET)) {
+ mFailuresCount = 0;
+ mStartTime = SystemClock.uptimeMillis();
+ } else if (action.equals(Intent.ACTION_PACKAGE_ADDED) ||
+ action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
+ mFailuresCount = 0;
+ mStartTime = SystemClock.uptimeMillis();
+ }
+ }
+
+}
diff --git a/services/java/com/android/server/AssetRedirectionManagerService.java b/services/java/com/android/server/AssetRedirectionManagerService.java
new file mode 100644
index 0000000..1e124b9
--- /dev/null
+++ b/services/java/com/android/server/AssetRedirectionManagerService.java
@@ -0,0 +1,397 @@
+package com.android.server;
+
+import com.android.internal.app.IAssetRedirectionManager;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ThemeInfo;
+import android.content.res.AssetManager;
+import android.content.res.PackageRedirectionMap;
+import android.content.res.Resources;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class AssetRedirectionManagerService extends IAssetRedirectionManager.Stub {
+ private static final String TAG = "AssetRedirectionManager";
+
+ private final Context mContext;
+
+ /*
+ * TODO: This data structure should have some way to expire very old cache
+ * entries. Would be nice to optimize for the removal path as well.
+ */
+ private final HashMap<RedirectionKey, PackageRedirectionMap> mRedirections =
+ new HashMap<RedirectionKey, PackageRedirectionMap>();
+
+ public AssetRedirectionManagerService(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void clearRedirectionMapsByTheme(String themePackageName, String themeId)
+ throws RemoteException {
+ synchronized (mRedirections) {
+ Set<RedirectionKey> keys = mRedirections.keySet();
+ Iterator<RedirectionKey> iter = keys.iterator();
+ while (iter.hasNext()) {
+ RedirectionKey key = iter.next();
+ if (themePackageName.equals(key.themePackageName) &&
+ (themeId == null || themeId.equals(key.themeId))) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void clearPackageRedirectionMap(String targetPackageName) throws RemoteException {
+ synchronized (mRedirections) {
+ Set<RedirectionKey> keys = mRedirections.keySet();
+ Iterator<RedirectionKey> iter = keys.iterator();
+ while (iter.hasNext()) {
+ RedirectionKey key = iter.next();
+ if (targetPackageName.equals(key.targetPackageName)) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public PackageRedirectionMap getPackageRedirectionMap(String themePackageName,
+ String themeId, String targetPackageName) throws RemoteException {
+ synchronized (mRedirections) {
+ RedirectionKey key = new RedirectionKey();
+ key.themePackageName = themePackageName;
+ key.themeId = themeId;
+ key.targetPackageName = targetPackageName;
+
+ PackageRedirectionMap map = mRedirections.get(key);
+ if (map != null) {
+ return map;
+ } else {
+ map = generatePackageRedirectionMap(key);
+ if (map != null) {
+ mRedirections.put(key, map);
+ }
+ return map;
+ }
+ }
+ }
+
+ private PackageRedirectionMap generatePackageRedirectionMap(RedirectionKey key) {
+ AssetManager assets = new AssetManager();
+
+ boolean frameworkAssets = key.targetPackageName.equals("android");
+
+ if (!frameworkAssets) {
+ PackageInfo pi = getPackageInfo(mContext, key.targetPackageName);
+ if (pi == null || pi.applicationInfo == null ||
+ assets.addAssetPath(pi.applicationInfo.publicSourceDir) == 0) {
+ Log.w(TAG, "Unable to attach target package assets for " + key.targetPackageName);
+ return null;
+ }
+ }
+
+ PackageInfo pi = getPackageInfo(mContext, key.themePackageName);
+ if (pi == null || pi.applicationInfo == null || pi.themeInfos == null ||
+ assets.addAssetPath(pi.applicationInfo.publicSourceDir) == 0) {
+ Log.w(TAG, "Unable to attach theme package assets from " + key.themePackageName);
+ return null;
+ }
+
+ PackageRedirectionMap resMap = new PackageRedirectionMap();
+
+ /*
+ * Apply a special redirection hack for the highest level <style>
+ * replacing @android:style/Theme.
+ */
+ if (frameworkAssets) {
+ int themeResourceId = findThemeResourceId(pi.themeInfos, key.themeId);
+ assets.generateStyleRedirections(resMap.getNativePointer(), android.R.style.Theme,
+ themeResourceId);
+ }
+
+ Resources res = new Resources(assets, null, null);
+ generateExplicitRedirections(resMap, res, key.themePackageName, key.targetPackageName);
+
+ return resMap;
+ }
+
+ private void generateExplicitRedirections(PackageRedirectionMap resMap, Resources res,
+ String themePackageName, String targetPackageName) {
+ /*
+ * XXX: We should be parsing the <theme> tag's <meta-data>! Instead,
+ * we're just assuming that res/xml/<package>.xml exists and describes
+ * the redirects we want!
+ */
+ String redirectXmlName = targetPackageName.replace('.', '_');
+ int redirectXmlResId = res.getIdentifier(redirectXmlName, "xml", themePackageName);
+ if (redirectXmlResId == 0) {
+ return;
+ }
+
+ ResourceRedirectionsProcessor processor = new ResourceRedirectionsProcessor(res,
+ redirectXmlResId, themePackageName, targetPackageName, resMap);
+ processor.process();
+ }
+
+ private static PackageInfo getPackageInfo(Context context, String packageName) {
+ try {
+ return context.getPackageManager().getPackageInfo(packageName, 0);
+ } catch (NameNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Searches for the high-level theme resource id for the specific
+ * &lt;theme&gt; tag being applied.
+ * <p>
+ * An individual theme package can contain multiple &lt;theme&gt; tags, each
+ * representing a separate theme choice from the user's perspective, even
+ * though the most common case is for there to be only 1.
+ *
+ * @return The style resource id or 0 if no match was found.
+ */
+ private static int findThemeResourceId(ThemeInfo[] themeInfos, String needle) {
+ if (themeInfos != null && !TextUtils.isEmpty(needle)) {
+ int n = themeInfos.length;
+ for (int i = 0; i < n; i++) {
+ ThemeInfo info = themeInfos[i];
+ if (needle.equals(info.themeId)) {
+ return info.styleResourceId;
+ }
+ }
+ }
+ return 0;
+ }
+
+ private static Resources getUnredirectedResourcesForPackage(Context context, String packageName) {
+ AssetManager assets = new AssetManager();
+
+ if (!packageName.equals("android")) {
+ PackageInfo pi = getPackageInfo(context, packageName);
+ if (pi == null || pi.applicationInfo == null ||
+ assets.addAssetPath(pi.applicationInfo.publicSourceDir) == 0) {
+ Log.w(TAG, "Unable to get resources for package " + packageName);
+ return null;
+ }
+ }
+
+ return new Resources(assets, null, null);
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ synchronized (mRedirections) {
+ final ArrayList<RedirectionKey> filteredKeySet = new ArrayList<RedirectionKey>();
+ for (Map.Entry<RedirectionKey, PackageRedirectionMap> entry: mRedirections.entrySet()) {
+ PackageRedirectionMap map = entry.getValue();
+ if (map != null && map.getPackageId() != -1) {
+ filteredKeySet.add(entry.getKey());
+ }
+ }
+ Collections.sort(filteredKeySet, new Comparator<RedirectionKey>() {
+ @Override
+ public int compare(RedirectionKey a, RedirectionKey b) {
+ int comp = a.themePackageName.compareTo(b.themePackageName);
+ if (comp != 0) {
+ return comp;
+ }
+ comp = a.themeId.compareTo(b.themeId);
+ if (comp != 0) {
+ return comp;
+ }
+ return a.targetPackageName.compareTo(b.targetPackageName);
+ }
+ });
+
+ pw.println("Theme asset redirections:");
+ String lastPackageName = null;
+ String lastId = null;
+ Resources themeRes = null;
+ for (RedirectionKey key: filteredKeySet) {
+ if (lastPackageName == null || !lastPackageName.equals(key.themePackageName)) {
+ pw.println("* Theme package " + key.themePackageName + ":");
+ lastPackageName = key.themePackageName;
+ themeRes = getUnredirectedResourcesForPackage(mContext, key.themePackageName);
+ }
+ if (lastId == null || !lastId.equals(key.themeId)) {
+ pw.println(" theme id #" + key.themeId + ":");
+ lastId = key.themeId;
+ }
+ pw.println(" " + key.targetPackageName + ":");
+ Resources targetRes = getUnredirectedResourcesForPackage(mContext, key.targetPackageName);
+ PackageRedirectionMap resMap = mRedirections.get(key);
+ int[] fromIdents = resMap.getRedirectionKeys();
+ int N = fromIdents.length;
+ for (int i = 0; i < N; i++) {
+ int fromIdent = fromIdents[i];
+ int toIdent = resMap.lookupRedirection(fromIdent);
+ String fromName = targetRes != null ? targetRes.getResourceName(fromIdent) : null;
+ String toName = themeRes != null ? themeRes.getResourceName(toIdent) : null;
+ pw.println(String.format(" %s (0x%08x) => %s (0x%08x)", fromName, fromIdent,
+ toName, toIdent));
+ }
+ }
+ }
+ }
+
+ private static class RedirectionKey {
+ public String themePackageName;
+ public String themeId;
+ public String targetPackageName;
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof RedirectionKey)) return false;
+ final RedirectionKey oo = (RedirectionKey)o;
+ if (!nullSafeEquals(themePackageName, oo.themePackageName)) {
+ return false;
+ }
+ if (!nullSafeEquals(themeId, oo.themeId)) {
+ return false;
+ }
+ if (!nullSafeEquals(targetPackageName, oo.targetPackageName)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return themePackageName.hashCode() +
+ themeId.hashCode() +
+ targetPackageName.hashCode();
+ }
+
+ private static boolean nullSafeEquals(Object a, Object b) {
+ if (a == null) {
+ return b == a;
+ } else if (b == null) {
+ return false;
+ } else {
+ return a.equals(b);
+ }
+ }
+ }
+
+ /**
+ * Parses and processes explicit redirection XML files.
+ */
+ private static class ResourceRedirectionsProcessor {
+ private final Resources mResources;
+ private final XmlPullParser mParser;
+ private final int mResourceId;
+ private final String mThemePackageName;
+ private final String mTargetPackageName;
+ private final PackageRedirectionMap mResMap;
+
+ public ResourceRedirectionsProcessor(Resources res, int resourceId,
+ String themePackageName, String targetPackageName,
+ PackageRedirectionMap outMap) {
+ mResources = res;
+ mParser = res.getXml(resourceId);
+ mResourceId = resourceId;
+ mThemePackageName = themePackageName;
+ mTargetPackageName = targetPackageName;
+ mResMap = outMap;
+ }
+
+ public void process() {
+ XmlPullParser parser = mParser;
+ int type;
+ try {
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ // just loop...
+ }
+
+ String tagName = parser.getName();
+ if (parser.getName().equals("resource-redirections")) {
+ processResourceRedirectionsTag();
+ } else {
+ Log.w(TAG, "Unknown root element: " + tagName + " at " + getResourceLabel() + " " +
+ parser.getPositionDescription());
+ }
+ } catch (XmlPullParserException e) {
+ Log.w(TAG, "Malformed theme redirection meta at " + getResourceLabel());
+ } catch (IOException e) {
+ Log.w(TAG, "Unknown error reading redirection meta at " + getResourceLabel());
+ }
+ }
+
+ private void processResourceRedirectionsTag() throws XmlPullParserException, IOException {
+ XmlPullParser parser = mParser;
+ int type;
+ final int innerDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT &&
+ (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals("item")) {
+ processItemTag();
+ } else {
+ Log.w(TAG, "Unknown element under <resource-redirections>: " + tagName
+ + " at " + getResourceLabel() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ }
+ }
+
+ private void processItemTag() throws XmlPullParserException, IOException {
+ XmlPullParser parser = mParser;
+ String fromName = parser.getAttributeValue(null, "name");
+ if (TextUtils.isEmpty(fromName)) {
+ Log.w(TAG, "Missing android:name attribute on <item> tag at " + getResourceLabel() + " " +
+ parser.getPositionDescription());
+ return;
+ }
+ String toName = parser.nextText();
+ if (TextUtils.isEmpty(toName)) {
+ Log.w(TAG, "Missing <item> text at " + getResourceLabel() + " " +
+ parser.getPositionDescription());
+ return;
+ }
+ int fromIdent = mResources.getIdentifier(fromName, null, mTargetPackageName);
+ if (fromIdent == 0) {
+ Log.w(TAG, "No such resource found for " + mTargetPackageName + ":" + fromName);
+ return;
+ }
+ int toIdent = mResources.getIdentifier(toName, null, mThemePackageName);
+ if (toIdent == 0) {
+ Log.w(TAG, "No such resource found for " + mThemePackageName + ":" + toName);
+ return;
+ }
+ mResMap.addRedirection(fromIdent, toIdent);
+ }
+
+ private String getResourceLabel() {
+ return "resource #0x" + Integer.toHexString(mResourceId);
+ }
+ }
+}
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index dbffa97..08d9ffa 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -17,15 +17,23 @@
package com.android.server;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.os.DeviceDockBatteryHandler;
+import com.android.internal.os.IDeviceHandler;
import com.android.server.am.BatteryStatsService;
import android.app.ActivityManagerNative;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.graphics.Color;
import android.os.BatteryManager;
import android.os.Binder;
+import android.os.Bundle;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
@@ -44,7 +52,7 @@ import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
-
+import java.util.Calendar;
/**
* <p>BatteryService monitors the charging status, and charge level of the device
@@ -62,7 +70,7 @@ import java.io.PrintWriter;
* <p>&quot;present&quot; - boolean, true if the battery is present<br />
* <p>&quot;icon-small&quot; - int, suggested small icon to use for this state</p>
* <p>&quot;plugged&quot; - int, 0 if the device is not plugged in; 1 if plugged
- * into an AC power adapter; 2 if plugged in via USB.</p>
+ * into an AC power adapter; 2 if plugged in via USB; 4 if plugged in via Wireless.</p>
* <p>&quot;voltage&quot; - int, current battery voltage in millivolts</p>
* <p>&quot;temperature&quot; - int, current battery temperature in tenths of
* a degree Centigrade</p>
@@ -114,6 +122,7 @@ public final class BatteryService extends Binder {
private int mBatteryTemperature;
private String mBatteryTechnology;
private boolean mBatteryLevelCritical;
+ private int mInvalidCharger;
/* End native fields. */
private int mLastBatteryStatus;
@@ -123,10 +132,12 @@ public final class BatteryService extends Binder {
private int mLastBatteryVoltage;
private int mLastBatteryTemperature;
private boolean mLastBatteryLevelCritical;
-
- private int mInvalidCharger;
private int mLastInvalidCharger;
+ // Device specific handler for extra dock battery
+ private boolean mHasDockBattery;
+ private DeviceDockBatteryHandler mDeviceDockBattery;
+
private int mLowBatteryWarningLevel;
private int mLowBatteryCloseWarningLevel;
private int mShutdownBatteryTemperature;
@@ -140,12 +151,23 @@ public final class BatteryService extends Binder {
private boolean mUpdatesStopped;
private Led mLed;
+ private boolean mLightEnabled;
+ private boolean mLedPulseEnabled;
+ private int mBatteryLowARGB;
+ private int mBatteryMediumARGB;
+ private int mBatteryFullARGB;
+ private boolean mMultiColorLed;
private boolean mSentLowBatteryBroadcast = false;
private native void native_update();
+ // Quiet hours support
+ private boolean mQuietHoursEnabled = false;
+ private int mQuietHoursStart = 0;
+ private int mQuietHoursEnd = 0;
+ private boolean mQuietHoursDim = true;
- public BatteryService(Context context, LightsService lights) {
+ public BatteryService(Context context, LightsService lights, IDeviceHandler deviceHandler) {
mContext = context;
mHandler = new Handler(true /*async*/);
mLed = new Led(context, lights);
@@ -160,6 +182,20 @@ public final class BatteryService extends Binder {
mShutdownBatteryTemperature = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shutdownBatteryTemperature);
+ // Has Dock battery? and device specific handler?
+ mHasDockBattery = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_hasDockBattery);
+ if (mHasDockBattery) {
+ if (deviceHandler != null) {
+ mDeviceDockBattery = deviceHandler.getDeviceDockBatteryHandler();
+
+ // Force an update of the data when dock state change
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_DOCK_EVENT);
+ context.registerReceiver(mDockReceiver, filter);
+ }
+ }
+
mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply");
// watch for invalid charger messages if the invalid_charger switch exists
@@ -168,6 +204,9 @@ public final class BatteryService extends Binder {
"DEVPATH=/devices/virtual/switch/invalid_charger");
}
+ SettingsObserver observer = new SettingsObserver(new Handler());
+ observer.observe();
+
// set initial status
synchronized (mLock) {
updateLocked();
@@ -197,6 +236,7 @@ public final class BatteryService extends Binder {
if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
return true;
}
+ // mAcOnline is used for main ac and dock battery ac
if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mAcOnline) {
return true;
}
@@ -277,6 +317,9 @@ public final class BatteryService extends Binder {
if (!mUpdatesStopped) {
// Update the values of mAcOnline, et. all.
native_update();
+ if (mDeviceDockBattery != null) {
+ mDeviceDockBattery.update();
+ }
// Process the new values.
processValuesLocked();
@@ -287,8 +330,14 @@ public final class BatteryService extends Binder {
boolean logOutlier = false;
long dischargeDuration = 0;
+ // Process the dock battery values
+ if (mDeviceDockBattery != null) {
+ mDeviceDockBattery.process();
+ }
+
mBatteryLevelCritical = (mBatteryLevel <= mCriticalBatteryLevel);
- if (mAcOnline) {
+ if (mAcOnline ||
+ (mDeviceDockBattery != null && mDeviceDockBattery.isPlugged())) {
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mUsbOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
@@ -299,6 +348,7 @@ public final class BatteryService extends Binder {
}
if (DEBUG) {
+ String dockValues = String.valueOf(mDeviceDockBattery);
Slog.d(TAG, "Processing new values: "
+ "mAcOnline=" + mAcOnline
+ ", mUsbOnline=" + mUsbOnline
@@ -311,7 +361,9 @@ public final class BatteryService extends Binder {
+ ", mBatteryVoltage=" + mBatteryVoltage
+ ", mBatteryTemperature=" + mBatteryTemperature
+ ", mBatteryLevelCritical=" + mBatteryLevelCritical
- + ", mPlugType=" + mPlugType);
+ + ", mPlugType=" + mPlugType
+ + ", mHasDockBattery=" + mHasDockBattery
+ + ", mDeviceDockBattery=[" + dockValues + "]");
}
// Let the battery stats keep track of the current level.
@@ -326,6 +378,11 @@ public final class BatteryService extends Binder {
shutdownIfNoPowerLocked();
shutdownIfOverTempLocked();
+ boolean dockBatteryHasNewData = false;
+ if (mDeviceDockBattery != null) {
+ dockBatteryHasNewData = mDeviceDockBattery.hasNewData();
+ }
+
if (mBatteryStatus != mLastBatteryStatus ||
mBatteryHealth != mLastBatteryHealth ||
mBatteryPresent != mLastBatteryPresent ||
@@ -333,7 +390,8 @@ public final class BatteryService extends Binder {
mPlugType != mLastPlugType ||
mBatteryVoltage != mLastBatteryVoltage ||
mBatteryTemperature != mLastBatteryTemperature ||
- mInvalidCharger != mLastInvalidCharger) {
+ mInvalidCharger != mLastInvalidCharger ||
+ dockBatteryHasNewData) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -465,6 +523,11 @@ public final class BatteryService extends Binder {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ Bundle dockData = new Bundle();
+ if (mDeviceDockBattery != null) {
+ dockData = mDeviceDockBattery.getNotifyData();
+ }
+
int icon = getIconLocked(mBatteryLevel);
intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus);
@@ -478,8 +541,13 @@ public final class BatteryService extends Binder {
intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature);
intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
+ intent.putExtras(dockData);
if (DEBUG) {
+ String dockDebug = "";
+ for (String key : dockData.keySet()) {
+ dockDebug += ", " + key + ": " + String.valueOf(dockData.get(key));
+ }
Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryLevel +
", scale:" + BATTERY_SCALE + ", status:" + mBatteryStatus +
", health:" + mBatteryHealth + ", present:" + mBatteryPresent +
@@ -488,7 +556,8 @@ public final class BatteryService extends Binder {
", technology: " + mBatteryTechnology +
", AC powered:" + mAcOnline + ", USB powered:" + mUsbOnline +
", Wireless powered:" + mWirelessOnline +
- ", icon:" + icon + ", invalid charger:" + mInvalidCharger);
+ ", icon:" + icon + ", invalid charger:" + mInvalidCharger +
+ dockDebug);
}
mHandler.post(new Runnable() {
@@ -650,6 +719,17 @@ public final class BatteryService extends Binder {
}
}
+ private final BroadcastReceiver mDockReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
+ synchronized (mLock) {
+ updateLocked();
+ }
+ }
+ }
+ };
+
private final UEventObserver mPowerSupplyObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
@@ -672,24 +752,23 @@ public final class BatteryService extends Binder {
}
};
+ private synchronized void updateLedPulse() {
+ mLed.updateLightsLocked();
+ }
+
private final class Led {
private final LightsService.Light mBatteryLight;
- private final int mBatteryLowARGB;
- private final int mBatteryMediumARGB;
- private final int mBatteryFullARGB;
private final int mBatteryLedOn;
private final int mBatteryLedOff;
public Led(Context context, LightsService lights) {
mBatteryLight = lights.getLight(LightsService.LIGHT_ID_BATTERY);
- mBatteryLowARGB = context.getResources().getInteger(
- com.android.internal.R.integer.config_notificationsBatteryLowARGB);
- mBatteryMediumARGB = context.getResources().getInteger(
- com.android.internal.R.integer.config_notificationsBatteryMediumARGB);
- mBatteryFullARGB = context.getResources().getInteger(
- com.android.internal.R.integer.config_notificationsBatteryFullARGB);
+ // Does the Device support changing battery LED colors?
+ mMultiColorLed = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_multiColorBatteryLed);
+
mBatteryLedOn = context.getResources().getInteger(
com.android.internal.R.integer.config_notificationsBatteryLedOn);
mBatteryLedOff = context.getResources().getInteger(
@@ -702,22 +781,40 @@ public final class BatteryService extends Binder {
public void updateLightsLocked() {
final int level = mBatteryLevel;
final int status = mBatteryStatus;
- if (level < mLowBatteryWarningLevel) {
+
+ if (!mLightEnabled) {
+ // No lights if explicitly disabled
+ mBatteryLight.turnOff();
+ } else if (inQuietHours() && mQuietHoursDim) {
+ if (mLedPulseEnabled && level < mLowBatteryWarningLevel &&
+ status != BatteryManager.BATTERY_STATUS_CHARGING) {
+ // The battery is low, the device is not charging and the low battery pulse
+ // is enabled - ignore Quiet Hours
+ mBatteryLight.setFlashing(mBatteryLowARGB, LightsService.LIGHT_FLASH_TIMED,
+ mBatteryLedOn, mBatteryLedOff);
+ } else {
+ // No lights if in Quiet Hours and battery not low
+ mBatteryLight.turnOff();
+ }
+ } else if (level < mLowBatteryWarningLevel) {
if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
- // Solid red when battery is charging
+ // Battery is charging and low
mBatteryLight.setColor(mBatteryLowARGB);
- } else {
- // Flash red when battery is low and not charging
+ } else if (mLedPulseEnabled) {
+ // Battery is low and not charging
mBatteryLight.setFlashing(mBatteryLowARGB, LightsService.LIGHT_FLASH_TIMED,
mBatteryLedOn, mBatteryLedOff);
+ } else {
+ // "Pulse low battery light" is disabled, no lights.
+ mBatteryLight.turnOff();
}
} else if (status == BatteryManager.BATTERY_STATUS_CHARGING
- || status == BatteryManager.BATTERY_STATUS_FULL) {
+ || status == BatteryManager.BATTERY_STATUS_FULL) {
if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) {
- // Solid green when full or charging and nearly full
+ // Battery is full or charging and nearly full
mBatteryLight.setColor(mBatteryFullARGB);
} else {
- // Solid orange when charging and halfway full
+ // Battery is charging and halfway full
mBatteryLight.setColor(mBatteryMediumARGB);
}
} else {
@@ -726,4 +823,101 @@ public final class BatteryService extends Binder {
}
}
}
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+
+ // Battery light enabled
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.BATTERY_LIGHT_ENABLED), false, this);
+
+ // Low battery pulse
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.BATTERY_LIGHT_PULSE), false, this);
+
+ // Light colors
+ if (mMultiColorLed) {
+ // Register observer if we have a multi color led
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.BATTERY_LIGHT_LOW_COLOR), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.BATTERY_LIGHT_MEDIUM_COLOR), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.BATTERY_LIGHT_FULL_COLOR), false, this);
+ }
+
+ // Quiet Hours
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_ENABLED), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_START), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_END), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_DIM), false, this);
+
+ update();
+ }
+
+ @Override public void onChange(boolean selfChange) {
+ update();
+ }
+
+ public void update() {
+ ContentResolver resolver = mContext.getContentResolver();
+ Resources res = mContext.getResources();
+
+ // Battery light enabled
+ mLightEnabled = Settings.System.getInt(resolver,
+ Settings.System.BATTERY_LIGHT_ENABLED, 1) != 0;
+
+ // Low battery pulse
+ mLedPulseEnabled = Settings.System.getInt(resolver,
+ Settings.System.BATTERY_LIGHT_PULSE, 1) != 0;
+
+ // Light colors
+ mBatteryLowARGB = Settings.System.getInt(resolver,
+ Settings.System.BATTERY_LIGHT_LOW_COLOR,
+ res.getInteger(com.android.internal.R.integer.config_notificationsBatteryLowARGB));
+ mBatteryMediumARGB = Settings.System.getInt(resolver,
+ Settings.System.BATTERY_LIGHT_MEDIUM_COLOR,
+ res.getInteger(com.android.internal.R.integer.config_notificationsBatteryMediumARGB));
+ mBatteryFullARGB = Settings.System.getInt(resolver,
+ Settings.System.BATTERY_LIGHT_FULL_COLOR,
+ res.getInteger(com.android.internal.R.integer.config_notificationsBatteryFullARGB));
+
+ // Quiet Hours
+ mQuietHoursEnabled = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_ENABLED, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ mQuietHoursStart = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_START, 0, UserHandle.USER_CURRENT_OR_SELF);
+ mQuietHoursEnd = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_END, 0, UserHandle.USER_CURRENT_OR_SELF);
+ mQuietHoursDim = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_DIM, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+
+ updateLedPulse();
+ }
+ }
+
+ private boolean inQuietHours() {
+ if (mQuietHoursEnabled && (mQuietHoursStart != mQuietHoursEnd)) {
+ // Get the date in "quiet hours" format.
+ Calendar calendar = Calendar.getInstance();
+ int minutes = calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE);
+ if (mQuietHoursEnd < mQuietHoursStart) {
+ // Starts at night, ends in the morning.
+ return (minutes > mQuietHoursStart) || (minutes < mQuietHoursEnd);
+ } else {
+ return (minutes > mQuietHoursStart) && (minutes < mQuietHoursEnd);
+ }
+ }
+ return false;
+ }
+
}
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index a7c4d73..f0693a9 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -67,6 +67,7 @@ import android.net.Proxy;
import android.net.ProxyProperties;
import android.net.RouteInfo;
import android.net.wifi.WifiStateTracker;
+import android.net.wimax.WimaxHelper;
import android.net.wimax.WimaxManagerConstants;
import android.os.Binder;
import android.os.FileUtils;
@@ -368,13 +369,17 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
// setup our unique device name
- if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
+ String hostname = Settings.Secure.getString(context.getContentResolver(),
+ Settings.Secure.DEVICE_HOSTNAME);
+ if (TextUtils.isEmpty(hostname) && TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
String id = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
if (id != null && id.length() > 0) {
String name = new String("android-").concat(id);
SystemProperties.set("net.hostname", name);
}
+ } else {
+ SystemProperties.set("net.hostname", hostname);
}
// read our default dns server ip
@@ -605,8 +610,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
Class wimaxStateTrackerClass = null;
Class wimaxServiceClass = null;
Class wimaxManagerClass;
- String wimaxJarLocation;
- String wimaxLibLocation;
String wimaxManagerClassName;
String wimaxServiceClassName;
String wimaxStateTrackerClassName;
@@ -618,10 +621,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (isWimaxEnabled) {
try {
- wimaxJarLocation = context.getResources().getString(
- com.android.internal.R.string.config_wimaxServiceJarLocation);
- wimaxLibLocation = context.getResources().getString(
- com.android.internal.R.string.config_wimaxNativeLibLocation);
wimaxManagerClassName = context.getResources().getString(
com.android.internal.R.string.config_wimaxManagerClassname);
wimaxServiceClassName = context.getResources().getString(
@@ -629,10 +628,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
wimaxStateTrackerClassName = context.getResources().getString(
com.android.internal.R.string.config_wimaxStateTrackerClassname);
- if (DBG) log("wimaxJarLocation: " + wimaxJarLocation);
- wimaxClassLoader = new DexClassLoader(wimaxJarLocation,
- new ContextWrapper(context).getCacheDir().getAbsolutePath(),
- wimaxLibLocation, ClassLoader.getSystemClassLoader());
+ wimaxClassLoader = WimaxHelper.getWimaxClassLoader(context);
try {
wimaxManagerClass = wimaxClassLoader.loadClass(wimaxManagerClassName);
diff --git a/services/java/com/android/server/DeviceHandlerService.java b/services/java/com/android/server/DeviceHandlerService.java
new file mode 100644
index 0000000..ddf455d
--- /dev/null
+++ b/services/java/com/android/server/DeviceHandlerService.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.content.ContextWrapper;
+import android.content.res.Resources;
+import android.os.Binder;
+import android.util.Log;
+
+import com.android.internal.os.DeviceDockBatteryHandler;
+import com.android.internal.os.DeviceKeyHandler;
+import com.android.internal.os.IDeviceHandler;
+
+import dalvik.system.DexClassLoader;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * DeviceHandlerService exposed device specific handlers to other services.
+ * All specific device, not implemented by aosp, should be included here.
+ * @see DeviceKeyHandler
+ * @see DeviceDockBatteryHandler
+ * @hide
+ */
+public final class DeviceHandlerService extends Binder implements IDeviceHandler {
+ private static final String TAG = DeviceHandlerService.class.getSimpleName();
+
+ private static final boolean DEBUG = true;
+
+ private final Context mContext;
+
+ private DeviceKeyHandler mDeviceKeyHandler = null;
+ private DeviceDockBatteryHandler mDeviceDockBatteryHandler = null;
+
+ public DeviceHandlerService(Context context) {
+ mContext = context;
+ registerHandlers();
+ }
+
+ private void registerHandlers() {
+ // For register device specific handlers at least a library with the
+ // implementations is required.
+ Resources res = mContext.getResources();
+ String deviceHandlersLib =
+ res.getString(
+ com.android.internal.R.string.config_deviceHandlersLib);
+ if (deviceHandlersLib.isEmpty()) {
+ Log.i(TAG, "No device specific handler lib was defined.");
+ return;
+ }
+ ClassLoader classLoader =
+ new DexClassLoader(
+ deviceHandlersLib,
+ new ContextWrapper(mContext).getCacheDir().getAbsolutePath(),
+ null,
+ ClassLoader.getSystemClassLoader());
+
+ // ------------------
+ // DeviceKeyHandler
+ // ------------------
+ String handlerClass =
+ res.getString(com.android.internal.R.string.config_deviceKeyHandlerClass);
+ if (!handlerClass.isEmpty()) {
+ mDeviceKeyHandler = (DeviceKeyHandler)getHandler(classLoader, "key", handlerClass);
+ }
+
+ // ------------------
+ // DeviceDockBatteryHandler
+ // ------------------
+ // Has dock battery? and device specific handler?
+ boolean hasDockBattery = res.getBoolean(com.android.internal.R.bool.config_hasDockBattery);
+ if (hasDockBattery) {
+ handlerClass =
+ res.getString(
+ com.android.internal.R.string.config_deviceDockBatteryHandlerClass);
+ if (!handlerClass.isEmpty()) {
+ mDeviceDockBatteryHandler =
+ (DeviceDockBatteryHandler)getHandler(
+ classLoader, "dock battery", handlerClass);
+ }
+ }
+ }
+
+ private Object getHandler(final ClassLoader classLoader,
+ final String type, final String handlerClass) {
+ try {
+ Class<?> clazz = classLoader.loadClass(handlerClass);
+ Constructor<?> constructor = clazz.getConstructor(Context.class);
+ Object handler = constructor.newInstance(mContext);
+ if(DEBUG) {
+ Log.d(TAG, String.format("Instantiated %s handler class %s", type, handlerClass));
+ }
+ return handler;
+
+ } catch (Exception e) {
+ Log.w(TAG,
+ String.format(
+ "Could not instantiate %s handler class %s", type, handlerClass), e);
+ }
+ return null;
+ }
+
+ public DeviceKeyHandler getDeviceKeyHandler() {
+ return mDeviceKeyHandler;
+ }
+
+ public DeviceDockBatteryHandler getDeviceDockBatteryHandler() {
+ return mDeviceDockBatteryHandler;
+ }
+}
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 94a087a..dbeb138 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -19,9 +19,11 @@ package com.android.server;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import com.android.internal.app.ThemeUtils;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -77,19 +79,20 @@ public class DeviceStorageMonitorService extends Binder {
private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
private static final int DEFAULT_FULL_THRESHOLD_BYTES = 1024*1024; // 1MB
- private long mFreeMem; // on /data
- private long mFreeMemAfterLastCacheClear; // on /data
+ private long mFreeMem; // on /data/data
+ private long mFreeMemAfterLastCacheClear; // on /data/data
private long mLastReportedFreeMem;
private long mLastReportedFreeMemTime;
private boolean mLowMemFlag=false;
private boolean mMemFullFlag=false;
private Context mContext;
+ private Context mUiContext;
private ContentResolver mContentResolver;
- private long mTotalMemory; // on /data
+ private long mTotalMemory; // on /data/data
private StatFs mDataFileStats;
private StatFs mSystemFileStats;
private StatFs mCacheFileStats;
- private static final String DATA_PATH = "/data";
+ private static final String DATA_PATH = "/data/data"; // might not be the same fs as /data
private static final String SYSTEM_PATH = "/system";
private static final String CACHE_PATH = "/cache";
private long mThreadStartTime = -1;
@@ -345,6 +348,14 @@ public class DeviceStorageMonitorService extends Binder {
mLastReportedFreeMemTime = 0;
mContext = context;
mContentResolver = mContext.getContentResolver();
+
+ ThemeUtils.registerThemeChangeReceiver(mContext, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context content, Intent intent) {
+ mUiContext = null;
+ }
+ });
+
//create StatFs object
mDataFileStats = new StatFs(DATA_PATH);
mSystemFileStats = new StatFs(SYSTEM_PATH);
@@ -402,7 +413,7 @@ public class DeviceStorageMonitorService extends Binder {
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(getUiContext(), title, details, intent);
mNotificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification,
UserHandle.ALL);
mContext.sendStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL);
@@ -515,4 +526,11 @@ public class DeviceStorageMonitorService extends Binder {
pw.print(" mMemCacheTrimToThreshold=");
pw.println(Formatter.formatFileSize(mContext, mMemCacheTrimToThreshold));
}
+
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 94e0bd4..7b5b584 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -15,6 +15,7 @@
package com.android.server;
+import com.android.internal.app.ThemeUtils;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
@@ -165,6 +166,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private static final Locale ENGLISH_LOCALE = new Locale("en");
final Context mContext;
+ private Context mUiContext;
final Resources mRes;
final Handler mHandler;
final InputMethodSettings mSettings;
@@ -398,6 +400,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
Settings.Secure.ENABLED_INPUT_METHODS), false, this);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_IME_SWITCHER),
+ false, new ContentObserver(mHandler) {
+ public void onChange(boolean selfChange) {
+ updateFromSettingsLocked();
+ }
+ });
}
@Override public void onChange(boolean selfChange) {
@@ -844,11 +853,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
(KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ ThemeUtils.registerThemeChangeReceiver(mContext, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ });
+
mStatusBar = statusBar;
statusBar.setIconVisibility("ime", false);
updateImeWindowStatusLocked();
- mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
- com.android.internal.R.bool.show_ongoing_ime_switcher);
if (mShowOngoingImeSwitcherForPhones) {
mWindowManagerService.setOnHardKeyboardStatusChangeListener(
mHardKeyboardListener);
@@ -1609,6 +1623,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mCurMethodId = null;
unbindCurrentMethodLocked(true, false);
}
+ // code to disable the CM Phone IME switcher with config_show_cmIMESwitcher set = false
+ try {
+ mShowOngoingImeSwitcherForPhones = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_IME_SWITCHER) == 1;
+ } catch (SettingNotFoundException e) {
+ mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
+ com.android.internal.R.bool.config_show_cmIMESwitcher);
+ }
}
/* package */ void setInputMethodLocked(String id, int subtypeId) {
@@ -2536,6 +2558,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
+
// ----------------------------------------------------------------------
private void showInputMethodMenu() {
@@ -2572,7 +2601,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private void showInputMethodMenuInternal(boolean showSubtypes) {
if (DEBUG) Slog.v(TAG, "Show switching menu");
- final Context context = mContext;
+ final Context context = getUiContext();
final boolean isScreenLocked = isScreenLocked();
final String lastInputMethodId = mSettings.getSelectedInputMethod();
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index f21f826..0f08c56 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1885,13 +1885,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
public void removeTestProvider(String provider) {
checkMockPermissionsSafe();
synchronized (mLock) {
- MockProvider mockProvider = mMockProviders.get(provider);
+ MockProvider mockProvider = mMockProviders.remove(provider);
if (mockProvider == null) {
throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
}
long identity = Binder.clearCallingIdentity();
removeProviderLocked(mProvidersByName.get(provider));
- mMockProviders.remove(mockProvider);
// reinstate real provider if available
LocationProviderInterface realProvider = mRealProviders.get(provider);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 2e0c977..383a39c 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -404,6 +404,13 @@ class MountService extends IMountService.Stub
case H_UNMOUNT_PM_UPDATE: {
if (DEBUG_UNMOUNT) Slog.i(TAG, "H_UNMOUNT_PM_UPDATE");
UnmountCallBack ucb = (UnmountCallBack) msg.obj;
+ if (!mUpdatingStatus && !isPrimaryStorage(ucb.path)) {
+ // If PM isn't already updating, and this isn't an ASEC
+ // mount, then go ahead and do the unmount immediately.
+ if (DEBUG_UNMOUNT) Slog.i(TAG, " skipping PackageManager for " + ucb.path);
+ ucb.handleFinished();
+ break;
+ }
mForceUnmounts.add(ucb);
if (DEBUG_UNMOUNT) Slog.i(TAG, " registered = " + mUpdatingStatus);
// Register only if needed.
@@ -996,7 +1003,9 @@ class MountService extends IMountService.Stub
Runtime.getRuntime().gc();
// Redundant probably. But no harm in updating state again.
- mPms.updateExternalMediaStatus(false, false);
+ if (isPrimaryStorage(path)) {
+ mPms.updateExternalMediaStatus(false, false);
+ }
try {
final Command cmd = new Command("volume", "unmount", path);
if (removeEncryption) {
@@ -1078,10 +1087,13 @@ class MountService extends IMountService.Stub
mSendUmsConnectedOnBoot = avail;
}
- final StorageVolume primary = getPrimaryPhysicalVolume();
- if (avail == false && primary != null
- && Environment.MEDIA_SHARED.equals(getVolumeState(primary.getPath()))) {
- final String path = primary.getPath();
+ final ArrayList<String> volumes = getShareableVolumes();
+ boolean mediaShared = false;
+ for (String path : volumes) {
+ if (getVolumeState(path).equals(Environment.MEDIA_SHARED))
+ mediaShared = true;
+ }
+ if (avail == false && mediaShared) {
/*
* USB mass storage disconnected while enabled
*/
@@ -1091,11 +1103,15 @@ class MountService extends IMountService.Stub
try {
int rc;
Slog.w(TAG, "Disabling UMS after cable disconnect");
- doShareUnshareVolume(path, "ums", false);
- if ((rc = doMountVolume(path)) != StorageResultCode.OperationSucceeded) {
- Slog.e(TAG, String.format(
- "Failed to remount {%s} on UMS enabled-disconnect (%d)",
- path, rc));
+ for (String path : volumes) {
+ if (getVolumeState(path).equals(Environment.MEDIA_SHARED)) {
+ doShareUnshareVolume(path, "ums", false);
+ if ((rc = doMountVolume(path)) != StorageResultCode.OperationSucceeded) {
+ Slog.e(TAG, String.format(
+ "Failed to remount {%s} on UMS enabled-disconnect (%d)",
+ path, rc));
+ }
+ }
}
} catch (Exception ex) {
Slog.w(TAG, "Failed to mount media on UMS enabled-disconnect", ex);
@@ -1434,6 +1450,30 @@ class MountService extends IMountService.Stub
}
}
+ private boolean isPrimaryStorage(String path) {
+ synchronized (mVolumesLock) {
+ for (StorageVolume volume : mVolumes) {
+ if (volume.isPrimary() && volume.getPath().equals(path)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ private ArrayList<String> getShareableVolumes() {
+ // Sharable volumes have android:allowMassStorage="true" in storage_list.xml
+ ArrayList<String> volumesToMount = new ArrayList<String>();
+ synchronized (mVolumesLock) {
+ for (StorageVolume v : mVolumes) {
+ if (v.allowMassStorage()) {
+ volumesToMount.add(v.getPath());
+ }
+ }
+ }
+ return volumesToMount;
+ }
+
public void setUsbMassStorageEnabled(boolean enable) {
waitForReady();
validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
@@ -1443,33 +1483,34 @@ class MountService extends IMountService.Stub
// TODO: Add support for multiple share methods
- /*
- * If the volume is mounted and we're enabling then unmount it
- */
- String path = primary.getPath();
- String vs = getVolumeState(path);
- String method = "ums";
- if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
- // Override for isUsbMassStorageEnabled()
- setUmsEnabling(enable);
- UmsEnableCallBack umscb = new UmsEnableCallBack(path, method, true);
- mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, umscb));
- // Clear override
- setUmsEnabling(false);
- }
- /*
- * If we disabled UMS then mount the volume
- */
- if (!enable) {
- doShareUnshareVolume(path, method, enable);
- if (doMountVolume(path) != StorageResultCode.OperationSucceeded) {
- Slog.e(TAG, "Failed to remount " + path +
- " after disabling share method " + method);
- /*
- * Even though the mount failed, the unshare didn't so don't indicate an error.
- * The mountVolume() call will have set the storage state and sent the necessary
- * broadcasts.
- */
+ for (String path : getShareableVolumes()) {
+ /*
+ * If the volume is mounted and we're enabling then unmount it
+ */
+ String vs = getVolumeState(path);
+ String method = "ums";
+ if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
+ // Override for isUsbMassStorageEnabled()
+ setUmsEnabling(enable);
+ UmsEnableCallBack umscb = new UmsEnableCallBack(path, method, true);
+ mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, umscb));
+ // Clear override
+ setUmsEnabling(false);
+ }
+ /*
+ * If we disabled UMS then mount the volume
+ */
+ if (!enable) {
+ doShareUnshareVolume(path, method, enable);
+ if (doMountVolume(path) != StorageResultCode.OperationSucceeded) {
+ Slog.e(TAG, "Failed to remount " + path +
+ " after disabling share method " + method);
+ /*
+ * Even though the mount failed, the unshare didn't so don't indicate an error.
+ * The mountVolume() call will have set the storage state and sent the necessary
+ * broadcasts.
+ */
+ }
}
}
}
@@ -1477,12 +1518,12 @@ class MountService extends IMountService.Stub
public boolean isUsbMassStorageEnabled() {
waitForReady();
- final StorageVolume primary = getPrimaryPhysicalVolume();
- if (primary != null) {
- return doGetVolumeShared(primary.getPath(), "ums");
- } else {
- return false;
+ for (String path : getShareableVolumes()) {
+ if (doGetVolumeShared(path, "ums"))
+ return true;
}
+ // no volume is shared
+ return false;
}
/**
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 3ddae3e..208ae25 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -37,6 +37,7 @@ import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENAB
import android.bluetooth.BluetoothTetheringDataTracker;
import android.content.Context;
+import android.content.res.Resources;
import android.net.INetworkManagementEventObserver;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
@@ -1011,7 +1012,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub
WifiConfiguration wifiConfig, String wlanIface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- wifiFirmwareReload(wlanIface, "AP");
+ if (mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_wifiApFirmwareReload)) {
+ wifiFirmwareReload(wlanIface, "AP");
+ }
+ if (mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_wifiApStartInterface)) {
+ mConnector.execute("softap", "start", wlanIface);
+ }
if (wifiConfig == null) {
mConnector.execute("softap", "set", wlanIface);
} else {
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 37d7ce7..41ef166 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -28,6 +28,8 @@ import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.Notification;
import android.app.PendingIntent;
+import android.app.ProfileGroup;
+import android.app.ProfileManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -62,7 +64,6 @@ import android.util.Slog;
import android.util.Xml;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
-import android.widget.RemoteViews;
import android.widget.Toast;
import com.android.internal.statusbar.StatusBarNotification;
@@ -81,7 +82,10 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import libcore.io.IoUtils;
@@ -143,10 +147,13 @@ public class NotificationManagerService extends INotificationManager.Stub
private IAudioService mAudioService;
private Vibrator mVibrator;
- // for enabling and disabling notification pulse behavior
+ // for enabling and disabling notification pulse behaviour
private boolean mScreenOn = true;
+ private boolean mWasScreenOn = false;
private boolean mInCall = false;
private boolean mNotificationPulseEnabled;
+ private HashMap<String, NotificationLedValues> mNotificationPulseCustomLedValues;
+ private Map<String, String> mPackageNameMappings;
private final ArrayList<NotificationRecord> mNotificationList =
new ArrayList<NotificationRecord>();
@@ -156,6 +163,18 @@ public class NotificationManagerService extends INotificationManager.Stub
private ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>();
private NotificationRecord mLedNotification;
+ private boolean mQuietHoursEnabled = false;
+ // Minutes from midnight when quiet hours begin.
+ private int mQuietHoursStart = 0;
+ // Minutes from midnight when quiet hours end.
+ private int mQuietHoursEnd = 0;
+ // Don't play sounds.
+ private boolean mQuietHoursMute = true;
+ // Don't vibrate.
+ private boolean mQuietHoursStill = true;
+ // Dim LED if hardware supports it.
+ private boolean mQuietHoursDim = true;
+
// Notification control database. For now just contains disabled packages.
private AtomicFile mPolicyFile;
private HashSet<String> mBlockedPackages = new HashSet<String>();
@@ -411,6 +430,12 @@ public class NotificationManagerService extends INotificationManager.Stub
}
}
+ class NotificationLedValues {
+ public int color;
+ public int onMS;
+ public int offMS;
+ }
+
private StatusBarManagerService.NotificationCallbacks mNotificationCallbacks
= new StatusBarManagerService.NotificationCallbacks() {
@@ -519,7 +544,7 @@ public class NotificationManagerService extends INotificationManager.Stub
boolean queryRestart = false;
boolean packageChanged = false;
-
+
if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
|| action.equals(Intent.ACTION_PACKAGE_RESTARTED)
|| (packageChanged=action.equals(Intent.ACTION_PACKAGE_CHANGED))
@@ -562,6 +587,8 @@ public class NotificationManagerService extends INotificationManager.Stub
mScreenOn = true;
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
mScreenOn = false;
+ mWasScreenOn = true;
+ updateLightsLocked();
} else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
mInCall = (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_OFFHOOK));
@@ -578,8 +605,8 @@ public class NotificationManagerService extends INotificationManager.Stub
}
};
- class SettingsObserver extends ContentObserver {
- SettingsObserver(Handler handler) {
+ class LEDSettingsObserver extends ContentObserver {
+ LEDSettingsObserver(Handler handler) {
super(handler);
}
@@ -587,24 +614,100 @@ public class NotificationManagerService extends INotificationManager.Stub
ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.NOTIFICATION_LIGHT_PULSE), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES), false, this);
update();
}
@Override public void onChange(boolean selfChange) {
update();
+ updateNotificationPulse();
}
public void update() {
ContentResolver resolver = mContext.getContentResolver();
- boolean pulseEnabled = Settings.System.getInt(resolver,
- Settings.System.NOTIFICATION_LIGHT_PULSE, 0) != 0;
- if (mNotificationPulseEnabled != pulseEnabled) {
- mNotificationPulseEnabled = pulseEnabled;
- updateNotificationPulse();
+ // LED enabled
+ mNotificationPulseEnabled = Settings.System.getIntForUser(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT) != 0;
+
+ // LED default color
+ mDefaultNotificationColor = Settings.System.getIntForUser(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, mDefaultNotificationColor,
+ UserHandle.USER_CURRENT);
+
+ // LED default on MS
+ mDefaultNotificationLedOn = Settings.System.getIntForUser(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_ON, mDefaultNotificationLedOn,
+ UserHandle.USER_CURRENT);
+
+ // LED default off MS
+ mDefaultNotificationLedOff = Settings.System.getIntForUser(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, mDefaultNotificationLedOff,
+ UserHandle.USER_CURRENT);
+
+ // LED custom notification colors
+ mNotificationPulseCustomLedValues.clear();
+ if (Settings.System.getIntForUser(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_ENABLE, 0,
+ UserHandle.USER_CURRENT) != 0) {
+ parseNotificationPulseCustomValuesString(Settings.System.getStringForUser(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE_CUSTOM_VALUES, UserHandle.USER_CURRENT));
}
}
}
+ class QuietHoursSettingsObserver extends ContentObserver {
+ QuietHoursSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_ENABLED), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_START), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_END), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_MUTE), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_STILL), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QUIET_HOURS_DIM), false, this);
+ update();
+ }
+
+ @Override public void onChange(boolean selfChange) {
+ update();
+ updateNotificationPulse();
+ }
+
+ public void update() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mQuietHoursEnabled = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_ENABLED, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ mQuietHoursStart = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_START, 0, UserHandle.USER_CURRENT_OR_SELF);
+ mQuietHoursEnd = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_END, 0, UserHandle.USER_CURRENT_OR_SELF);
+ mQuietHoursMute = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_MUTE, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ mQuietHoursStill = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_STILL, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ mQuietHoursDim = Settings.System.getIntForUser(resolver,
+ Settings.System.QUIET_HOURS_DIM, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ }
+ }
+
static long[] getLongArray(Resources r, int resid, int maxlen, long[] def) {
int[] ar = r.getIntArray(resid);
if (ar == null) {
@@ -644,6 +747,15 @@ public class NotificationManagerService extends INotificationManager.Stub
mDefaultNotificationLedOff = resources.getInteger(
com.android.internal.R.integer.config_defaultNotificationLedOff);
+ mNotificationPulseCustomLedValues = new HashMap<String, NotificationLedValues>();
+
+ mPackageNameMappings = new HashMap<String, String>();
+ for(String mapping : resources.getStringArray(
+ com.android.internal.R.array.notification_light_package_mapping)) {
+ String[] map = mapping.split("\\|");
+ mPackageNameMappings.put(map[0], map[1]);
+ }
+
mDefaultVibrationPattern = getLongArray(resources,
com.android.internal.R.array.config_defaultNotificationVibePattern,
VIBRATE_PATTERN_MAXLEN,
@@ -681,8 +793,10 @@ public class NotificationManagerService extends INotificationManager.Stub
IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mIntentReceiver, sdFilter);
- SettingsObserver observer = new SettingsObserver(mHandler);
- observer.observe();
+ LEDSettingsObserver ledObserver = new LEDSettingsObserver(mHandler);
+ ledObserver.observe();
+ QuietHoursSettingsObserver qhObserver = new QuietHoursSettingsObserver(mHandler);
+ qhObserver.observe();
}
void systemReady() {
@@ -1000,6 +1114,8 @@ public class NotificationManagerService extends INotificationManager.Stub
final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
synchronized (mNotificationList) {
+ final boolean inQuietHours = inQuietHours();
+
NotificationRecord r = new NotificationRecord(pkg, tag, id,
callingUid, callingPid, userId,
score,
@@ -1076,6 +1192,18 @@ public class NotificationManagerService extends INotificationManager.Stub
}
}
+ try {
+ final ProfileManager profileManager =
+ (ProfileManager) mContext.getSystemService(Context.PROFILE_SERVICE);
+
+ ProfileGroup group = profileManager.getActiveProfileGroup(pkg);
+ if (group != null) {
+ notification = group.processNotification(notification);
+ }
+ } catch(Throwable th) {
+ Log.e(TAG, "An error occurred profiling the notification.", th);
+ }
+
// If we're not supposed to beep, vibrate, etc. then don't.
if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
&& (!(old != null
@@ -1095,7 +1223,7 @@ public class NotificationManagerService extends INotificationManager.Stub
Uri soundUri = null;
boolean hasValidSound = false;
- if (useDefaultSound) {
+ if (!(inQuietHours && mQuietHoursMute) && useDefaultSound) {
soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
// check to see if the default notification sound is silent
@@ -1142,16 +1270,16 @@ public class NotificationManagerService extends INotificationManager.Stub
final boolean convertSoundToVibration =
!hasCustomVibrate
&& hasValidSound
+ && shouldConvertSoundToVibration()
&& (audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE);
// The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
final boolean useDefaultVibrate =
(notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
-
- if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
+ if (!(inQuietHours && mQuietHoursStill)
+ && (useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
&& !(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) {
mVibrateNotification = r;
-
if (useDefaultVibrate || convertSoundToVibration) {
// Escalate privileges so we can use the vibrator even if the notifying app
// does not have the VIBRATE permission.
@@ -1196,6 +1324,26 @@ public class NotificationManagerService extends INotificationManager.Stub
idOut[0] = id;
}
+ private boolean shouldConvertSoundToVibration() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.NOTIFICATION_CONVERT_SOUND_TO_VIBRATION, 1) != 0;
+ }
+
+ private boolean inQuietHours() {
+ if (mQuietHoursEnabled && (mQuietHoursStart != mQuietHoursEnd)) {
+ // Get the date in "quiet hours" format.
+ Calendar calendar = Calendar.getInstance();
+ int minutes = calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE);
+ if (mQuietHoursEnd < mQuietHoursStart) {
+ // Starts at night, ends in the morning.
+ return (minutes > mQuietHoursStart) || (minutes < mQuietHoursEnd);
+ } else {
+ return (minutes > mQuietHoursStart) && (minutes < mQuietHoursEnd);
+ }
+ }
+ return false;
+ }
+
private void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
if (!manager.isEnabled()) {
@@ -1441,17 +1589,45 @@ public class NotificationManagerService extends INotificationManager.Stub
}
}
- // Don't flash while we are in a call or screen is on
- if (mLedNotification == null || mInCall || mScreenOn) {
+ boolean wasScreenOn = mWasScreenOn;
+ mWasScreenOn = false;
+
+ if (mLedNotification == null) {
+ mNotificationLight.turnOff();
+ return;
+ }
+
+ // We can assume that if the user turned the screen off while there was
+ // still an active notification then they wanted to keep the notification
+ // for later. In this case we shouldn't flash the notification light.
+ // For special notifications that automatically turn the screen on (such
+ // as missed calls), we use this flag to force the notification light
+ // even if the screen was turned off.
+ boolean forceWithScreenOff = (mLedNotification.notification.flags &
+ Notification.FLAG_FORCE_LED_SCREEN_OFF) != 0;
+
+ // Don't flash while we are in a call, screen is on or we are in quiet hours with light dimmed
+ if (mInCall || mScreenOn || (inQuietHours() && mQuietHoursDim) || (wasScreenOn && !forceWithScreenOff)) {
mNotificationLight.turnOff();
} else {
- int ledARGB = mLedNotification.notification.ledARGB;
- int ledOnMS = mLedNotification.notification.ledOnMS;
- int ledOffMS = mLedNotification.notification.ledOffMS;
- if ((mLedNotification.notification.defaults & Notification.DEFAULT_LIGHTS) != 0) {
- ledARGB = mDefaultNotificationColor;
- ledOnMS = mDefaultNotificationLedOn;
- ledOffMS = mDefaultNotificationLedOff;
+ int ledARGB;
+ int ledOnMS;
+ int ledOffMS;
+ NotificationLedValues ledValues = getLedValuesForNotification(mLedNotification);
+ if (ledValues != null) {
+ ledARGB = ledValues.color != 0 ? ledValues.color : mDefaultNotificationColor;
+ ledOnMS = ledValues.onMS >= 0 ? ledValues.onMS : mDefaultNotificationLedOn;
+ ledOffMS = ledValues.offMS >= 0 ? ledValues.offMS : mDefaultNotificationLedOn;
+ } else {
+ if ((mLedNotification.notification.defaults & Notification.DEFAULT_LIGHTS) != 0) {
+ ledARGB = mDefaultNotificationColor;
+ ledOnMS = mDefaultNotificationLedOn;
+ ledOffMS = mDefaultNotificationLedOff;
+ } else {
+ ledARGB = mLedNotification.notification.ledARGB;
+ ledOnMS = mLedNotification.notification.ledOnMS;
+ ledOffMS = mLedNotification.notification.ledOffMS;
+ }
}
if (mNotificationPulseEnabled) {
// pulse repeatedly
@@ -1461,6 +1637,47 @@ public class NotificationManagerService extends INotificationManager.Stub
}
}
+ private void parseNotificationPulseCustomValuesString(String customLedValuesString) {
+ if (TextUtils.isEmpty(customLedValuesString)) {
+ return;
+ }
+
+ for (String packageValuesString : customLedValuesString.split("\\|")) {
+ String[] packageValues = packageValuesString.split("=");
+ if (packageValues.length != 2) {
+ Log.e(TAG, "Error parsing custom led values for unknown package");
+ continue;
+ }
+ String packageName = packageValues[0];
+ String[] values = packageValues[1].split(";");
+ if (values.length != 3) {
+ Log.e(TAG, "Error parsing custom led values '" + packageValues[1] + "' for " + packageName);
+ continue;
+ }
+ NotificationLedValues ledValues = new NotificationLedValues();
+ try {
+ ledValues.color = Integer.parseInt(values[0]);
+ ledValues.onMS = Integer.parseInt(values[1]);
+ ledValues.offMS = Integer.parseInt(values[2]);
+ } catch (Exception e) {
+ Log.e(TAG, "Error parsing custom led values '" + packageValues[1] + "' for " + packageName);
+ continue;
+ }
+ mNotificationPulseCustomLedValues.put(packageName, ledValues);
+ }
+ }
+
+ private NotificationLedValues getLedValuesForNotification(NotificationRecord ledNotification) {
+ return mNotificationPulseCustomLedValues.get(mapPackage(ledNotification.pkg));
+ }
+
+ private String mapPackage(String pkg) {
+ if(!mPackageNameMappings.containsKey(pkg)) {
+ return pkg;
+ }
+ return mPackageNameMappings.get(pkg);
+ }
+
// lock on mNotificationList
private int indexOfNotificationLocked(String pkg, String tag, int id, int userId)
{
@@ -1517,7 +1734,6 @@ public class NotificationManagerService extends INotificationManager.Stub
}
pw.println(" ");
}
-
}
synchronized (mNotificationList) {
diff --git a/services/java/com/android/server/ProfileManagerService.java b/services/java/com/android/server/ProfileManagerService.java
new file mode 100644
index 0000000..c7f12ee
--- /dev/null
+++ b/services/java/com/android/server/ProfileManagerService.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import android.app.IProfileManager;
+import android.app.NotificationGroup;
+import android.app.Profile;
+import android.app.ProfileGroup;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.XmlResourceParser;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.os.ParcelUuid;
+
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/** {@hide} */
+public class ProfileManagerService extends IProfileManager.Stub {
+ // Enable the below for detailed logging of this class
+ private static final boolean LOCAL_LOGV = false;
+ /**
+ * <p>Broadcast Action: A new profile has been selected. This can be triggered by the user
+ * or by calls to the ProfileManagerService / Profile.</p>
+ * @hide
+ */
+ public static final String INTENT_ACTION_PROFILE_SELECTED = "android.intent.action.PROFILE_SELECTED";
+
+ public static final String PERMISSION_CHANGE_SETTINGS = "android.permission.WRITE_SETTINGS";
+
+ private static final String PROFILE_FILENAME = "/data/system/profiles.xml";
+
+ private static final String TAG = "ProfileService";
+
+ private Map<UUID, Profile> mProfiles;
+
+ // Match UUIDs and names, used for reverse compatibility
+ private Map<String, UUID> mProfileNames;
+
+ private Map<UUID, NotificationGroup> mGroups;
+
+ private Profile mActiveProfile;
+
+ // Well-known UUID of the wildcard group
+ private static final UUID mWildcardUUID = UUID.fromString("a126d48a-aaef-47c4-baed-7f0e44aeffe5");
+ private NotificationGroup mWildcardGroup;
+
+ private Context mContext;
+ private boolean mDirty;
+
+ private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
+ persistIfDirty();
+ initialize();
+ } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
+ persistIfDirty();
+ }
+ }
+ };
+
+ public ProfileManagerService(Context context) {
+ mContext = context;
+
+ mWildcardGroup = new NotificationGroup(
+ context.getString(com.android.internal.R.string.wildcardProfile),
+ com.android.internal.R.string.wildcardProfile,
+ mWildcardUUID);
+
+ initialize();
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_LOCALE_CHANGED);
+ filter.addAction(Intent.ACTION_SHUTDOWN);
+ mContext.registerReceiver(mIntentReceiver, filter);
+ }
+
+ private void initialize() {
+ initialize(false);
+ }
+
+ private void initialize(boolean skipFile) {
+ mProfiles = new HashMap<UUID, Profile>();
+ mProfileNames = new HashMap<String, UUID>();
+ mGroups = new HashMap<UUID, NotificationGroup>();
+ mDirty = false;
+
+ boolean init = skipFile;
+
+ if (! skipFile) {
+ try {
+ loadFromFile();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (XmlPullParserException e) {
+ init = true;
+ } catch (IOException e) {
+ init = true;
+ }
+ }
+
+ if (init) {
+ try {
+ initialiseStructure();
+ } catch (Throwable ex) {
+ Log.e(TAG, "Error loading xml from resource: ", ex);
+ }
+ }
+ }
+
+ @Override
+ public void resetAll() {
+ enforceChangePermissions();
+ initialize(true);
+ }
+
+ @Override
+ @Deprecated
+ public boolean setActiveProfileByName(String profileName) throws RemoteException, SecurityException {
+ if (mProfileNames.containsKey(profileName)) {
+ if (LOCAL_LOGV) Log.v(TAG, "setActiveProfile(String) found profile name in mProfileNames.");
+ return setActiveProfile(mProfiles.get(mProfileNames.get(profileName)), true);
+ } else {
+ // Since profileName could not be casted into a UUID, we can call it a string.
+ Log.w(TAG, "Unable to find profile to set active, based on string: " + profileName);
+ return false;
+ }
+ }
+
+ @Override
+ public boolean setActiveProfile(ParcelUuid profileParcelUuid) throws RemoteException, SecurityException {
+ UUID profileUuid = profileParcelUuid.getUuid();
+ if(mProfiles.containsKey(profileUuid)){
+ if (LOCAL_LOGV) Log.v(TAG, "setActiveProfileByUuid(ParcelUuid) found profile UUID in mProfileNames.");
+ return setActiveProfile(mProfiles.get(profileUuid), true);
+ } else {
+ Log.e(TAG, "Cannot set active profile to: " + profileUuid.toString() + " - does not exist.");
+ return false;
+ }
+ }
+
+ private boolean setActiveProfile(UUID profileUuid, boolean doinit) throws RemoteException {
+ if(mProfiles.containsKey(profileUuid)){
+ if (LOCAL_LOGV) Log.v(TAG, "setActiveProfile(UUID, boolean) found profile UUID in mProfiles.");
+ return setActiveProfile(mProfiles.get(profileUuid), doinit);
+ } else {
+ Log.e(TAG, "Cannot set active profile to: " + profileUuid.toString() + " - does not exist.");
+ return false;
+ }
+ }
+
+ private boolean setActiveProfile(Profile newActiveProfile, boolean doinit) throws RemoteException {
+ /*
+ * NOTE: Since this is not a public function, and all public functions
+ * take either a string or a UUID, the active profile should always be
+ * in the collection. If writing another setActiveProfile which receives
+ * a Profile object, run enforceChangePermissions, add the profile to the
+ * list, and THEN add it.
+ */
+
+ try {
+ enforceChangePermissions();
+ Log.d(TAG, "Set active profile to: " + newActiveProfile.getUuid().toString() + " - " + newActiveProfile.getName());
+ Profile lastProfile = mActiveProfile;
+ mActiveProfile = newActiveProfile;
+ mDirty = true;
+ if (doinit) {
+ if (LOCAL_LOGV) Log.v(TAG, "setActiveProfile(Profile, boolean) - Running init");
+
+ /*
+ * We need to clear the caller's identity in order to
+ * - allow the profile switch to execute actions not included in the caller's permissions
+ * - broadcast INTENT_ACTION_PROFILE_SELECTED
+ */
+ long token = clearCallingIdentity();
+
+ // Call profile's "doSelect"
+ mActiveProfile.doSelect(mContext);
+
+ // Notify other applications of newly selected profile.
+ Intent broadcast = new Intent(INTENT_ACTION_PROFILE_SELECTED);
+ broadcast.putExtra("name", mActiveProfile.getName());
+ broadcast.putExtra("uuid", mActiveProfile.getUuid().toString());
+ broadcast.putExtra("lastName", lastProfile.getName());
+ broadcast.putExtra("lastUuid", lastProfile.getUuid().toString());
+ mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL);
+
+ restoreCallingIdentity(token);
+ persistIfDirty();
+ }
+ return true;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public boolean addProfile(Profile profile) throws RemoteException, SecurityException {
+ enforceChangePermissions();
+ addProfileInternal(profile);
+ persistIfDirty();
+ return true;
+ }
+
+ private void addProfileInternal(Profile profile) {
+ // Make sure this profile has all of the correct groups.
+ for (NotificationGroup group : mGroups.values()) {
+ ensureGroupInProfile(profile, group, false);
+ }
+ ensureGroupInProfile(profile, mWildcardGroup, true);
+ mProfiles.put(profile.getUuid(), profile);
+ mProfileNames.put(profile.getName(), profile.getUuid());
+ mDirty = true;
+ }
+
+ private void ensureGroupInProfile(Profile profile, NotificationGroup group, boolean defaultGroup) {
+ if (profile.getProfileGroup(group.getUuid()) != null) {
+ return;
+ }
+
+ /* enforce a matchup between profile and notification group, which not only
+ * works by UUID, but also by name for backwards compatibility */
+ for (ProfileGroup pg : profile.getProfileGroups()) {
+ if (pg.matches(group, defaultGroup)) {
+ return;
+ }
+ }
+
+ /* didn't find any, create new group */
+ profile.addProfileGroup(new ProfileGroup(group.getUuid(), defaultGroup));
+ }
+
+ @Override
+ @Deprecated
+ public Profile getProfileByName(String profileName) throws RemoteException {
+ if (mProfileNames.containsKey(profileName)) {
+ return mProfiles.get(mProfileNames.get(profileName));
+ } else if (mProfiles.containsKey(UUID.fromString((profileName)))) {
+ return mProfiles.get(UUID.fromString(profileName));
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Profile getProfile(ParcelUuid profileParcelUuid) {
+ UUID profileUuid = profileParcelUuid.getUuid();
+ return getProfile(profileUuid);
+ }
+
+ public Profile getProfile(UUID profileUuid) {
+ // use primary UUID first
+ if (mProfiles.containsKey(profileUuid)) {
+ return mProfiles.get(profileUuid);
+ }
+ // if no match was found: try secondary UUID
+ for (Profile p : mProfiles.values()) {
+ for (UUID uuid : p.getSecondaryUuids()) {
+ if (profileUuid.equals(uuid)) {
+ return p;
+ }
+ }
+ }
+ // nothing found
+ return null;
+ }
+
+ @Override
+ public Profile[] getProfiles() throws RemoteException {
+ Profile[] tmpArr = mProfiles.values().toArray(new Profile[mProfiles.size()]);
+ Arrays.sort(tmpArr);
+ return tmpArr;
+ }
+
+ @Override
+ public Profile getActiveProfile() throws RemoteException {
+ return mActiveProfile;
+ }
+
+ @Override
+ public boolean removeProfile(Profile profile) throws RemoteException, SecurityException {
+ enforceChangePermissions();
+ if (mProfileNames.remove(profile.getName()) != null && mProfiles.remove(profile.getUuid()) != null) {
+ mDirty = true;
+ persistIfDirty();
+ return true;
+ } else{
+ return false;
+ }
+ }
+
+ @Override
+ public void updateProfile(Profile profile) throws RemoteException, SecurityException {
+ enforceChangePermissions();
+ Profile old = mProfiles.get(profile.getUuid());
+ if (old != null) {
+ mProfileNames.remove(old.getName());
+ mProfileNames.put(profile.getName(), profile.getUuid());
+ mProfiles.put(profile.getUuid(), profile);
+ /* no need to set mDirty, if the profile was actually changed,
+ * it's marked as dirty by itself */
+ persistIfDirty();
+
+ // Also update we changed the active profile
+ if (mActiveProfile != null && mActiveProfile.getUuid().equals(profile.getUuid())) {
+ setActiveProfile(profile, true);
+ }
+ }
+ }
+
+ @Override
+ public boolean profileExists(ParcelUuid profileUuid) throws RemoteException {
+ return mProfiles.containsKey(profileUuid.getUuid());
+ }
+
+ @Override
+ public boolean profileExistsByName(String profileName) throws RemoteException {
+ for (Map.Entry<String, UUID> entry : mProfileNames.entrySet()) {
+ if (entry.getKey().equalsIgnoreCase(profileName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean notificationGroupExistsByName(String notificationGroupName) throws RemoteException {
+ for (NotificationGroup group : mGroups.values()) {
+ if (group.getName().equalsIgnoreCase(notificationGroupName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public NotificationGroup[] getNotificationGroups() throws RemoteException {
+ return mGroups.values().toArray(new NotificationGroup[mGroups.size()]);
+ }
+
+ @Override
+ public void addNotificationGroup(NotificationGroup group) throws RemoteException, SecurityException {
+ enforceChangePermissions();
+ addNotificationGroupInternal(group);
+ persistIfDirty();
+ }
+
+ private void addNotificationGroupInternal(NotificationGroup group) {
+ if (mGroups.put(group.getUuid(), group) == null) {
+ // If the above is true, then the ProfileGroup shouldn't exist in
+ // the profile. Ensure it is added.
+ for (Profile profile : mProfiles.values()) {
+ ensureGroupInProfile(profile, group, false);
+ }
+ }
+ mDirty = true;
+ }
+
+ @Override
+ public void removeNotificationGroup(NotificationGroup group) throws RemoteException, SecurityException {
+ enforceChangePermissions();
+ mDirty |= (mGroups.remove(group.getUuid()) != null);
+ // Remove the corresponding ProfileGroup from all the profiles too if
+ // they use it.
+ for (Profile profile : mProfiles.values()) {
+ profile.removeProfileGroup(group.getUuid());
+ }
+ persistIfDirty();
+ }
+
+ @Override
+ public void updateNotificationGroup(NotificationGroup group) throws RemoteException, SecurityException {
+ enforceChangePermissions();
+ NotificationGroup old = mGroups.get(group.getUuid());
+ if (old != null) {
+ mGroups.put(group.getUuid(), group);
+ /* no need to set mDirty, if the group was actually changed,
+ * it's marked as dirty by itself */
+ persistIfDirty();
+ }
+ }
+
+ @Override
+ public NotificationGroup getNotificationGroupForPackage(String pkg) throws RemoteException {
+ for (NotificationGroup group : mGroups.values()) {
+ if (group.hasPackage(pkg)) {
+ return group;
+ }
+ }
+ return null;
+ }
+
+ private void loadFromFile() throws RemoteException, XmlPullParserException, IOException {
+ XmlPullParserFactory xppf = XmlPullParserFactory.newInstance();
+ XmlPullParser xpp = xppf.newPullParser();
+ FileReader fr = new FileReader(PROFILE_FILENAME);
+ xpp.setInput(fr);
+ loadXml(xpp, mContext);
+ fr.close();
+ persistIfDirty();
+ }
+
+ private void loadXml(XmlPullParser xpp, Context context) throws
+ XmlPullParserException, IOException, RemoteException {
+ int event = xpp.next();
+ String active = null;
+ while (event != XmlPullParser.END_TAG || !"profiles".equals(xpp.getName())) {
+ if (event == XmlPullParser.START_TAG) {
+ String name = xpp.getName();
+ if (name.equals("active")) {
+ active = xpp.nextText();
+ Log.d(TAG, "Found active: " + active);
+ } else if (name.equals("profile")) {
+ Profile prof = Profile.fromXml(xpp, context);
+ addProfileInternal(prof);
+ // Failsafe if no active found
+ if (active == null) {
+ active = prof.getUuid().toString();
+ }
+ } else if (name.equals("notificationGroup")) {
+ NotificationGroup ng = NotificationGroup.fromXml(xpp, context);
+ addNotificationGroupInternal(ng);
+ }
+ } else if (event == XmlPullParser.END_DOCUMENT) {
+ throw new IOException("Premature end of file while reading " + PROFILE_FILENAME);
+ }
+ event = xpp.next();
+ }
+ // Don't do initialisation on startup. The AudioManager doesn't exist yet
+ // and besides, the volume settings will have survived the reboot.
+ try {
+ // Try / catch block to detect if XML file needs to be upgraded.
+ setActiveProfile(UUID.fromString(active), false);
+ } catch (IllegalArgumentException e) {
+ if (mProfileNames.containsKey(active)) {
+ setActiveProfile(mProfileNames.get(active), false);
+ } else {
+ // Final fail-safe: We must have SOME profile active.
+ // If we couldn't select one by now, we'll pick the first in the set.
+ setActiveProfile(mProfiles.values().iterator().next(), false);
+ }
+ // This is a hint that we probably just upgraded the XML file. Save changes.
+ mDirty = true;
+ }
+ }
+
+ private void initialiseStructure() throws RemoteException, XmlPullParserException, IOException {
+ XmlResourceParser xml = mContext.getResources().getXml(
+ com.android.internal.R.xml.profile_default);
+ try {
+ loadXml(xml, mContext);
+ mDirty = true;
+ persistIfDirty();
+ } finally {
+ xml.close();
+ }
+ }
+
+ private String getXmlString() throws RemoteException {
+ StringBuilder builder = new StringBuilder();
+ builder.append("<profiles>\n<active>");
+ builder.append(TextUtils.htmlEncode(getActiveProfile().getUuid().toString()));
+ builder.append("</active>\n");
+
+ for (Profile p : mProfiles.values()) {
+ p.getXmlString(builder, mContext);
+ }
+ for (NotificationGroup g : mGroups.values()) {
+ g.getXmlString(builder, mContext);
+ }
+ builder.append("</profiles>\n");
+ return builder.toString();
+ }
+
+ @Override
+ public NotificationGroup getNotificationGroup(ParcelUuid uuid) throws RemoteException {
+ if (uuid.getUuid().equals(mWildcardGroup.getUuid())) {
+ return mWildcardGroup;
+ }
+ return mGroups.get(uuid.getUuid());
+ }
+
+ private synchronized void persistIfDirty() {
+ boolean dirty = mDirty;
+ if (!dirty) {
+ for (Profile profile : mProfiles.values()) {
+ if (profile.isDirty()) {
+ dirty = true;
+ break;
+ }
+ }
+ }
+ if (!dirty) {
+ for (NotificationGroup group : mGroups.values()) {
+ if (group.isDirty()) {
+ dirty = true;
+ break;
+ }
+ }
+ }
+ if (dirty) {
+ try {
+ Log.d(TAG, "Saving profile data...");
+ FileWriter fw = new FileWriter(PROFILE_FILENAME);
+ fw.write(getXmlString());
+ fw.close();
+ Log.d(TAG, "Save completed.");
+ mDirty = false;
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void enforceChangePermissions() throws SecurityException {
+ mContext.enforceCallingOrSelfPermission(PERMISSION_CHANGE_SETTINGS,
+ "You do not have permissions to change the Profile Manager.");
+ }
+}
diff --git a/services/java/com/android/server/RotationSwitchObserver.java b/services/java/com/android/server/RotationSwitchObserver.java
new file mode 100644
index 0000000..a191433
--- /dev/null
+++ b/services/java/com/android/server/RotationSwitchObserver.java
@@ -0,0 +1,163 @@
+/*
+ * 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.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.UEventObserver;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+
+import android.widget.Toast;
+import android.view.IWindowManager;
+import android.os.ServiceManager;
+import android.os.RemoteException;
+import android.os.AsyncTask;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+/**
+ * <p>RotationLockObserver monitors for rotation lock switch state
+ */
+class RotationSwitchObserver extends UEventObserver {
+ private static final String TAG = RotationSwitchObserver.class
+ .getSimpleName();
+ private static final boolean LOG = true;
+
+ private static final String LOCK_UEVENT_MATCH =
+ "DEVPATH=/devices/virtual/switch/rotationlock";
+ private static final String LOCK_STATE_PATH =
+ "/sys/class/switch/rotationlock/state";
+
+ private static final int MSG_LOCK_STATE = 0;
+
+ private int mLockState;
+ private int mPreviousLockState;
+
+ private boolean mSystemReady;
+
+ private final Context mContext;
+
+ private boolean mAutoRotation;
+
+ public RotationSwitchObserver(Context context) {
+ mContext = context;
+ init(); // set initial status
+
+ startObserving(LOCK_UEVENT_MATCH);
+ }
+
+ @Override
+ public void onUEvent(UEventObserver.UEvent event) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Slog.v(TAG, "Switch UEVENT: " + event.toString());
+ }
+
+ synchronized (this) {
+ try {
+ int newState = Integer.parseInt(event.get("SWITCH_STATE"));
+ if (newState != mLockState) {
+ mPreviousLockState = mLockState;
+ mLockState = newState;
+ if (mSystemReady) {
+ update();
+ }
+ }
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "Could not parse switch state from event "
+ + event);
+ }
+ }
+ }
+
+ private final void init() {
+ char[] buffer = new char[1024];
+
+ try {
+ FileReader file = new FileReader(LOCK_STATE_PATH);
+ int len = file.read(buffer, 0, 1024);
+ file.close();
+ mPreviousLockState = mLockState =
+ Integer.valueOf((new String(buffer, 0, len)).trim());
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "This kernel does not have rotation switch support");
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "" , e);
+ } catch (IOException e) {
+ Slog.e(TAG, "" , e);
+ }
+ }
+
+ void systemReady() {
+ synchronized (this) {
+ mSystemReady = true;
+ }
+ }
+
+ private final void update() {
+ mHandler.sendEmptyMessage(MSG_LOCK_STATE);
+ }
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_LOCK_STATE:
+ synchronized (this) {
+ boolean autoRotate = mLockState == 0;
+ int toastId = autoRotate
+ ? com.android.internal.R.string.toast_rotation_unlocked
+ : com.android.internal.R.string.toast_rotation_locked;
+
+ setAutoRotation(autoRotate);
+
+ Toast.makeText(mContext, mContext.getString(toastId),
+ Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+ }
+ };
+
+ private void setAutoRotation(final boolean autorotate) {
+ mAutoRotation = autorotate;
+ AsyncTask.execute(new Runnable() {
+ public void run() {
+ try {
+ IWindowManager wm = IWindowManager.Stub.asInterface(
+ ServiceManager
+ .getService(Context.WINDOW_SERVICE));
+ if (autorotate) {
+ wm.thawRotation();
+ } else {
+ wm.freezeRotation(-1);
+ }
+ } catch (RemoteException exc) {
+ Log.w(TAG, "Unable to save auto-rotate setting");
+ }
+ }
+ });
+ }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 55885e6..b2ea635 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +25,11 @@ import android.content.ContentResolver;
import android.content.ContentService;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.database.Cursor;
import android.media.AudioService;
import android.net.wifi.p2p.WifiP2pService;
import android.os.Handler;
@@ -38,6 +42,7 @@ import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.provider.Settings;
import android.server.search.SearchManagerService;
import android.service.dreams.DreamService;
import android.util.DisplayMetrics;
@@ -71,6 +76,8 @@ import dalvik.system.Zygote;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
+import com.stericsson.hardware.fm.FmReceiverService;
+import com.stericsson.hardware.fm.FmTransmitterService;
class ServerThread extends Thread {
private static final String TAG = "SystemServer";
@@ -84,6 +91,19 @@ class ServerThread extends Thread {
Log.wtf(TAG, "BOOT FAILURE " + msg, e);
}
+ private class AdbPortObserver extends ContentObserver {
+ public AdbPortObserver() {
+ super(null);
+ }
+ @Override
+ public void onChange(boolean selfChange) {
+ int adbPort = Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ADB_PORT, 0);
+ // setting this will control whether ADB runs on TCP/IP or USB
+ SystemProperties.set("service.adb.tcp.port", Integer.toString(adbPort));
+ }
+ }
+
@Override
public void run() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
@@ -126,6 +146,7 @@ class ServerThread extends Thread {
LightsService lights = null;
PowerManagerService power = null;
DisplayManagerService display = null;
+ DeviceHandlerService device = null;
BatteryService battery = null;
VibratorService vibrator = null;
AlarmManagerService alarm = null;
@@ -142,6 +163,7 @@ class ServerThread extends Thread {
WindowManagerService wm = null;
BluetoothManagerService bluetooth = null;
DockObserver dock = null;
+ RotationSwitchObserver rotateSwitch = null;
UsbService usb = null;
SerialService serial = null;
TwilightService twilight = null;
@@ -281,11 +303,15 @@ class ServerThread extends Thread {
Slog.i(TAG, "System Content Providers");
ActivityManagerService.installSystemProviders();
+ // Requires context, activity manager y providers
+ Slog.i(TAG, "Device Handler Service");
+ device = new DeviceHandlerService(context);
+
Slog.i(TAG, "Lights Service");
lights = new LightsService(context);
Slog.i(TAG, "Battery Service");
- battery = new BatteryService(context, lights);
+ battery = new BatteryService(context, lights, device);
ServiceManager.addService("battery", battery);
Slog.i(TAG, "Vibrator Service");
@@ -310,7 +336,7 @@ class ServerThread extends Thread {
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power, display, inputManager,
- uiHandler, wmHandler,
+ device, uiHandler, wmHandler,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
!firstBoot, onlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
@@ -342,10 +368,14 @@ class ServerThread extends Thread {
Slog.e("System", "************ Failure starting core service", e);
}
+ boolean hasRotationLock = context.getResources().getBoolean(com.android
+ .internal.R.bool.config_hasRotationLockSwitch);
+
DevicePolicyManagerService devicePolicy = null;
StatusBarManagerService statusBar = null;
InputMethodManagerService imm = null;
AppWidgetService appWidget = null;
+ ProfileManagerService profile = null;
NotificationManagerService notification = null;
WallpaperManagerService wallpaper = null;
LocationManagerService location = null;
@@ -522,6 +552,21 @@ class ServerThread extends Thread {
}
try {
+ Slog.i(TAG, "FM receiver Service");
+ ServiceManager.addService("fm_receiver",
+ new FmReceiverService(context));
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting FM receiver Service", e);
+ }
+
+ try {
+ Slog.i(TAG, "FM transmitter Service");
+ ServiceManager.addService("fm_transmitter",
+ new FmTransmitterService(context));
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting FM transmitter Service", e);
+ }
+ try {
Slog.i(TAG, "UpdateLock Service");
ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
new UpdateLockService(context));
@@ -553,6 +598,14 @@ class ServerThread extends Thread {
}
try {
+ Slog.i(TAG, "Profile Manager");
+ profile = new ProfileManagerService(context);
+ ServiceManager.addService(Context.PROFILE_SERVICE, profile);
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting Profile Manager", e);
+ }
+
+ try {
Slog.i(TAG, "Notification Manager");
notification = new NotificationManagerService(context, statusBar, lights);
ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
@@ -632,7 +685,17 @@ class ServerThread extends Thread {
}
try {
- Slog.i(TAG, "Wired Accessory Manager");
+ if (hasRotationLock) {
+ Slog.i(TAG, "Rotation Switch Observer");
+ // Listen for switch changes
+ rotateSwitch = new RotationSwitchObserver(context);
+ }
+ } catch (Throwable e) {
+ reportWtf("starting RotationSwitchObserver", e);
+ }
+
+ try {
+ Slog.i(TAG, "Wired Accessory Observer");
// Listen for wired headset changes
inputManager.setWiredAccessoryCallbacks(
new WiredAccessoryManager(context, inputManager));
@@ -748,8 +811,24 @@ class ServerThread extends Thread {
reportWtf("starting DreamManagerService", e);
}
}
+
+ try {
+ Slog.i(TAG, "AssetRedirectionManager Service");
+ ServiceManager.addService("assetredirection", new AssetRedirectionManagerService(context));
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting AssetRedirectionManager Service", e);
+ }
}
+ // make sure the ADB_ENABLED setting value matches the secure property value
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ADB_PORT,
+ Integer.parseInt(SystemProperties.get("service.adb.tcp.port", "-1")));
+
+ // register observer to listen for settings changes
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.ADB_PORT),
+ false, new AdbPortObserver());
+
// Before things start rolling, be sure we have decided whether
// we are in safe mode.
final boolean safeMode = wm.detectSafeMode();
@@ -831,6 +910,15 @@ class ServerThread extends Thread {
reportWtf("making Display Manager Service ready", e);
}
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_APP_LAUNCH_FAILURE);
+ filter.addAction(Intent.ACTION_APP_LAUNCH_FAILURE_RESET);
+ filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addCategory(Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE);
+ filter.addDataScheme("package");
+ context.registerReceiver(new AppsLaunchFailureReceiver(), filter);
+
// These are needed to propagate to the runnable below.
final Context contextF = context;
final MountService mountServiceF = mountService;
@@ -840,6 +928,7 @@ class ServerThread extends Thread {
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
final DockObserver dockF = dock;
+ final RotationSwitchObserver rotateSwitchF = rotateSwitch;
final UsbService usbF = usb;
final ThrottleService throttleF = throttle;
final TwilightService twilightF = twilight;
@@ -904,6 +993,11 @@ class ServerThread extends Thread {
reportWtf("making Dock Service ready", e);
}
try {
+ if (rotateSwitchF != null) rotateSwitchF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Rotation Switch Service ready", e);
+ }
+ try {
if (usbF != null) usbF.systemReady();
} catch (Throwable e) {
reportWtf("making USB Service ready", e);
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index 75eb3c4..9bc3a91 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -53,6 +53,7 @@ import android.util.Slog;
import android.util.TrustedTime;
import com.android.internal.R;
+import com.android.internal.app.ThemeUtils;
import com.android.internal.telephony.TelephonyProperties;
import java.io.BufferedWriter;
@@ -80,6 +81,7 @@ public class ThrottleService extends IThrottleManager.Stub {
private HandlerThread mThread;
private Context mContext;
+ private Context mUiContext;
private static final int INITIAL_POLL_DELAY_SEC = 90;
private static final int TESTING_POLLING_PERIOD_SEC = 60 * 1;
@@ -339,6 +341,13 @@ public class ThrottleService extends IThrottleManager.Stub {
}
}, new IntentFilter(ACTION_RESET));
+ ThemeUtils.registerThemeChangeReceiver(mContext, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ });
+
// use a new thread as we don't want to stall the system for file writes
mThread = new HandlerThread(TAG);
mThread.start();
@@ -685,12 +694,18 @@ public class ThrottleService extends IThrottleManager.Stub {
}
mThrottlingNotification.flags = flags;
mThrottlingNotification.tickerText = title;
- mThrottlingNotification.setLatestEventInfo(mContext, title, message, pi);
+ mThrottlingNotification.setLatestEventInfo(getUiContext(), title, message, pi);
mNotificationManager.notifyAsUser(null, mThrottlingNotification.icon,
mThrottlingNotification, UserHandle.ALL);
}
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
private void clearThrottleAndNotification() {
if (mThrottleIndex.get() != THROTTLE_INDEX_UNTHROTTLED) {
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 0e456f1..797990e 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -48,6 +48,7 @@ import java.io.PrintWriter;
import com.android.internal.R;
import com.android.internal.app.DisableCarModeActivity;
import com.android.server.TwilightService.TwilightState;
+import com.android.internal.app.ThemeUtils;
final class UiModeManagerService extends IUiModeManager.Stub {
private static final String TAG = UiModeManager.class.getSimpleName();
@@ -60,6 +61,7 @@ final class UiModeManagerService extends IUiModeManager.Stub {
private final Context mContext;
private final TwilightService mTwilightService;
private final Handler mHandler = new Handler();
+ private Context mUiContext;
final Object mLock = new Object();
@@ -142,6 +144,13 @@ final class UiModeManagerService extends IUiModeManager.Stub {
}
};
+ private final BroadcastReceiver mThemeChangeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ };
+
private final TwilightService.TwilightListener mTwilightListener =
new TwilightService.TwilightListener() {
@Override
@@ -161,6 +170,8 @@ final class UiModeManagerService extends IUiModeManager.Stub {
mContext.registerReceiver(mBatteryReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ ThemeUtils.registerThemeChangeReceiver(mContext, mThemeChangeReceiver);
+
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
@@ -549,7 +560,7 @@ final class UiModeManagerService extends IUiModeManager.Stub {
n.flags = Notification.FLAG_ONGOING_EVENT;
n.when = 0;
n.setLatestEventInfo(
- mContext,
+ getUiContext(),
mContext.getString(R.string.car_mode_disable_notification_title),
mContext.getString(R.string.car_mode_disable_notification_message),
PendingIntent.getActivityAsUser(mContext, 0, carModeOffIntent, 0,
@@ -579,6 +590,13 @@ final class UiModeManagerService extends IUiModeManager.Stub {
}
}
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index df91dec..805fd16 100755
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -39,6 +39,7 @@ import android.provider.Settings.SettingNotFoundException;
import android.util.Slog;
import android.view.InputDevice;
+import java.util.Calendar;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;
@@ -164,6 +165,29 @@ public class VibratorService extends IVibratorService.Stub
return doVibratorExists();
}
+ private boolean inQuietHours() {
+ boolean quietHoursEnabled = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.QUIET_HOURS_ENABLED, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ int quietHoursStart = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.QUIET_HOURS_START, 0, UserHandle.USER_CURRENT_OR_SELF);
+ int quietHoursEnd = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.QUIET_HOURS_END, 0, UserHandle.USER_CURRENT_OR_SELF);
+ boolean quietHoursHaptic = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.QUIET_HOURS_HAPTIC, 0, UserHandle.USER_CURRENT_OR_SELF) != 0;
+ if (quietHoursEnabled && quietHoursHaptic && (quietHoursStart != quietHoursEnd)) {
+ // Get the date in "quiet hours" format.
+ Calendar calendar = Calendar.getInstance();
+ int minutes = calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE);
+ if (quietHoursEnd < quietHoursStart) {
+ // Starts at night, ends in the morning.
+ return (minutes > quietHoursStart) || (minutes < quietHoursEnd);
+ } else {
+ return (minutes > quietHoursStart) && (minutes < quietHoursEnd);
+ }
+ }
+ return false;
+ }
+
public void vibrate(long milliseconds, IBinder token) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
!= PackageManager.PERMISSION_GRANTED) {
@@ -174,7 +198,7 @@ public class VibratorService extends IVibratorService.Stub
// timeout of 0 or negative. This will ensure that a vibration has
// either a timeout of > 0 or a non-null pattern.
if (milliseconds <= 0 || (mCurrentVibration != null
- && mCurrentVibration.hasLongerTimeout(milliseconds))) {
+ && mCurrentVibration.hasLongerTimeout(milliseconds)) || inQuietHours()) {
// Ignore this vibration since the current vibration will play for
// longer than milliseconds.
return;
@@ -204,6 +228,9 @@ public class VibratorService extends IVibratorService.Stub
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires VIBRATE permission");
}
+ if (inQuietHours()) {
+ return;
+ }
int uid = Binder.getCallingUid();
// so wakelock calls will succeed
long identity = Binder.clearCallingIdentity();
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 21a1956..97dd98f 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -639,6 +639,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
throw new IllegalArgumentException("width and height must be > 0");
}
+ int maxWidth = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_wallpaperMaxWidth);
+ if (maxWidth != -1 && width > maxWidth) {
+ width = maxWidth;
+ }
+
if (width != wallpaper.width || height != wallpaper.height) {
wallpaper.width = width;
wallpaper.height = height;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 98794c9..2104097 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -887,6 +887,15 @@ public class WifiService extends IWifiManager.Stub {
mWifiStateMachine.setCountryCode(countryCode, persist);
}
+
+ /**
+ * Get the operational country code
+ */
+ public String getCountryCode() {
+ enforceAccessPermission();
+ return mWifiStateMachine.getCountryCode();
+ }
+
/**
* Set the operational frequency band
* @param band One of
diff --git a/services/java/com/android/server/WiredAccessoryManager.java b/services/java/com/android/server/WiredAccessoryManager.java
index d5c9c8f..3499fa0 100644
--- a/services/java/com/android/server/WiredAccessoryManager.java
+++ b/services/java/com/android/server/WiredAccessoryManager.java
@@ -79,6 +79,8 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
private int mSwitchValues;
+ private boolean dockAudioEnabled = false;
+
private final WiredAccessoryObserver mObserver;
private final InputManagerService mInputManager;
@@ -96,6 +98,12 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
mObserver = new WiredAccessoryObserver();
+ File f = new File("/sys/class/switch/dock/state");
+ if (f!=null && f.exists()) {
+ // Listen out for changes to the Dock Audio Settings
+ context.registerReceiver(new SettingsChangedReceiver(),
+ new IntentFilter("com.cyanogenmod.settings.SamsungDock"), null, null);
+ }
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context ctx, Intent intent) {
@@ -105,6 +113,23 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
}
+ private final class SettingsChangedReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ Slog.e(TAG, "Recieved a Settings Changed Action " + action);
+ if (action.equals("com.cyanogenmod.settings.SamsungDock")) {
+ String data = intent.getStringExtra("data");
+ Slog.e(TAG, "Recieved a Dock Audio change " + data);
+ if (data != null && data.equals("1")) {
+ dockAudioEnabled = true;
+ } else {
+ dockAudioEnabled = false;
+ }
+ }
+ }
+ }
+
private void bootCompleted() {
if (mUseDevInputEventForAudioJack) {
int switchValues = 0;
@@ -300,7 +325,8 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
FileReader file = new FileReader(uei.getSwitchStatePath());
int len = file.read(buffer, 0, 1024);
file.close();
- curState = Integer.valueOf((new String(buffer, 0, len)).trim());
+ curState = validateSwitchState(
+ Integer.valueOf((new String(buffer, 0, len)).trim()));
if (curState > 0) {
updateStateLocked(uei.getDevPath(), uei.getDevName(), curState);
@@ -315,14 +341,23 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
}
// At any given time accessories could be inserted
- // one on the board, one on the dock and one on HDMI:
- // observe three UEVENTs
+ // one on the board, one on the dock, one on the
+ // samsung dock and one on HDMI:
+ // observe all UEVENTs that have valid switch supported
+ // by the Kernel
for (int i = 0; i < mUEventInfo.size(); ++i) {
UEventInfo uei = mUEventInfo.get(i);
startObserving("DEVPATH="+uei.getDevPath());
}
}
+ private int validateSwitchState(int state) {
+ // Some drivers, namely HTC headset ones, add additional bits to
+ // the switch state. As we only are able to deal with the states
+ // 0, 1 and 2, mask out all the other bits
+ return state & 0x3;
+ }
+
private List<UEventInfo> makeObservedUEventList() {
List<UEventInfo> retVal = new ArrayList<UEventInfo>();
UEventInfo uei;
@@ -345,6 +380,14 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
Slog.w(TAG, "This kernel does not have usb audio support");
}
+ // Monitor Samsung USB audio
+ uei = new UEventInfo("dock", BIT_USB_HEADSET_DGTL, BIT_USB_HEADSET_ANLG);
+ if (uei.checkSwitchExists()) {
+ retVal.add(uei);
+ } else {
+ Slog.w(TAG, "This kernel does not have samsung usb dock audio support");
+ }
+
// Monitor HDMI
//
// If the kernel has support for the "hdmi_audio" switch, use that. It will be
@@ -372,10 +415,20 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
public void onUEvent(UEventObserver.UEvent event) {
if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());
+ int state = validateSwitchState(Integer.parseInt(event.get("SWITCH_STATE")));
try {
String devPath = event.get("DEVPATH");
String name = event.get("SWITCH_NAME");
- int state = Integer.parseInt(event.get("SWITCH_STATE"));
+ if (name.equals("dock")) {
+ // Samsung USB Audio Jack is non-sensing - so must be enabled manually
+ // The choice is made in the GalaxyS2Settings.apk
+ // device/samsung/i9100/DeviceSettings/src/com/cyanogenmod/settings/device/DockFragmentActivity.java
+ // This sends an Intent to this class
+ if ((!dockAudioEnabled) && (state > 0)) {
+ Slog.e(TAG, "Ignoring dock event as Audio routing disabled " + event);
+ return;
+ }
+ }
synchronized (mLock) {
updateStateLocked(devPath, name, state);
}
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 671cbfe..a34d44c 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1123,7 +1123,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return;
}
mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
- .setIcon(android.R.drawable.ic_dialog_alert)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1d08d31..c068982 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006-2008 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +20,7 @@ package com.android.server.am;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import com.android.internal.R;
+import com.android.internal.app.ThemeUtils;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.ProcessStats;
import com.android.server.AttributeCache;
@@ -86,6 +88,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.content.res.CustomTheme;
import android.graphics.Bitmap;
import android.net.Proxy;
import android.net.ProxyProperties;
@@ -159,6 +162,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
+import dalvik.system.Zygote;
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@@ -666,6 +670,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean mLaunchWarningShown = false;
Context mContext;
+ Context mUiContext;
int mFactoryTest;
@@ -935,7 +940,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return;
}
if (mShowDialogs && !mSleeping && !mShuttingDown) {
- Dialog d = new AppErrorDialog(mContext,
+ Dialog d = new AppErrorDialog(getUiContext(),
ActivityManagerService.this, res, proc);
d.show();
proc.crashDialog = d;
@@ -970,7 +975,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mShowDialogs) {
Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
- mContext, proc, (ActivityRecord)data.get("activity"),
+ getUiContext(), proc, (ActivityRecord)data.get("activity"),
msg.arg1 != 0);
d.show();
proc.anrDialog = d;
@@ -996,7 +1001,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
AppErrorResult res = (AppErrorResult) data.get("result");
if (mShowDialogs && !mSleeping && !mShuttingDown) {
- Dialog d = new StrictModeViolationDialog(mContext,
+ Dialog d = new StrictModeViolationDialog(getUiContext(),
ActivityManagerService.this, res, proc);
d.show();
proc.crashDialog = d;
@@ -1010,7 +1015,7 @@ public final class ActivityManagerService extends ActivityManagerNative
} break;
case SHOW_FACTORY_ERROR_MSG: {
Dialog d = new FactoryErrorDialog(
- mContext, msg.getData().getCharSequence("msg"));
+ getUiContext(), msg.getData().getCharSequence("msg"));
d.show();
ensureBootCompleted();
} break;
@@ -1030,7 +1035,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!app.waitedForDebugger) {
Dialog d = new AppWaitingForDebuggerDialog(
ActivityManagerService.this,
- mContext, app);
+ getUiContext(), app);
app.waitDialog = d;
app.waitedForDebugger = true;
d.show();
@@ -1112,7 +1117,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Log.e(TAG, title + ": " + text);
if (mShowDialogs) {
// XXX This is a temporary dialog, no need to localize.
- AlertDialog d = new BaseErrorDialog(mContext);
+ AlertDialog d = new BaseErrorDialog(getUiContext());
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
d.setCancelable(false);
d.setTitle(title);
@@ -1183,7 +1188,7 @@ public final class ActivityManagerService extends ActivityManagerNative
notification.defaults = 0; // please be quiet
notification.sound = null;
notification.vibrate = null;
- notification.setLatestEventInfo(context, text,
+ notification.setLatestEventInfo(getUiContext(), text,
mContext.getText(R.string.heavy_weight_notification_detail),
PendingIntent.getActivityAsUser(mContext, 0, root.intent,
PendingIntent.FLAG_CANCEL_CURRENT, null,
@@ -1798,6 +1803,15 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ private Context getUiContext() {
+ synchronized (this) {
+ if (mUiContext == null && mBooted) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
+ }
+
/**
* Initialize the application bind args. These are passed to each
* process when the bindApplication() IPC is sent to the process. They're
@@ -3406,7 +3420,7 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public void run() {
synchronized (ActivityManagerService.this) {
- final Dialog d = new LaunchWarningWindow(mContext, cur, next);
+ final Dialog d = new LaunchWarningWindow(getUiContext(), cur, next);
d.show();
mHandler.postDelayed(new Runnable() {
@Override
@@ -4389,6 +4403,13 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}, pkgFilter);
+ ThemeUtils.registerThemeChangeReceiver(mContext, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ });
+
synchronized (this) {
// Ensure that any processes we had put on hold are now started
// up.
@@ -9164,7 +9185,7 @@ public final class ActivityManagerService extends ActivityManagerNative
TaskRecord tr = mRecentTasks.get(i);
if (dumpPackage != null) {
if (tr.realActivity == null ||
- !dumpPackage.equals(tr.realActivity)) {
+ !dumpPackage.equals(tr.realActivity.getPackageName())) {
continue;
}
}
@@ -12321,6 +12342,11 @@ public final class ActivityManagerService extends ActivityManagerNative
values.userSetLocale);
}
+ if (values.customTheme != null) {
+ saveThemeResourceLocked(values.customTheme,
+ !values.customTheme.equals(mConfiguration.customTheme));
+ }
+
mConfigurationSeq++;
if (mConfigurationSeq <= 0) {
mConfigurationSeq = 1;
@@ -12540,6 +12566,13 @@ public final class ActivityManagerService extends ActivityManagerNative
return srec.launchedFromUid;
}
+ private void saveThemeResourceLocked(CustomTheme t, boolean isDiff){
+ if(isDiff){
+ SystemProperties.set(Configuration.THEME_ID_PERSISTENCE_PROPERTY, t.getThemeId());
+ SystemProperties.set(Configuration.THEME_PACKAGE_NAME_PERSISTENCE_PROPERTY, t.getThemePackageName());
+ }
+ }
+
// =========================================================
// LIFETIME MANAGEMENT
// =========================================================
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 27dd732..885ec89 100755..100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -22,6 +22,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
+import com.android.server.power.PowerManagerService;
import android.app.Activity;
import android.app.ActivityManager;
@@ -53,13 +54,16 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.view.Display;
import android.view.WindowManagerPolicy;
+import com.android.internal.app.ActivityTrigger;
import java.io.IOException;
import java.lang.ref.WeakReference;
@@ -306,6 +310,18 @@ final class ActivityStack {
}
}
+ private static final ActivityTrigger mActivityTrigger;
+
+ private final PowerManagerService mPm;
+
+ static {
+ if (SystemProperties.QCOM_HARDWARE) {
+ mActivityTrigger = new ActivityTrigger();
+ } else {
+ mActivityTrigger = null;
+ }
+ }
+
final Handler mHandler = new Handler() {
//public Handler() {
// if (localLOGV) Slog.v(TAG, "Handler started!");
@@ -418,6 +434,7 @@ final class ActivityStack {
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
+ mPm = (PowerManagerService) ServiceManager.getService("power");
mLaunchingActivity.setReferenceCounted(false);
}
@@ -1404,6 +1421,9 @@ final class ActivityStack {
}
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
+
+ mPm.cpuBoost(1500000);
+
// Find the first activity that is not finishing.
ActivityRecord next = topRunningActivityLocked(null);
@@ -1468,6 +1488,10 @@ final class ActivityStack {
if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);
+ if (mActivityTrigger != null) {
+ mActivityTrigger.activityResumeTrigger(next.intent);
+ }
+
// If we are currently pausing an activity, then don't do anything
// until that is done.
if (mPausingActivity != null) {
@@ -2460,6 +2484,8 @@ final class ActivityStack {
int err = ActivityManager.START_SUCCESS;
+ mPm.cpuBoost(1500000);
+
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
@@ -2478,6 +2504,9 @@ final class ActivityStack {
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));
+ if (mActivityTrigger != null) {
+ mActivityTrigger.activityStartTrigger(intent);
+ }
}
ActivityRecord sourceRecord = null;
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index e4a7ead..8f154b1 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -47,6 +47,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
+import com.android.internal.app.ThemeUtils;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.IState;
@@ -74,6 +75,7 @@ import java.util.Set;
public class Tethering extends INetworkManagementEventObserver.Stub {
private Context mContext;
+ private Context mUiContext;
private final static String TAG = "Tethering";
private final static boolean DBG = true;
private final static boolean VDBG = false;
@@ -158,6 +160,13 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(mStateReceiver, filter);
+ ThemeUtils.registerThemeChangeReceiver(mContext, new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context content, Intent intent) {
+ mUiContext = null;
+ }
+ });
+
filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_SHARED);
filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
@@ -478,12 +487,19 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
mTetheredNotification.defaults &= ~Notification.DEFAULT_SOUND;
mTetheredNotification.flags = Notification.FLAG_ONGOING_EVENT;
mTetheredNotification.tickerText = title;
- mTetheredNotification.setLatestEventInfo(mContext, title, message, pi);
+ mTetheredNotification.setLatestEventInfo(getUiContext(), title, message, pi);
notificationManager.notifyAsUser(null, mTetheredNotification.icon,
mTetheredNotification, UserHandle.ALL);
}
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
+ }
+
private void clearTetheredNotification() {
NotificationManager notificationManager =
(NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 5e4907e..9921b5c 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -179,6 +179,7 @@ public class InputManagerService extends IInputManager.Stub
InputChannel fromChannel, InputChannel toChannel);
private static native void nativeSetPointerSpeed(int ptr, int speed);
private static native void nativeSetShowTouches(int ptr, boolean enabled);
+ private static native void nativeSetStylusIconEnabled(int ptr, boolean enabled);
private static native void nativeVibrate(int ptr, int deviceId, long[] pattern,
int repeat, int token);
private static native void nativeCancelVibrate(int ptr, int deviceId, int token);
@@ -269,6 +270,7 @@ public class InputManagerService extends IInputManager.Stub
registerPointerSpeedSettingObserver();
registerShowTouchesSettingObserver();
+ registerStylusIconEnabledSettingObserver();
mContext.registerReceiver(new BroadcastReceiver() {
@Override
@@ -280,6 +282,7 @@ public class InputManagerService extends IInputManager.Stub
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
+ updateStylusIconEnabledFromSettings();
}
// TODO(BT) Pass in paramter for bluetooth system
@@ -1123,6 +1126,32 @@ public class InputManagerService extends IInputManager.Stub
return speed;
}
+ public void updateStylusIconEnabledFromSettings() {
+ int enabled = getStylusIconEnabled(0);
+ nativeSetStylusIconEnabled(mPtr, enabled != 0);
+ }
+
+ public void registerStylusIconEnabledSettingObserver() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STYLUS_ICON_ENABLED), false,
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateStylusIconEnabledFromSettings();
+ }
+ });
+ }
+
+ private int getStylusIconEnabled(int defaultValue) {
+ int result = defaultValue;
+ try {
+ result = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STYLUS_ICON_ENABLED);
+ } catch (SettingNotFoundException snfe) {
+ }
+ return result;
+ }
+
public void updateShowTouchesFromSettings() {
int setting = getShowTouchesSetting(0);
nativeSetShowTouches(mPtr, setting != 0);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 2238f17..1833457 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +32,7 @@ import static libcore.io.OsConstants.S_IXGRP;
import static libcore.io.OsConstants.S_IROTH;
import static libcore.io.OsConstants.S_IXOTH;
+import com.android.internal.app.IAssetRedirectionManager;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
@@ -143,6 +145,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -150,6 +153,9 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
import libcore.io.ErrnoException;
import libcore.io.IoUtils;
@@ -201,6 +207,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// package apks to install directory.
private static final String INSTALL_PACKAGE_SUFFIX = "-";
+ private static final int THEME_MAMANER_GUID = 1300;
+
static final int SCAN_MONITOR = 1<<0;
static final int SCAN_NO_DEX = 1<<1;
static final int SCAN_FORCE_DEX = 1<<2;
@@ -407,6 +415,8 @@ public class PackageManagerService extends IPackageManager.Stub {
ComponentName mResolveComponentName;
PackageParser.Package mPlatformPackage;
+ IAssetRedirectionManager mAssetRedirectionManager;
+
// Set of pending broadcasts for aggregating enable/disable of components.
final HashMap<String, ArrayList<String>> mPendingBroadcasts
= new HashMap<String, ArrayList<String>>();
@@ -706,7 +716,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageInstalledInfo res = data.res;
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
- res.removedInfo.sendBroadcast(false, true, false);
+ res.removedInfo.sendBroadcast(false, true, false, false);
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, res.uid);
// Determine the set of users who are adding this
@@ -743,21 +753,25 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
- res.pkg.applicationInfo.packageName,
+ res.pkg.applicationInfo.packageName, null,
extras, null, null, firstUsers);
final boolean update = res.removedInfo.removedPackage != null;
if (update) {
extras.putBoolean(Intent.EXTRA_REPLACING, true);
}
+ String category = null;
+ if(res.pkg.mIsThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
- res.pkg.applicationInfo.packageName,
+ res.pkg.applicationInfo.packageName, category,
extras, null, null, updateUsers);
if (update) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
- res.pkg.applicationInfo.packageName,
+ res.pkg.applicationInfo.packageName, category,
extras, null, null, updateUsers);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
- null, null,
+ null, null, null,
res.pkg.applicationInfo.packageName, null, updateUsers);
}
if (res.removedInfo.args != null) {
@@ -975,6 +989,7 @@ public class PackageManagerService extends IPackageManager.Stub {
Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
+ mSettings.addSharedUserLPw("com.tmobile.thememanager", THEME_MAMANER_GUID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
@@ -2943,6 +2958,20 @@ public class PackageManagerService extends IPackageManager.Stub {
return list;
}
+ public List<PackageInfo> getInstalledThemePackages() {
+ // Returns a list of theme APKs.
+ ArrayList<PackageInfo> finalList = new ArrayList<PackageInfo>();
+ List<PackageInfo> installedPackagesList = mContext.getPackageManager().getInstalledPackages(0);
+ Iterator<PackageInfo> i = installedPackagesList.iterator();
+ while (i.hasNext()) {
+ final PackageInfo pi = i.next();
+ if (pi != null && pi.isThemeApk) {
+ finalList.add(pi);
+ }
+ }
+ return finalList;
+ }
+
@Override
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
String lastRead, int userId) {
@@ -3682,6 +3711,20 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ if (!pkg.applicationInfo.sourceDir.startsWith(Environment.getRootDirectory().getPath()) &&
+ !pkg.applicationInfo.sourceDir.startsWith("/vendor")) {
+ Object obj = mSettings.getUserIdLPr(1000);
+ Signature[] s1 = null;
+ if (obj instanceof SharedUserSetting) {
+ s1 = ((SharedUserSetting)obj).signatures.mSignatures;
+ }
+ if ((compareSignatures(pkg.mSignatures, s1) == PackageManager.SIGNATURE_MATCH)) {
+ Slog.w(TAG, "Cannot install platform packages to user storage");
+ mLastScanError = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
+ return null;
+ }
+ }
+
// Initialize package source and resource directories
File destCodeFile = new File(pkg.applicationInfo.sourceDir);
File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
@@ -4100,7 +4143,10 @@ public class PackageManagerService extends IPackageManager.Stub {
* Update native library dir if it starts with
* /data/data
*/
- if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
+ // For devices using /datadata, dataPathString will point
+ // to /datadata while nativeLibraryDir will point to /data/data.
+ // Thus, compare to /data/data directly to avoid problems.
+ if (nativeLibraryDir.getPath().startsWith("/data/data")) {
setInternalAppNativeLibraryPath(pkg, pkgSetting);
nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
}
@@ -4500,6 +4546,32 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ // NOTE: this method can return null if the SystemServer is still
+ // initializing
+ public IAssetRedirectionManager getAssetRedirectionManager() {
+ if (mAssetRedirectionManager != null) {
+ return mAssetRedirectionManager;
+ }
+ IBinder b = ServiceManager.getService("assetredirection");
+ mAssetRedirectionManager = IAssetRedirectionManager.Stub.asInterface(b);
+ return mAssetRedirectionManager;
+ }
+
+ private void cleanAssetRedirections(PackageParser.Package pkg) {
+ IAssetRedirectionManager rm = getAssetRedirectionManager();
+ if (rm == null) {
+ return;
+ }
+ try {
+ if (pkg.mIsThemeApk) {
+ rm.clearRedirectionMapsByTheme(pkg.packageName, null);
+ } else {
+ rm.clearPackageRedirectionMap(pkg.packageName);
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
void removePackageLI(PackageSetting ps, boolean chatty) {
if (DEBUG_INSTALL) {
if (chatty)
@@ -4528,6 +4600,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
+ cleanAssetRedirections(pkg);
+
mPackages.remove(pkg.applicationInfo.packageName);
if (pkg.mPath != null) {
mAppDirs.remove(pkg.mPath);
@@ -5372,7 +5446,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
};
- static final void sendPackageBroadcast(String action, String pkg,
+ static final void sendPackageBroadcast(String action, String pkg, String intentCategory,
Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
int[] userIds) {
IActivityManager am = ActivityManagerNative.getDefault();
@@ -5405,6 +5479,9 @@ public class PackageManagerService extends IPackageManager.Stub {
+ intent.toShortString(false, true, false, false)
+ " " + intent.getExtras(), here);
}
+ if (intentCategory != null) {
+ intent.addCategory(intentCategory);
+ }
am.broadcastIntent(null, intent, null, finishedReceiver,
0, null, null, null, finishedReceiver != null, false, id);
}
@@ -5488,6 +5565,7 @@ public class PackageManagerService extends IPackageManager.Stub {
String addedPackage = null;
int addedAppId = -1;
int[] addedUsers = null;
+ String category = null;
// TODO post a message to the handler to obtain serial ordering
synchronized (mInstallLock) {
@@ -5518,6 +5596,9 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
p = mAppDirs.get(fullPathStr);
if (p != null) {
+ if (p.mIsThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
ps = mSettings.mPackages.get(p.applicationInfo.packageName);
if (ps != null) {
removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
@@ -5559,6 +5640,9 @@ public class PackageManagerService extends IPackageManager.Stub {
addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
}
}
+ if (p != null && p.mIsThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
}
// reader
@@ -5571,13 +5655,13 @@ public class PackageManagerService extends IPackageManager.Stub {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, removedAppId);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, category,
extras, null, null, removedUsers);
}
if (addedPackage != null) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, addedAppId);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage, category,
extras, null, null, addedUsers);
}
}
@@ -5674,7 +5758,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (sendAdded) {
- sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, null,
packageName, extras, null, null, new int[] {userId});
}
} finally {
@@ -7809,6 +7893,24 @@ public class PackageManagerService extends IPackageManager.Stub {
Log.d(TAG, "New package installed in " + newPackage.mPath);
+ cleanAssetRedirections(newPackage);
+
+ if (newPackage.mIsThemeApk) {
+ /* DBS-TODO
+ boolean isThemePackageDrmProtected = false;
+ int N = newPackage.mThemeInfos.size();
+ for (int i = 0; i < N; i++) {
+ if (newPackage.mThemeInfos.get(i).isDrmProtected) {
+ isThemePackageDrmProtected = true;
+ break;
+ }
+ }
+ if (isThemePackageDrmProtected) {
+ splitThemePackage(newPackage.mPath);
+ }
+ */
+ }
+
synchronized (mPackages) {
updatePermissionsLPw(newPackage.packageName, newPackage,
UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
@@ -7824,6 +7926,65 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ private void deleteLockedZipFileIfExists(String originalPackagePath) {
+ String lockedZipFilePath = PackageParser.getLockedZipFilePath(originalPackagePath);
+ File zipFile = new File(lockedZipFilePath);
+ if (zipFile.exists() && zipFile.isFile()) {
+ if (!zipFile.delete()) {
+ Log.w(TAG, "Couldn't delete locked zip file: " + originalPackagePath);
+ }
+ }
+ }
+ private void splitThemePackage(File originalFile) {
+ final String originalPackagePath = originalFile.getPath();
+ final String lockedZipFilePath = PackageParser.getLockedZipFilePath(originalPackagePath);
+
+ try {
+ final List<String> drmProtectedEntries = new ArrayList<String>();
+ final ZipFile privateZip = new ZipFile(originalFile.getPath());
+
+ final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries();
+ while (privateZipEntries.hasMoreElements()) {
+ final ZipEntry zipEntry = privateZipEntries.nextElement();
+ final String zipEntryName = zipEntry.getName();
+ if (zipEntryName.startsWith("assets/") && zipEntryName.contains("/locked/")) {
+ drmProtectedEntries.add(zipEntryName);
+ }
+ }
+ privateZip.close();
+
+ String [] args = new String[0];
+ args = drmProtectedEntries.toArray(args);
+ int code = mContext.getAssets().splitDrmProtectedThemePackage(
+ originalPackagePath,
+ lockedZipFilePath,
+ args);
+ if (code != 0) {
+ Log.e("PackageManagerService",
+ "splitDrmProtectedThemePackage returned = " + code);
+ }
+ code = FileUtils.setPermissions(
+ lockedZipFilePath,
+ 0640,
+ -1,
+ THEME_MAMANER_GUID);
+ if (code != 0) {
+ Log.e("PackageManagerService",
+ "Set permissions for " + lockedZipFilePath + " returned = " + code);
+ }
+ code = FileUtils.setPermissions(
+ originalPackagePath,
+ 0644,
+ -1, -1);
+ if (code != 0) {
+ Log.e("PackageManagerService",
+ "Set permissions for " + originalPackagePath + " returned = " + code);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Failure to generate new zip files for theme");
+ }
+ }
+
private void installPackageLI(InstallArgs args,
boolean newInstall, PackageInstalledInfo res) {
int pFlags = args.flags;
@@ -8084,6 +8245,18 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean removedForAllUsers = false;
boolean systemUpdate = false;
+
+ synchronized (mPackages) {
+ PackageParser.Package p = mPackages.get(packageName);
+ if (p != null) {
+ info.isThemeApk = p.mIsThemeApk;
+ if (info.isThemeApk &&
+ !info.isRemovedPackageSystemUpdate) {
+ deleteLockedZipFileIfExists(p.mPath);
+ }
+ }
+ }
+
synchronized (mInstallLock) {
res = deletePackageLI(packageName,
(flags & PackageManager.DELETE_ALL_USERS) != 0
@@ -8096,7 +8269,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (res) {
- info.sendBroadcast(true, systemUpdate, removedForAllUsers);
+ info.sendBroadcast(true, systemUpdate, removedForAllUsers, true);
// If the removed package was a system update, the old system package
// was re-enabled; we need to broadcast this information
@@ -8106,11 +8279,16 @@ public class PackageManagerService extends IPackageManager.Stub {
? info.removedAppId : info.uid);
extras.putBoolean(Intent.EXTRA_REPLACING, true);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+ String category = null;
+ if (info.isThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
+
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, category,
extras, null, null, null);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, category,
extras, null, null, null);
- sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
+ sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null,
null, packageName, null, null);
}
}
@@ -8135,8 +8313,10 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean isRemovedPackageSystemUpdate = false;
// Clean up resources deleted packages.
InstallArgs args = null;
+ boolean isThemeApk = false;
- void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
+ void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers,
+ boolean deleteLockedZipFileIfExists) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
@@ -8145,15 +8325,19 @@ public class PackageManagerService extends IPackageManager.Stub {
}
extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
if (removedPackage != null) {
- sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
+ String category = null;
+ if (isThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, category,
extras, null, null, removedUsers);
if (fullRemove && !replacing) {
- sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, category,
extras, null, null, removedUsers);
}
}
if (removedAppId >= 0) {
- sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
+ sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, null, extras, null, null,
removedUsers);
}
}
@@ -8732,6 +8916,7 @@ public class PackageManagerService extends IPackageManager.Stub {
"replacePreferredActivity expects filter to have no data authorities, " +
"paths, schemes or types.");
}
+
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -9007,7 +9192,7 @@ public class PackageManagerService extends IPackageManager.Stub {
extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
extras.putInt(Intent.EXTRA_UID, packageUid);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, null, extras, null, null,
new int[] {UserHandle.getUserId(packageUid)});
}
@@ -9670,7 +9855,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
: Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
- sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
+ sendPackageBroadcast(action, null, null, extras, null, finishedReceiver, null);
}
}
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 06f11bc..1f568fb 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -2481,7 +2481,7 @@ final class Settings {
if (pkgSetting.getNotLaunched(userId)) {
if (pkgSetting.installerPackageName != null) {
PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
- pkgSetting.name, null,
+ pkgSetting.name, null, null,
pkgSetting.installerPackageName, null, new int[] {userId});
}
pkgSetting.setNotLaunched(false, userId);
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index b5010f2..5c84a58 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -767,6 +767,8 @@ final class DisplayPowerController {
if (on) {
mNotifier.onScreenOn();
} else {
+ mLights.getLight(LightsService.LIGHT_ID_BUTTONS).setBrightness(0);
+ mLights.getLight(LightsService.LIGHT_ID_KEYBOARD).setBrightness(0);
mNotifier.onScreenOff();
}
}
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 546f22e..156c08f 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -148,6 +148,7 @@ public final class PowerManagerService extends IPowerManager.Stub
// This is subtracted from the end of the screen off timeout so the
// minimum screen off timeout should be longer than this.
private static final int SCREEN_DIM_DURATION = 7 * 1000;
+ private static final int BUTTON_ON_DURATION = 5 * 1000;
// The maximum screen dim time expressed as a ratio relative to the screen
// off timeout. If the screen off timeout is very short then we want the
@@ -166,6 +167,9 @@ public final class PowerManagerService extends IPowerManager.Stub
// effectively and terminate the dream.
private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5;
+ // Max time (microseconds) to allow a CPU boost for
+ private static final int MAX_CPU_BOOST_TIME = 5000000;
+
private Context mContext;
private LightsService mLightsService;
private BatteryService mBatteryService;
@@ -180,6 +184,8 @@ public final class PowerManagerService extends IPowerManager.Stub
private SettingsObserver mSettingsObserver;
private DreamManagerService mDreamManager;
private LightsService.Light mAttentionLight;
+ private LightsService.Light mButtonsLight;
+ private LightsService.Light mKeyboardLight;
private final Object mLock = new Object();
@@ -335,6 +341,11 @@ public final class PowerManagerService extends IPowerManager.Stub
// Use -1 to disable.
private int mScreenBrightnessOverrideFromWindowManager = -1;
+ // The button brightness setting override from the window manager
+ // to allow the current foreground activity to override the button brightness.
+ // Use -1 to disable.
+ private int mButtonBrightnessOverrideFromWindowManager = -1;
+
// The user activity timeout override from the window manager
// to allow the current foreground activity to override the user activity timeout.
// Use -1 to disable.
@@ -363,6 +374,8 @@ public final class PowerManagerService extends IPowerManager.Stub
private static native void nativeReleaseSuspendBlocker(String name);
private static native void nativeSetInteractive(boolean enable);
private static native void nativeSetAutoSuspend(boolean enable);
+ private static native void nativeCpuBoost(int duration);
+ private boolean mKeyboardVisible = false;
public PowerManagerService() {
synchronized (mLock) {
@@ -440,6 +453,8 @@ public final class PowerManagerService extends IPowerManager.Stub
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"));
mSettingsObserver = new SettingsObserver(mHandler);
mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
+ mButtonsLight = mLightsService.getLight(LightsService.LIGHT_ID_BUTTONS);
+ mKeyboardLight = mLightsService.getLight(LightsService.LIGHT_ID_KEYBOARD);
// Register for broadcasts from other components of the system.
IntentFilter filter = new IntentFilter();
@@ -879,6 +894,18 @@ public final class PowerManagerService extends IPowerManager.Stub
}
@Override // Binder call
+ public void setKeyboardVisibility(boolean visible) {
+ synchronized (mLock) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "setKeyboardVisibility: " + visible);
+ }
+ if (mKeyboardVisible != visible) {
+ mKeyboardVisible = visible;
+ }
+ }
+ }
+
+ @Override // Binder call
public void wakeUp(long eventTime) {
if (eventTime > SystemClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
@@ -1300,6 +1327,19 @@ public final class PowerManagerService extends IPowerManager.Stub
nextTimeout = mLastUserActivityTime
+ screenOffTimeout - screenDimDuration;
if (now < nextTimeout) {
+ if (now > mLastUserActivityTime + BUTTON_ON_DURATION) {
+ mButtonsLight.setBrightness(0);
+ mKeyboardLight.setBrightness(0);
+ } else {
+ int brightness = mButtonBrightnessOverrideFromWindowManager >= 0
+ ? mButtonBrightnessOverrideFromWindowManager
+ : mDisplayPowerRequest.screenBrightness;
+ mButtonsLight.setBrightness(brightness);
+ mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
+ if (brightness != 0) {
+ nextTimeout = now + BUTTON_ON_DURATION;
+ }
+ }
mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
} else {
nextTimeout = mLastUserActivityTime + screenOffTimeout;
@@ -1824,6 +1864,20 @@ public final class PowerManagerService extends IPowerManager.Stub
}
}
+ /**
+ * Boost the CPU
+ * @param duration Duration to boost the CPU for, in milliseconds.
+ * @hide
+ */
+ @Override // Binder call
+ public void cpuBoost(int duration) {
+ if (duration > 0 && duration <= MAX_CPU_BOOST_TIME) {
+ nativeCpuBoost(duration);
+ } else {
+ Log.e(TAG, "Invalid boost duration: " + duration);
+ }
+ }
+
private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
final String reason, boolean wait) {
if (mHandler == null || !mSystemReady) {
@@ -2028,9 +2082,24 @@ public final class PowerManagerService extends IPowerManager.Stub
* @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);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ setButtonBrightnessOverrideFromWindowManagerInternal(brightness);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void setButtonBrightnessOverrideFromWindowManagerInternal(int brightness) {
+ synchronized (mLock) {
+ if (mButtonBrightnessOverrideFromWindowManager != brightness) {
+ mButtonBrightnessOverrideFromWindowManager = brightness;
+ mDirty |= DIRTY_SETTINGS;
+ updatePowerStateLocked();
+ }
+ }
}
/**
diff --git a/services/java/com/android/server/power/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java
index c7f7390..3660657 100644
--- a/services/java/com/android/server/power/ShutdownThread.java
+++ b/services/java/com/android/server/power/ShutdownThread.java
@@ -47,6 +47,7 @@ import com.android.internal.telephony.ITelephony;
import android.util.Log;
import android.view.WindowManager;
+import android.view.KeyEvent;
public final class ShutdownThread extends Thread {
// constants
@@ -129,22 +130,62 @@ public final class ShutdownThread extends Thread {
if (sConfirmDialog != null) {
sConfirmDialog.dismiss();
}
- sConfirmDialog = new AlertDialog.Builder(context)
- .setTitle(mRebootSafeMode
- ? com.android.internal.R.string.reboot_safemode_title
- : com.android.internal.R.string.power_off)
- .setMessage(resourceId)
- .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- beginShutdownSequence(context);
- }
- })
- .setNegativeButton(com.android.internal.R.string.no, null)
- .create();
+ if (mReboot && !mRebootSafeMode){
+ sConfirmDialog = new AlertDialog.Builder(context)
+ .setTitle(com.android.internal.R.string.reboot_system)
+ .setSingleChoiceItems(com.android.internal.R.array.shutdown_reboot_options, 0, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which < 0)
+ return;
+
+ String actions[] = context.getResources().getStringArray(com.android.internal.R.array.shutdown_reboot_actions);
+
+ if (actions != null && which < actions.length)
+ mRebootReason = actions[which];
+ }
+ })
+ .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mReboot = true;
+ beginShutdownSequence(context);
+ }
+ })
+ .setNegativeButton(com.android.internal.R.string.no, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mReboot = false;
+ dialog.cancel();
+ }
+ })
+ .create();
+ sConfirmDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
+ public boolean onKey (DialogInterface dialog, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ mReboot = false;
+ dialog.cancel();
+ }
+ return true;
+ }
+ });
+ } else {
+ sConfirmDialog = new AlertDialog.Builder(context)
+ .setTitle(mRebootSafeMode
+ ? com.android.internal.R.string.reboot_safemode_title
+ : com.android.internal.R.string.power_off)
+ .setMessage(resourceId)
+ .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ beginShutdownSequence(context);
+ }
+ })
+ .setNegativeButton(com.android.internal.R.string.no, null)
+ .create();
+ }
+
closer.dialog = sConfirmDialog;
sConfirmDialog.setOnDismissListener(closer);
sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
sConfirmDialog.show();
+
} else {
beginShutdownSequence(context);
}
@@ -213,8 +254,13 @@ public final class ShutdownThread extends Thread {
// throw up an indeterminate system dialog to indicate radio is
// shutting down.
ProgressDialog pd = new ProgressDialog(context);
- pd.setTitle(context.getText(com.android.internal.R.string.power_off));
- pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
+ if (mReboot) {
+ pd.setTitle(context.getText(com.android.internal.R.string.reboot_system));
+ pd.setMessage(context.getText(com.android.internal.R.string.reboot_progress));
+ } else {
+ pd.setTitle(context.getText(com.android.internal.R.string.power_off));
+ pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
+ }
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
@@ -294,7 +340,7 @@ public final class ShutdownThread extends Thread {
}
Log.i(TAG, "Sending shutdown broadcast...");
-
+
// First send the high-level shut down broadcast.
mActionDone = false;
mContext.sendOrderedBroadcastAsUser(new Intent(Intent.ACTION_SHUTDOWN),
@@ -314,9 +360,9 @@ public final class ShutdownThread extends Thread {
}
}
}
-
+
Log.i(TAG, "Shutting down activity manager...");
-
+
final IActivityManager am =
ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
if (am != null) {
diff --git a/services/java/com/android/server/usb/LegacyUsbDeviceManager.java b/services/java/com/android/server/usb/LegacyUsbDeviceManager.java
new file mode 100644
index 0000000..dd9ba66
--- /dev/null
+++ b/services/java/com/android/server/usb/LegacyUsbDeviceManager.java
@@ -0,0 +1,676 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions an
+ * limitations under the License.
+ */
+
+package com.android.server.usb;
+
+import android.app.PendingIntent;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
+import android.os.SystemProperties;
+import android.os.UEventObserver;
+import android.provider.Settings;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+/**
+ * LegacyUsbDeviceManager manages USB state in devices with legacy USB stacks.
+ */
+public class LegacyUsbDeviceManager extends UsbDeviceManager {
+
+ private static final String TAG = LegacyUsbDeviceManager.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private static final String USB_CONNECTED_MATCH =
+ "DEVPATH=/devices/virtual/switch/usb_connected";
+ private static final String USB_CONFIGURATION_MATCH =
+ "DEVPATH=/devices/virtual/switch/usb_configuration";
+ private static final String USB_LEGACY_MATCH =
+ "DEVPATH=/devices/virtual/switch/usb_mass_storage";
+ private static final String USB_CONNECTED_PATH =
+ "/sys/class/switch/usb_connected/state";
+ private static final String USB_CONFIGURATION_PATH =
+ "/sys/class/switch/usb_configuration/state";
+ private static final String USB_LEGACY_PATH =
+ "/sys/class/switch/usb_mass_storage/state";
+ private static final String FUNCTIONS_PATH =
+ "/sys/devices/virtual/usb_composite/";
+ private static final String MASS_STORAGE_FILE_PATH =
+ Resources.getSystem().getString(com.android.internal.R.string.config_legacyUmsLunFile);
+
+ private final Object mLock = new Object();
+
+ private static final int MSG_UPDATE_STATE = 0;
+ private static final int MSG_ENABLE_ADB = 1;
+ private static final int MSG_SET_CURRENT_FUNCTION = 2;
+ private static final int MSG_SYSTEM_READY = 3;
+ private static final int MSG_BOOT_COMPLETED = 4;
+
+ private boolean mConnected = false;
+ private boolean mConfigured = false;
+
+ // Delay for debouncing USB disconnects.
+ // We often get rapid connect/disconnect events when enabling USB functions,
+ // which need debouncing.
+ private static final int UPDATE_DELAY = 1000;
+
+ private LegacyUsbHandler mHandler;
+ private boolean mBootCompleted;
+
+ private final Context mContext;
+ private final ContentResolver mContentResolver;
+
+ // @GuardedBy("mLock")
+ private UsbSettingsManager mCurrentSettings;
+
+ private NotificationManager mNotificationManager;
+ private final boolean mHasUsbAccessory;
+ private boolean mUseUsbNotification;
+ private boolean mAdbEnabled;
+ private boolean mLegacy = false;
+
+ private class AdbSettingsObserver extends ContentObserver {
+ public AdbSettingsObserver() {
+ super(null);
+ }
+ @Override
+ public void onChange(boolean selfChange) {
+ boolean enable = (Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ADB_ENABLED, 0) > 0);
+ mHandler.sendMessage(MSG_ENABLE_ADB, enable);
+ }
+ }
+
+ /*
+ * Listens for uevent messages from the kernel to monitor the USB state
+ */
+
+ private final UEventObserver mUEventObserver = new UEventObserver() {
+ @Override
+ public void onUEvent(UEventObserver.UEvent event) {
+ if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString());
+
+ String name = event.get("SWITCH_NAME");
+ String state = event.get("SWITCH_STATE");
+
+ if (name != null && state != null) {
+ if (mLegacy) {
+ if ("usb_mass_storage".equals(name)) {
+ mConnected = "online".equals(state);
+ mConfigured = "online".equals(state);
+ }
+ } else {
+ if ("usb_connected".equals(name))
+ mConnected = "1".equals(state);
+ else if ("usb_configuration".equals(name))
+ mConfigured = "1".equals(state);
+ }
+
+ if (!mConnected && !mConfigured) mHandler.updateState("DISCONNECTED");
+ else if(mConnected && !mConfigured) mHandler.updateState("CONNECTED");
+ else if(mConnected && mConfigured) mHandler.updateState("CONFIGURED");
+ else mHandler.updateState("UNKNOWN");
+ }
+ }
+ };
+
+ public LegacyUsbDeviceManager(Context context) {
+ super();
+ mContext = context;
+ mContentResolver = context.getContentResolver();
+ PackageManager pm = mContext.getPackageManager();
+ mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
+
+ // create a thread for our Handler
+ HandlerThread thread = new HandlerThread("LegacyUsbDeviceManager",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ mHandler = new LegacyUsbHandler(thread.getLooper());
+ }
+
+ public void setCurrentSettings(UsbSettingsManager settings) {
+ synchronized (mLock) {
+ mCurrentSettings = settings;
+ }
+ }
+
+ private UsbSettingsManager getCurrentSettings() {
+ synchronized (mLock) {
+ return mCurrentSettings;
+ }
+ }
+
+ @Override
+ public void systemReady() {
+ if (DEBUG) Slog.d(TAG, "systemReady");
+
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // We do not show the USB notification if the primary volume supports mass storage.
+ // The legacy mass storage UI will be used instead.
+ boolean massStorageSupported = false;
+ StorageManager storageManager = (StorageManager)
+ mContext.getSystemService(Context.STORAGE_SERVICE);
+ StorageVolume[] volumes = storageManager.getVolumeList();
+
+ if (volumes.length > 0) {
+ if (Settings.Secure.getInt(mContentResolver, Settings.Secure.USB_MASS_STORAGE_ENABLED, 0 ) == 1 ) {
+ massStorageSupported = volumes[0].allowMassStorage();
+ } else {
+ massStorageSupported = false;
+ }
+ }
+
+ mUseUsbNotification = !massStorageSupported;
+
+ // make sure the ADB_ENABLED setting value matches the current state
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ADB_ENABLED, mAdbEnabled ? 1 : 0);
+ if (DEBUG) Slog.d(TAG, "mAdbEnable="+mAdbEnabled);
+
+ mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
+ }
+
+ private static String addFunction(String functions, String function) {
+ if (!containsFunction(functions, function)) {
+ if (functions.length() > 0) {
+ functions += ",";
+ }
+ functions += function;
+ }
+ return functions;
+ }
+
+ private static String removeFunction(String functions, String function) {
+ String[] split = functions.split(",");
+ for (int i = 0; i < split.length; i++) {
+ if (function.equals(split[i])) {
+ split[i] = null;
+ }
+ }
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < split.length; i++) {
+ String s = split[i];
+ if (s != null) {
+ if (builder.length() > 0) {
+ builder.append(",");
+ }
+ builder.append(s);
+ }
+ }
+ return builder.toString();
+ }
+
+ private static boolean containsFunction(String functions, String function) {
+ int index = functions.indexOf(function);
+ if (index < 0) return false;
+ if (index > 0 && functions.charAt(index - 1) != ',') return false;
+ int charAfter = index + function.length();
+ if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
+ return true;
+ }
+
+ private final class LegacyUsbHandler extends Handler {
+
+ // current USB state
+ private boolean mConnected = false;
+ private boolean mConfigured = false;
+ private String mCurrentFunctions;
+ private String mDefaultFunctions;
+ private UsbAccessory mCurrentAccessory;
+ private int mUsbNotificationId;
+ private boolean mAdbNotificationShown;
+
+ final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) Slog.d(TAG, "boot completed");
+ mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
+ }
+ };
+
+ public LegacyUsbHandler(Looper looper) {
+ super(looper);
+ char[] buffer = new char[1024];
+
+ try {
+ // persist.sys.usb.config should never be unset. But if it is, set it to "adb"
+ // so we have a chance of debugging what happened.
+ mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb");
+ // sanity check the sys.usb.config system property
+ // this may be necessary if we crashed while switching USB configurations
+ String config = SystemProperties.get("sys.usb.config", "none");
+ if (!config.equals(mDefaultFunctions)) {
+ Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions);
+ SystemProperties.set("sys.usb.config", mDefaultFunctions);
+ }
+
+ // Read initial USB state (device mode)
+ try {
+ FileReader file = new FileReader(USB_CONNECTED_PATH);
+ int len = file.read(buffer, 0, 1024);
+ file.close();
+ mConnected = "1".equals((new String(buffer, 0, len)).trim());
+
+ file = new FileReader(USB_CONFIGURATION_PATH);
+ len = file.read(buffer, 0, 1024);
+ file.close();
+ mConfigured = "1".equals((new String(buffer, 0, len)).trim());
+ } catch (FileNotFoundException e) {
+ Slog.i(TAG, "This kernel does not have USB configuration switch support");
+ Slog.i(TAG, "Trying legacy USB configuration switch support");
+ try {
+ FileReader file = new FileReader(USB_LEGACY_PATH);
+ int len = file.read(buffer, 0, 1024);
+ file.close();
+ mConnected = "online".equals((new String(buffer, 0, len)).trim());
+ mLegacy = true;
+ mConfigured = false;
+ } catch (FileNotFoundException f) {
+ Slog.i(TAG, "This kernel does not have legacy USB configuration switch support");
+ } catch (Exception f) {
+ Slog.e(TAG, "" , f);
+ }
+ }
+
+ mCurrentFunctions = mDefaultFunctions;
+ if (!mConnected && !mConfigured) updateState("DISCONNECTED");
+ else if(mConnected && !mConfigured) updateState("CONNECTED");
+ else if(mConnected && mConfigured) updateState("CONFIGURED");
+ else updateState("UNKNOWN");
+
+ mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);
+ // Upgrade step for previous versions that used persist.service.adb.enable
+ String value = SystemProperties.get("persist.service.adb.enable", "0");
+ if (value.length() > 0) {
+ char enable = value.charAt(0);
+ if (enable == '1') {
+ setAdbEnabled(true);
+ } else if (enable == '0') {
+ setAdbEnabled(false);
+ }
+ }
+
+ // register observer to listen for settings changes
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED),
+ false, new AdbSettingsObserver());
+
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.ADB_NOTIFY),
+ false, new ContentObserver(null) {
+ public void onChange(boolean selfChange) {
+ updateAdbNotification();
+ }
+ });
+
+ // Watch for USB configuration changes
+ if (mLegacy) {
+ mUEventObserver.startObserving(USB_LEGACY_MATCH);
+ } else {
+ mUEventObserver.startObserving(USB_CONNECTED_MATCH);
+ mUEventObserver.startObserving(USB_CONFIGURATION_MATCH);
+ }
+ mContext.registerReceiver(mBootCompletedReceiver,
+ new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
+ if(DEBUG) Slog.d(TAG, "Initialised USB event listeners");
+ } catch (Exception e) {
+ Slog.e(TAG, "Error initializing listener", e);
+ }
+ }
+
+ public boolean isConnected() {
+ return mConnected;
+ }
+
+ public boolean isConfigured() {
+ return mConfigured;
+ }
+
+ public void sendMessage(int what, boolean arg) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ m.arg1 = (arg ? 1 : 0);
+ sendMessage(m);
+ }
+
+ public void sendMessage(int what, Object arg) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ m.obj = arg;
+ sendMessage(m);
+ }
+
+ public void sendMessage(int what, Object arg0, boolean arg1) {
+ removeMessages(what);
+ Message m = Message.obtain(this, what);
+ m.obj = arg0;
+ m.arg1 = (arg1 ? 1 : 0);
+ sendMessage(m);
+ }
+
+ public void updateState(String state) {
+ int connected, configured;
+
+ if ("DISCONNECTED".equals(state)) {
+ connected = 0;
+ configured = 0;
+ } else if ("CONNECTED".equals(state)) {
+ connected = 1;
+ configured = 0;
+ } else if ("CONFIGURED".equals(state)) {
+ connected = 1;
+ configured = 1;
+ } else {
+ Slog.e(TAG, "unknown state " + state);
+ return;
+ }
+ removeMessages(MSG_UPDATE_STATE);
+ Message msg = Message.obtain(this, MSG_UPDATE_STATE);
+ msg.arg1 = connected;
+ msg.arg2 = configured;
+ // debounce disconnects to avoid problems bringing up USB tethering
+ sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
+ }
+
+ private boolean waitForState(String state) {
+ // wait for the transition to complete.
+ // give up after 1 second.
+ for (int i = 0; i < 20; i++) {
+ // State transition is done when sys.usb.state is set to the new configuration
+ if (state.equals(SystemProperties.get("sys.usb.state"))) return true;
+ try {
+ // try again in 50ms
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ }
+ }
+ Slog.e(TAG, "waitForState(" + state + ") FAILED");
+ return false;
+ }
+
+ private boolean setUsbConfig(String config) {
+ if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");
+ // set the new configuration
+ SystemProperties.set("sys.usb.config", config);
+ return waitForState(config);
+ }
+
+ private void setAdbEnabled(boolean enable) {
+ if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
+ if (enable != mAdbEnabled) {
+ mAdbEnabled = enable;
+ // Due to the persist.sys.usb.config property trigger, changing adb state requires
+ // switching to default function
+ setEnabledFunctions(mDefaultFunctions, true);
+ updateAdbNotification();
+ }
+ SystemProperties.set("persist.service.adb.enable", enable ? "1":"0");
+ }
+
+ private void setEnabledFunctions(String functions, boolean makeDefault) {
+ if (functions != null && makeDefault) {
+ if (mAdbEnabled) {
+ functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ } else {
+ functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ }
+ if (!mDefaultFunctions.equals(functions)) {
+ if (!setUsbConfig("none")) {
+ Slog.e(TAG, "Failed to disable USB");
+ // revert to previous configuration if we fail
+ setUsbConfig(mCurrentFunctions);
+ return;
+ }
+ // setting this property will also change the current USB state
+ // via a property trigger
+ SystemProperties.set("persist.sys.usb.config", functions);
+ if (waitForState(functions)) {
+ mCurrentFunctions = functions;
+ mDefaultFunctions = functions;
+ } else {
+ Slog.e(TAG, "Failed to switch persistent USB config to " + functions);
+ // revert to previous configuration if we fail
+ SystemProperties.set("persist.sys.usb.config", mDefaultFunctions);
+ }
+ }
+ } else {
+ if (functions == null) {
+ functions = mDefaultFunctions;
+ }
+ if (mAdbEnabled) {
+ functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ } else {
+ functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ }
+ if (!mCurrentFunctions.equals(functions)) {
+ if (!setUsbConfig("none")) {
+ Slog.e(TAG, "Failed to disable USB");
+ // revert to previous configuration if we fail
+ setUsbConfig(mCurrentFunctions);
+ return;
+ }
+ if (setUsbConfig(functions)) {
+ mCurrentFunctions = functions;
+ } else {
+ Slog.e(TAG, "Failed to switch USB config to " + functions);
+ // revert to previous configuration if we fail
+ setUsbConfig(mCurrentFunctions);
+ }
+ }
+ }
+ }
+
+ private void updateUsbState() {
+ // send a sticky broadcast containing current USB state
+ Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.putExtra(UsbManager.USB_CONNECTED, mConnected);
+ intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured);
+
+ if (mCurrentFunctions != null) {
+ String[] functions = mCurrentFunctions.split(",");
+ for (int i = 0; i < functions.length; i++) {
+ intent.putExtra(functions[i], true);
+ }
+ }
+
+ mContext.sendStickyBroadcast(intent);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_UPDATE_STATE:
+ if (DEBUG) Slog.d(TAG, "Got MSG_UPDATE_STATE. Connected="+msg.arg1+" Configured="+msg.arg2);
+ mConnected = (msg.arg1 == 1);
+ mConfigured = (msg.arg2 == 1);
+ updateUsbNotification();
+ updateAdbNotification();
+
+ if (!mConnected) {
+ // restore defaults when USB is disconnected
+ setEnabledFunctions(mDefaultFunctions, false);
+ }
+ if (mBootCompleted) {
+ updateUsbState();
+ }
+ break;
+ case MSG_ENABLE_ADB:
+ setAdbEnabled(msg.arg1 == 1);
+ break;
+ case MSG_SET_CURRENT_FUNCTION:
+ String function = (String)msg.obj;
+ boolean makeDefault = (msg.arg1 == 1);
+ setEnabledFunctions(function, makeDefault);
+ break;
+ case MSG_SYSTEM_READY:
+ updateUsbNotification();
+ updateAdbNotification();
+ updateUsbState();
+ break;
+ case MSG_BOOT_COMPLETED:
+ mBootCompleted = true;
+ if (mCurrentAccessory != null) {
+ getCurrentSettings().accessoryAttached(mCurrentAccessory);
+ }
+ break;
+ }
+ }
+
+ public UsbAccessory getCurrentAccessory() {
+ return mCurrentAccessory;
+ }
+
+ private void updateUsbNotification() {
+ if (mNotificationManager == null || !mUseUsbNotification) {
+ if(DEBUG && mNotificationManager == null) Slog.d(TAG, "mNotificationManager == null");
+ if(DEBUG && !mUseUsbNotification) Slog.d(TAG, "!mUseUsbNotification");
+ return;
+ }
+ int id = 0;
+ Resources r = mContext.getResources();
+ if (mConnected) {
+ if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) {
+ id = com.android.internal.R.string.usb_mtp_notification_title;
+ } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) {
+ id = com.android.internal.R.string.usb_ptp_notification_title;
+ } /* else if (containsFunction(mCurrentFunctions,
+ UsbManager.USB_FUNCTION_MASS_STORAGE)) { // Disable this as it causes double USB settings menues when in UMS mode.
+ id = com.android.internal.R.string.usb_cd_installer_notification_title;
+ } */ else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) {
+ id = com.android.internal.R.string.usb_accessory_notification_title;
+ } else {
+ // There is a different notification for USB tethering so we don't need one here
+ if (!containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) {
+ Slog.e(TAG, "No known USB function in updateUsbNotification");
+ }
+ }
+ }
+ if (id != mUsbNotificationId) {
+ // clear notification if title needs changing
+ if (mUsbNotificationId != 0) {
+ mNotificationManager.cancel(mUsbNotificationId);
+ mUsbNotificationId = 0;
+ }
+ if (id != 0) {
+ CharSequence message = r.getText(
+ com.android.internal.R.string.usb_notification_message);
+ CharSequence title = r.getText(id);
+
+ Notification notification = new Notification();
+ notification.icon = com.android.internal.R.drawable.stat_sys_data_usb;
+ notification.when = 0;
+ notification.flags = Notification.FLAG_ONGOING_EVENT;
+ notification.tickerText = title;
+ notification.defaults = 0; // please be quiet
+ notification.sound = null;
+ notification.vibrate = null;
+
+ Intent intent = Intent.makeRestartActivityTask(
+ new ComponentName("com.android.settings",
+ "com.android.settings.UsbSettings"));
+ PendingIntent pi = PendingIntent.getActivity(mContext, 0,
+ intent, 0);
+ notification.setLatestEventInfo(mContext, title, message, pi);
+ mNotificationManager.notify(id, notification);
+ mUsbNotificationId = id;
+ }
+ }
+ }
+
+ private void updateAdbNotification() {
+ if (mNotificationManager == null) return;
+ final int id = com.android.internal.R.string.adb_active_notification_title;
+ if (mAdbEnabled && mConnected) {
+ if ("0".equals(SystemProperties.get("persist.adb.notify"))
+ || Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ADB_NOTIFY, 1) == 0)
+ return;
+
+ if (!mAdbNotificationShown) {
+ Resources r = mContext.getResources();
+ CharSequence title = r.getText(id);
+ CharSequence message = r.getText(
+ com.android.internal.R.string.adb_active_notification_message);
+
+ Notification notification = new Notification();
+ notification.icon = com.android.internal.R.drawable.stat_sys_adb;
+ notification.when = 0;
+ notification.flags = Notification.FLAG_ONGOING_EVENT;
+ notification.tickerText = title;
+ notification.defaults = 0; // please be quiet
+ notification.sound = null;
+ notification.vibrate = null;
+
+ Intent intent = Intent.makeRestartActivityTask(
+ new ComponentName("com.android.settings",
+ "com.android.settings.DevelopmentSettings"));
+ PendingIntent pi = PendingIntent.getActivity(mContext, 0,
+ intent, 0);
+ notification.setLatestEventInfo(mContext, title, message, pi);
+ mAdbNotificationShown = true;
+ mNotificationManager.notify(id, notification);
+ }
+ } else if (mAdbNotificationShown) {
+ mAdbNotificationShown = false;
+ mNotificationManager.cancel(id);
+ }
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw) {
+ pw.println(" USB Device State:");
+ pw.println(" Current Functions: " + mCurrentFunctions);
+ pw.println(" Default Functions: " + mDefaultFunctions);
+ pw.println(" mConnected: " + mConnected);
+ pw.println(" mConfigured: " + mConfigured);
+ pw.println(" mCurrentAccessory: " + mCurrentAccessory);
+ try {
+ pw.println(" Kernel function list: "
+ + Arrays.toString(new File(FUNCTIONS_PATH).list()));
+ pw.println(" Mass storage backing file: "
+ + FileUtils.readTextFile(new File(MASS_STORAGE_FILE_PATH), 0, null).trim());
+ } catch (IOException e) {
+ pw.println("IOException: " + e);
+ }
+ }
+ }
+}
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index c7c2c62..7c5cc3d 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -149,6 +149,13 @@ public class UsbDeviceManager {
}
};
+ // Dummy constructor to use when extending class
+ public UsbDeviceManager() {
+ mContext = null;
+ mContentResolver = null;
+ mHasUsbAccessory = false;
+ }
+
public UsbDeviceManager(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
@@ -197,7 +204,13 @@ public class UsbDeviceManager {
boolean massStorageSupported = false;
final StorageManager storageManager = StorageManager.from(mContext);
final StorageVolume primary = storageManager.getPrimaryVolume();
- massStorageSupported = primary != null && primary.allowMassStorage();
+
+ if (Settings.Secure.getInt(mContentResolver, Settings.Secure.USB_MASS_STORAGE_ENABLED, 0 ) == 1 ) {
+ massStorageSupported = primary != null && primary.allowMassStorage();
+ } else {
+ massStorageSupported = false;
+ }
+
mUseUsbNotification = !massStorageSupported;
// make sure the ADB_ENABLED setting value matches the current state
@@ -364,6 +377,18 @@ public class UsbDeviceManager {
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
false, new AdbSettingsObserver());
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.ADB_NOTIFY),
+ false, new ContentObserver(null) {
+ public void onChange(boolean selfChange) {
+ updateAdbNotification();
+ }
+ }
+ );
+
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.ADB_PORT),
+ false, new AdbSettingsObserver());
// Watch for USB configuration changes
mUEventObserver.startObserving(USB_STATE_MATCH);
@@ -714,7 +739,10 @@ public class UsbDeviceManager {
if (mNotificationManager == null) return;
final int id = com.android.internal.R.string.adb_active_notification_title;
if (mAdbEnabled && mConnected) {
- if ("0".equals(SystemProperties.get("persist.adb.notify"))) return;
+ if ("0".equals(SystemProperties.get("persist.adb.notify"))
+ || Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ADB_NOTIFY, 1) == 0)
+ return;
if (!mAdbNotificationShown) {
Resources r = mContext.getResources();
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index 3918d15..b209db9 100644
--- a/services/java/com/android/server/usb/UsbService.java
+++ b/services/java/com/android/server/usb/UsbService.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
@@ -78,6 +79,8 @@ public class UsbService extends IUsbManager.Stub {
if (new File("/sys/class/android_usb").exists()) {
mDeviceManager = new UsbDeviceManager(context);
}
+ else if(new File(Resources.getSystem().getString(com.android.internal.R.string.config_legacyUmsLunFile)).exists())
+ mDeviceManager = new LegacyUsbDeviceManager(context);
setCurrentUser(UserHandle.USER_OWNER);
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index cfcf841..338d706 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -49,6 +49,7 @@ class ScreenRotationAnimation {
BlackFrame mEnteringBlackFrame;
int mWidth, mHeight;
int mExitAnimId, mEnterAnimId;
+ int mSnapshotRotation;
int mOriginalRotation;
int mOriginalWidth, mOriginalHeight;
@@ -196,16 +197,27 @@ class ScreenRotationAnimation {
mExitAnimId = exitAnim;
mEnterAnimId = enterAnim;
- // Screenshot does NOT include rotation!
- if (originalRotation == Surface.ROTATION_90
+ // Allow for abnormal hardware orientation
+ mSnapshotRotation = (4 - android.os.SystemProperties.getInt("ro.sf.hwrotation",0) / 90) % 4;
+ if (mSnapshotRotation == Surface.ROTATION_0 || mSnapshotRotation == Surface.ROTATION_180) {
+ if (originalRotation == Surface.ROTATION_90
|| originalRotation == Surface.ROTATION_270) {
- mWidth = originalHeight;
- mHeight = originalWidth;
+ mWidth = originalHeight;
+ mHeight = originalWidth;
+ } else {
+ mWidth = originalWidth;
+ mHeight = originalHeight;
+ }
} else {
- mWidth = originalWidth;
- mHeight = originalHeight;
+ if (originalRotation == Surface.ROTATION_90
+ || originalRotation == Surface.ROTATION_270) {
+ mWidth = originalWidth;
+ mHeight = originalHeight;
+ } else {
+ mWidth = originalHeight;
+ mHeight = originalWidth;
+ }
}
-
mOriginalRotation = originalRotation;
mOriginalWidth = originalWidth;
mOriginalHeight = originalHeight;
@@ -313,7 +325,7 @@ class ScreenRotationAnimation {
// Compute the transformation matrix that must be applied
// to the snapshot to make it stay in the same original position
// with the current screen rotation.
- int delta = deltaRotation(rotation, Surface.ROTATION_0);
+ int delta = deltaRotation(rotation, mSnapshotRotation);
createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 5b9fc9a..bbea849 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -41,6 +41,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.app.ThemeUtils;
+
+import com.android.internal.os.IDeviceHandler;
import com.android.internal.policy.PolicyManager;
import com.android.internal.policy.impl.PhoneWindowManager;
import com.android.internal.view.IInputContext;
@@ -298,6 +301,13 @@ public class WindowManagerService extends IWindowManager.Stub
private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
+
+ private BroadcastReceiver mThemeChangeReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ mUiContext = null;
+ }
+ };
+
final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -313,6 +323,7 @@ public class WindowManagerService extends IWindowManager.Stub
int mCurrentUserId;
final Context mContext;
+ private Context mUiContext;
final boolean mHaveInputMethods;
@@ -320,7 +331,7 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean mLimitedAlphaCompositing;
- final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
+ final WindowManagerPolicy mPolicy;
final IActivityManager mActivityManager;
@@ -579,6 +590,8 @@ public class WindowManagerService extends IWindowManager.Stub
final DisplayManagerService mDisplayManagerService;
final DisplayManager mDisplayManager;
+ private boolean mForceDisableHardwareKeyboard = false;
+
// Who is holding the screen on.
Session mHoldingScreenOn;
PowerManager.WakeLock mHoldingScreenWakeLock;
@@ -757,7 +770,7 @@ public class WindowManagerService extends IWindowManager.Stub
public static WindowManagerService main(final Context context,
final PowerManagerService pm, final DisplayManagerService dm,
- final InputManagerService im,
+ final InputManagerService im, final IDeviceHandler device,
final Handler uiHandler, final Handler wmHandler,
final boolean haveInputMethods, final boolean showBootMsgs,
final boolean onlyCore) {
@@ -766,7 +779,7 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void run() {
holder[0] = new WindowManagerService(context, pm, dm, im,
- uiHandler, haveInputMethods, showBootMsgs, onlyCore);
+ device, uiHandler, haveInputMethods, showBootMsgs, onlyCore);
}
}, 0);
return holder[0];
@@ -788,7 +801,7 @@ public class WindowManagerService extends IWindowManager.Stub
private WindowManagerService(Context context, PowerManagerService pm,
DisplayManagerService displayManager, InputManagerService inputManager,
- Handler uiHandler,
+ IDeviceHandler device, Handler uiHandler,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mContext = context;
mHaveInputMethods = haveInputMethods;
@@ -798,6 +811,7 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.bool.config_sf_limitedAlpha);
mDisplayManagerService = displayManager;
mHeadless = displayManager.isHeadless();
+ mPolicy = PolicyManager.makeNewWindowManager(device);
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
@@ -839,6 +853,9 @@ public class WindowManagerService extends IWindowManager.Stub
mFxSession = new SurfaceSession();
mAnimator = new WindowAnimator(this);
+ mForceDisableHardwareKeyboard = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_forceDisableHardwareKeyboard);
+
initPolicy(uiHandler);
// Add ourself to the Watchdog monitors.
@@ -850,6 +867,15 @@ public class WindowManagerService extends IWindowManager.Stub
} finally {
Surface.closeTransaction();
}
+
+ ThemeUtils.registerThemeChangeReceiver(mContext, mThemeChangeReceiver);
+ }
+
+ private Context getUiContext() {
+ if (mUiContext == null) {
+ mUiContext = ThemeUtils.createUiContext(mContext);
+ }
+ return mUiContext != null ? mUiContext : mContext;
}
public InputMonitor getInputMonitor() {
@@ -5451,13 +5477,13 @@ public class WindowManagerService extends IWindowManager.Stub
// Called by window manager policy. Not exposed externally.
@Override
public void shutdown(boolean confirm) {
- ShutdownThread.shutdown(mContext, confirm);
+ ShutdownThread.shutdown(getUiContext(), confirm);
}
// Called by window manager policy. Not exposed externally.
@Override
public void rebootSafeMode(boolean confirm) {
- ShutdownThread.rebootSafeMode(mContext, confirm);
+ ShutdownThread.rebootSafeMode(getUiContext(), confirm);
}
public void setInputFilter(IInputFilter filter) {
@@ -5467,6 +5493,12 @@ public class WindowManagerService extends IWindowManager.Stub
mInputManager.setInputFilter(filter);
}
+ // Called by window manager policy. Not exposed externally.
+ @Override
+ public void reboot() {
+ ShutdownThread.reboot(getUiContext(), null, true);
+ }
+
public void setCurrentUser(final int newUserId) {
synchronized (mWindowMap) {
mCurrentUserId = newUserId;
@@ -5882,6 +5914,9 @@ public class WindowManagerService extends IWindowManager.Stub
// The screenshot API does not apply the current screen rotation.
rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
+ // Allow for abnormal hardware orientation
+ rot = (rot + (android.os.SystemProperties.getInt("ro.sf.hwrotation",0) / 90 )) % 4;
+
int fw = frame.width();
int fh = frame.height();
@@ -7011,7 +7046,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
// Determine whether a hard keyboard is available and enabled.
- boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
+ boolean hardKeyboardAvailable = false;
+ if (!mForceDisableHardwareKeyboard) {
+ hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
+ }
if (hardKeyboardAvailable != mHardKeyboardAvailable) {
mHardKeyboardAvailable = hardKeyboardAvailable;
mHardKeyboardEnabled = hardKeyboardAvailable;
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index d097a93..70413d8 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -44,10 +44,22 @@ LOCAL_SHARED_LIBRARIES := \
libusbhost \
libsuspend
+ifeq ($(BOARD_HAVE_NEW_QC_GPS),true)
+ LOCAL_CFLAGS += -DNEW_QC_GPS
+endif
+
+ifeq ($(BOARD_HAVE_SAMSUNG_GPS),true)
+ LOCAL_CFLAGS += -DSAMSUNG_GPS
+endif
+
ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
endif
+ifeq ($(TARGET_HAS_DOCK_BATTERY),true)
+ LOCAL_CFLAGS += -DHAS_DOCK_BATTERY
+endif
+
LOCAL_MODULE:= libandroid_servers
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index e6133af..c7e931e 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -202,20 +202,20 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);
setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline);
setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
-
+
setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
-
+
const int SIZE = 128;
char buf[SIZE];
-
+
if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0)
env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));
else
env->SetIntField(obj, gFieldIds.mBatteryStatus,
gConstants.statusUnknown);
-
+
if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)
env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index a97becf..55a8061 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -176,6 +176,7 @@ public:
void setSystemUiVisibility(int32_t visibility);
void setPointerSpeed(int32_t speed);
void setShowTouches(bool enabled);
+ void setStylusIconEnabled(bool enabled);
/* --- InputReaderPolicyInterface implementation --- */
@@ -236,6 +237,9 @@ private:
// Show touches feature enable/disable.
bool showTouches;
+ // Show icon when stylus is used
+ bool stylusIconEnabled;
+
// Sprite controller singleton, created on first use.
sp<SpriteController> spriteController;
@@ -274,6 +278,7 @@ NativeInputManager::NativeInputManager(jobject contextObj,
mLocked.pointerSpeed = 0;
mLocked.pointerGesturesEnabled = true;
mLocked.showTouches = false;
+ mLocked.stylusIconEnabled = false;
}
sp<EventHub> eventHub = new EventHub();
@@ -406,8 +411,11 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
outConfig->showTouches = mLocked.showTouches;
+ outConfig->stylusIconEnabled = mLocked.stylusIconEnabled;
+
outConfig->setDisplayInfo(false /*external*/, mLocked.internalViewport);
outConfig->setDisplayInfo(true /*external*/, mLocked.externalViewport);
+
} // release lock
}
@@ -728,6 +736,22 @@ void NativeInputManager::setShowTouches(bool enabled) {
InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
}
+void NativeInputManager::setStylusIconEnabled(bool enabled) {
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (mLocked.stylusIconEnabled == enabled) {
+ return;
+ }
+
+ ALOGI("Setting stylus icon enabled to %s.", enabled ? "enabled" : "disabled");
+ mLocked.stylusIconEnabled = enabled;
+ } // release lock
+
+ mInputManager->getReader()->requestRefreshConfiguration(
+ InputReaderConfiguration::CHANGE_STYLUS_ICON_ENABLED);
+}
+
bool NativeInputManager::isScreenOn() {
return android_server_PowerManagerService_isScreenOn();
}
@@ -1219,6 +1243,13 @@ static void nativeSetShowTouches(JNIEnv* env,
im->setShowTouches(enabled);
}
+static void nativeSetStylusIconEnabled(JNIEnv* env,
+ jclass clazz, jint ptr, jboolean enabled) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+ im->setStylusIconEnabled(enabled);
+}
+
static void nativeVibrate(JNIEnv* env,
jclass clazz, jint ptr, jint deviceId, jlongArray patternObj,
jint repeat, jint token) {
@@ -1324,6 +1355,8 @@ static JNINativeMethod gInputManagerMethods[] = {
(void*) nativeSetPointerSpeed },
{ "nativeSetShowTouches", "(IZ)V",
(void*) nativeSetShowTouches },
+ { "nativeSetStylusIconEnabled", "(IZ)V",
+ (void*) nativeSetStylusIconEnabled },
{ "nativeVibrate", "(II[JII)V",
(void*) nativeVibrate },
{ "nativeCancelVibrate", "(III)V",
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index 50bd46e..f2ec1b3 100755
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -167,7 +167,11 @@ static void agps_status_callback(AGpsStatus* agps_status)
uint32_t ipaddr;
// ipaddr field was not included in original AGpsStatus
if (agps_status->size >= sizeof(AGpsStatus))
+#ifdef NEW_QC_GPS
+ ipaddr = agps_status->ipv4_addr;
+#else
ipaddr = agps_status->ipaddr;
+#endif
else
ipaddr = 0xFFFFFFFF;
env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
@@ -483,7 +487,11 @@ static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env
return;
}
const char *apnStr = env->GetStringUTFChars(apn, NULL);
+#ifdef NEW_QC_GPS
+ sAGpsInterface->data_conn_open(0, apnStr, 0);
+#else
sAGpsInterface->data_conn_open(apnStr);
+#endif
env->ReleaseStringUTFChars(apn, apnStr);
}
@@ -493,7 +501,11 @@ static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* e
ALOGE("no AGPS interface in agps_data_conn_open");
return;
}
+#ifdef NEW_QC_GPS
+ sAGpsInterface->data_conn_closed(0);
+#else
sAGpsInterface->data_conn_closed();
+#endif
}
static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
@@ -502,7 +514,11 @@ static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* e
ALOGE("no AGPS interface in agps_data_conn_open");
return;
}
+#ifdef NEW_QC_GPS
+ sAGpsInterface->data_conn_failed(0);
+#else
sAGpsInterface->data_conn_failed();
+#endif
}
static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
diff --git a/services/jni/com_android_server_power_PowerManagerService.cpp b/services/jni/com_android_server_power_PowerManagerService.cpp
index 23c33af..58af5f1 100644
--- a/services/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/jni/com_android_server_power_PowerManagerService.cpp
@@ -204,6 +204,12 @@ static void nativeReboot(JNIEnv *env, jclass clazz, jstring reason) {
jniThrowIOException(env, errno);
}
+static void nativeCpuBoost(JNIEnv *env, jobject clazz, jint duration) {
+ // Tell the Power HAL to boost the CPU
+ if (gPowerModule && gPowerModule->powerHint) {
+ gPowerModule->powerHint(gPowerModule, POWER_HINT_CPU_BOOST, (void *) duration);
+ }
+}
// ----------------------------------------------------------------------------
@@ -225,6 +231,8 @@ static JNINativeMethod gPowerManagerServiceMethods[] = {
(void*) nativeShutdown },
{ "nativeReboot", "(Ljava/lang/String;)V",
(void*) nativeReboot },
+ { "nativeCpuBoost", "(I)V",
+ (void*) nativeCpuBoost },
};
#define FIND_CLASS(var, className) \
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index 2f81b65..b0eb8f4 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -26,7 +26,7 @@ import android.util.Log;
public final class CellInfoLte extends CellInfo implements Parcelable {
private static final String LOG_TAG = "CellInfoLte";
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
private CellIdentityLte mCellIdentityLte;
private CellSignalStrengthLte mCellSignalStrengthLte;
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 0f9a3b9..51e1e95 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -25,8 +25,7 @@ import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
-
-
+import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPAP;
/**
* Represents the neighboring cell information, including
@@ -108,7 +107,8 @@ public class NeighboringCellInfo implements Parcelable
* {@link TelephonyManager#NETWORK_TYPE_UMTS TelephonyManager.NETWORK_TYPE_UMTS},
* {@link TelephonyManager#NETWORK_TYPE_HSDPA TelephonyManager.NETWORK_TYPE_HSDPA},
* {@link TelephonyManager#NETWORK_TYPE_HSUPA TelephonyManager.NETWORK_TYPE_HSUPA},
- * and {@link TelephonyManager#NETWORK_TYPE_HSPA TelephonyManager.NETWORK_TYPE_HSPA}.
+ * {@link TelephonyManager#NETWORK_TYPE_HSPA TelephonyManager.NETWORK_TYPE_HSPA},
+ * and {@link TelephonyManager#NETWORK_TYPE_HSPAP TelephonyManager.NETWORK_TYPE_HSPAP}.
*/
public NeighboringCellInfo(int rssi, String location, int radioType) {
// set default value
@@ -143,6 +143,7 @@ public class NeighboringCellInfo implements Parcelable
case NETWORK_TYPE_HSDPA:
case NETWORK_TYPE_HSUPA:
case NETWORK_TYPE_HSPA:
+ case NETWORK_TYPE_HSPAP:
mNetworkType = radioType;
mPsc = Integer.valueOf(location, 16);
break;
@@ -218,7 +219,8 @@ public class NeighboringCellInfo implements Parcelable
* Return {@link TelephonyManager#NETWORK_TYPE_UMTS TelephonyManager.NETWORK_TYPE_UMTS},
* {@link TelephonyManager#NETWORK_TYPE_HSDPA TelephonyManager.NETWORK_TYPE_HSDPA},
* {@link TelephonyManager#NETWORK_TYPE_HSUPA TelephonyManager.NETWORK_TYPE_HSUPA},
- * or {@link TelephonyManager#NETWORK_TYPE_HSPA TelephonyManager.NETWORK_TYPE_HSPA}
+ * {@link TelephonyManager#NETWORK_TYPE_HSPA TelephonyManager.NETWORK_TYPE_HSPA},
+ * or {@link TelephonyManager#NETWORK_TYPE_HSPAP TelephonyManager.NETWORK_TYPE_HSPAP}
* means that Neighboring Cell information is stored for UMTS network, in
* which {@link NeighboringCellInfo#getPsc NeighboringCellInfo.getPsc}
* should be called to access location.
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index f998935..c063290 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -19,6 +19,7 @@ package android.telephony;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemProperties;
import android.util.Log;
/**
@@ -342,7 +343,7 @@ public class SignalStrength implements Parcelable {
mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID;
mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
- mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
+ mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300) && !(mLteRsrq == SignalStrength.INVALID && mLteRssnr == -1)) ? mLteRssnr
: SignalStrength.INVALID;
// Cqi no change
if (DBG) log("Signal after validate=" + this);
@@ -435,6 +436,16 @@ public class SignalStrength implements Parcelable {
return mLteCqi;
}
+ /** @hide */
+ public boolean needsOldRilFeature(String feature) {
+ String[] features = SystemProperties.get("ro.telephony.ril.v3", "").split(",");
+ for (String found: features) {
+ if (found.equals(feature))
+ return true;
+ }
+ return false;
+ }
+
/**
* Get signal level as an int from 0..4
*
@@ -444,8 +455,9 @@ public class SignalStrength implements Parcelable {
int level;
if (isGsm) {
+ boolean oldRil = needsOldRilFeature("signalstrength");
level = getLteLevel();
- if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN || oldRil) {
level = getGsmLevel();
}
} else {
@@ -474,7 +486,8 @@ public class SignalStrength implements Parcelable {
public int getAsuLevel() {
int asuLevel;
if (isGsm) {
- if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ boolean oldRil = needsOldRilFeature("signalstrength");
+ if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN || oldRil) {
asuLevel = getGsmAsuLevel();
} else {
asuLevel = getLteAsuLevel();
@@ -506,7 +519,8 @@ public class SignalStrength implements Parcelable {
int dBm;
if(isGsm()) {
- if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ boolean oldRil = needsOldRilFeature("signalstrength");
+ if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN || oldRil) {
dBm = getGsmDbm();
} else {
dBm = getLteDbm();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 2fa41e7..2f80d39 100755
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -377,6 +377,8 @@ public class TelephonyManager {
case RILConstants.NETWORK_MODE_GSM_ONLY:
case RILConstants.NETWORK_MODE_WCDMA_ONLY:
case RILConstants.NETWORK_MODE_GSM_UMTS:
+ case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
+ case RILConstants.NETWORK_MODE_LTE_WCDMA:
return PhoneConstants.PHONE_TYPE_GSM;
// Use CDMA Phone for the global mode including CDMA
@@ -473,6 +475,15 @@ public class TelephonyManager {
return retVal;
}
+ /**
+ * Return if the current radio is LTE on GSM
+ * @hide
+ */
+ public static int getLteOnGsmModeStatic() {
+ return SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_GSM_DEVICE,
+ 0);
+ }
+
//
//
// Current Network
@@ -596,6 +607,17 @@ public class TelephonyManager {
}
}
+ /**
+ * {@hide}
+ */
+ public void toggleLTE(boolean on) {
+ try {
+ getITelephony().toggleLTE(on);
+ } catch (RemoteException e) {
+ //Silently fail
+ }
+ }
+
/** Unknown network class. {@hide} */
public static final int NETWORK_CLASS_UNKNOWN = 0;
/** Class of broadly defined "2G" networks. {@hide} */
@@ -825,6 +847,21 @@ public class TelephonyManager {
}
}
+ /**
+ * Return if the current radio is LTE on GSM
+ * @hide
+ */
+ public int getLteOnGsmMode() {
+ try {
+ return getITelephony().getLteOnGsmMode();
+ } catch (RemoteException ex) {
+ return 0;
+ } catch (NullPointerException ex) {
+ // This could happen before phone restarts due to crashing
+ return 0;
+ }
+ }
+
//
//
// Subscriber Info
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 12a7286..9d1cc1d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -45,6 +45,12 @@ interface ITelephony {
void call(String number);
/**
+ * Toggle between 3G and LTE (NT_MODE_CDMA, NT_MODE_GLOBAL)
+ * @param boolean to turn on and off LTE
+ */
+ void toggleLTE(boolean on);
+
+ /**
* If there is currently a call in progress, show the call screen.
* The DTMF dialpad may or may not be visible initially, depending on
* whether it was up when the user last exited the InCallScreen.
@@ -284,5 +290,7 @@ interface ITelephony {
* Returns the all observed cell information of the device.
*/
List<CellInfo> getAllCellInfo();
+
+ int getLteOnGsmMode();
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index f501b21..d93da8f 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -72,7 +72,7 @@ public interface RILConstants {
int NETWORK_MODE_LTE_GSM_WCDMA = 9; /* LTE, GSM/WCDMA */
int NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
int NETWORK_MODE_LTE_ONLY = 11; /* LTE Only mode. */
-
+ int NETWORK_MODE_LTE_WCDMA = 12; /* LTE/WCDMA */
int PREFERRED_NETWORK_MODE = NETWORK_MODE_WCDMA_PREF;
int CDMA_CELL_BROADCAST_SMS_DISABLED = 1;
@@ -297,4 +297,5 @@ cat include/telephony/ril.h | \
int RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
int RIL_UNSOL_RIL_CONNECTED = 1034;
int RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035;
+ int RIL_UNSOL_STK_SEND_SMS_RESULT = 11002; /* Samsung STK */
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index f95e081..99c718f 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -88,6 +88,11 @@ public interface TelephonyProperties
*/
static final String PROPERTY_LTE_ON_CDMA_DEVICE = "telephony.lteOnCdmaDevice";
+ /**
+ * {@see BaseCommands#getLteOnGsmMode()}
+ */
+ static final String PROPERTY_LTE_ON_GSM_DEVICE = "telephony.lteOnGsmDevice";
+
static final String CURRENT_ACTIVE_PHONE = "gsm.current.phone-type";
//****** SIM Card
@@ -187,4 +192,15 @@ public interface TelephonyProperties
* Ignore RIL_UNSOL_NITZ_TIME_RECEIVED completely, used for debugging/testing.
*/
static final String PROPERTY_IGNORE_NITZ = "telephony.test.ignore.nitz";
+
+ /**
+ * Set to true to indicates support for simultaneous voice and data.
+ */
+ static final String PROPERTY_SVDATA = "ro.config.svlte1x";
+
+ /**
+ * Property to control alpha ID display for proactive commands
+ * Type: boolean ( true = alpha display enabled, false = alpha display disabled)
+ */
+ static final String PROPERTY_ALPHA_USRCNF = "persist.atel.noalpha.usrcnf";
}
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 2eba4e1..35148e6 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -577,6 +577,14 @@ public class MockPackageManager extends PackageManager {
throw new UnsupportedOperationException();
}
+ /**
+ * @hide - to match hiding in superclass
+ */
+ @Override
+ public List<PackageInfo> getInstalledThemePackages() {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void verifyPendingInstall(int id, int verificationCode) {
throw new UnsupportedOperationException();
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 5089b9d..835f39f 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -1,5 +1,6 @@
//
// Copyright 2006 The Android Open Source Project
+// This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
//
// State bundle. Used to pass around stuff like command-line args.
//
@@ -49,7 +50,7 @@ public:
Bundle(void)
: mCmd(kCommandUnknown), mVerbose(false), mAndroidList(false),
mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),
- mUpdate(false), mExtending(false),
+ mUpdate(false), mExtending(false), mExtendedPackageId(0),
mRequireLocalization(false), mPseudolocalize(false),
mWantUTF16(false), mValues(false),
mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),
@@ -92,6 +93,8 @@ public:
void setUpdate(bool val) { mUpdate = val; }
bool getExtending(void) const { return mExtending; }
void setExtending(bool val) { mExtending = val; }
+ int getExtendedPackageId(void) const { return mExtendedPackageId; }
+ void setExtendedPackageId(int val) { mExtendedPackageId = val; }
bool getRequireLocalization(void) const { return mRequireLocalization; }
void setRequireLocalization(bool val) { mRequireLocalization = val; }
bool getPseudolocalize(void) const { return mPseudolocalize; }
@@ -249,6 +252,7 @@ private:
bool mMakePackageDirs;
bool mUpdate;
bool mExtending;
+ int mExtendedPackageId;
bool mRequireLocalization;
bool mPseudolocalize;
bool mWantUTF16;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 32fecb2..e776560 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -1,5 +1,6 @@
//
// Copyright 2006 The Android Open Source Project
+// This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
//
// Android Asset Packaging Tool main entry point.
//
@@ -14,6 +15,7 @@
#include <stdlib.h>
#include <getopt.h>
#include <assert.h>
+#include <ctype.h>
using namespace android;
@@ -55,7 +57,7 @@ void usage(void)
" xmltree Print the compiled xmls in the given assets.\n"
" xmlstrings Print the strings of the given compiled xml assets.\n\n", gProgName);
fprintf(stderr,
- " %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n"
+ " %s p[ackage] [-d][-f][-m][-u][-v][-x[ extending-resource-id]][-z][-M AndroidManifest.xml] \\\n"
" [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n"
" [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
" [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\n"
@@ -119,7 +121,7 @@ void usage(void)
#endif
" -u update existing packages (add new, replace older, remove deleted files)\n"
" -v verbose output\n"
- " -x create extending (non-application) resource IDs\n"
+ " -x either create or assign (if specified) extending (non-application) resource IDs\n"
" -z require localization of resource attributes marked with\n"
" localization=\"suggested\"\n"
" -A additional directory in which to find raw asset files\n"
@@ -320,6 +322,14 @@ int main(int argc, char* const argv[])
break;
case 'x':
bundle.setExtending(true);
+ argc--;
+ argv++;
+ if (!argc || !isdigit(argv[0][0])) {
+ argc++;
+ argv--;
+ } else {
+ bundle.setExtendedPackageId(atoi(argv[0]));
+ }
break;
case 'z':
bundle.setRequireLocalization(true);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 52ebaf0..7fd429c 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -1,5 +1,6 @@
//
// Copyright 2006 The Android Open Source Project
+// This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
//
// Build resource files from raw assets.
//
@@ -3755,7 +3756,16 @@ sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
mHaveAppPackage = true;
p = new Package(package, 127);
} else {
- p = new Package(package, mNextPackageId);
+ int extendedPackageId = mBundle->getExtendedPackageId();
+ if (extendedPackageId != 0) {
+ if ((uint32_t)extendedPackageId < mNextPackageId) {
+ fprintf(stderr, "Package ID %d already in use!\n", mNextPackageId);
+ return NULL;
+ }
+ p = new Package(package, extendedPackageId);
+ } else {
+ p = new Package(package, mNextPackageId);
+ }
}
//printf("*** NEW PACKAGE: \"%s\" id=%d\n",
// String8(package).string(), p->getAssignedId());
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 1ccbc40..b4dd542 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -119,4 +119,14 @@ public class BridgePowerManager implements IPowerManager {
public void wakeUp(long time) throws RemoteException {
// pass for now.
}
+
+ @Override
+ public void cpuBoost(int duration) throws RemoteException {
+ // pass for now
+ }
+
+ @Override
+ public void setKeyboardVisibility(boolean visible) {
+
+ }
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 55de065..1e67938 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -61,6 +61,8 @@ interface IWifiManager
void setCountryCode(String country, boolean persist);
+ String getCountryCode();
+
void setFrequencyBand(int band, boolean persist);
int getFrequencyBand();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 0e29882..e3ef913 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -814,6 +814,18 @@ public class WifiManager {
}
/**
+ * Get the operational country code.
+ * @hide
+ */
+ public String getCountryCode() {
+ try {
+ return mService.getCountryCode();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Set the operational frequency band.
* @param band One of
* {@link #WIFI_FREQUENCY_BAND_AUTO},
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 5e25623..733fb91 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -798,4 +798,6 @@ public class WifiNative {
public boolean p2pServDiscCancelReq(String id) {
return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
}
+
+ public native static boolean setMode(int mode);
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index dafa8e8..67e8ac9 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -209,6 +209,9 @@ public class WifiStateMachine extends StateMachine {
/* Tracks current frequency mode */
private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
+ /* Tracks current country code */
+ private String mCountryCode = "GB";
+
/* Tracks if we are filtering Multicast v4 packets. Default is to filter. */
private AtomicBoolean mFilteringMulticastV4Packets = new AtomicBoolean(true);
@@ -758,6 +761,7 @@ public class WifiStateMachine extends StateMachine {
public void setWifiEnabled(boolean enable) {
mLastEnableUid.set(Binder.getCallingUid());
if (enable) {
+ WifiNative.setMode(0);
/* Argument is the state that is entered prior to load */
sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
sendMessage(CMD_START_SUPPLICANT);
@@ -774,6 +778,7 @@ public class WifiStateMachine extends StateMachine {
public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
mLastApEnableUid.set(Binder.getCallingUid());
if (enable) {
+ WifiNative.setMode(1);
/* Argument is the state that is entered prior to load */
sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
@@ -1079,6 +1084,13 @@ public class WifiStateMachine extends StateMachine {
}
/**
+ * Returns the operational country code
+ */
+ public String getCountryCode() {
+ return mCountryCode;
+ }
+
+ /**
* Set the operational frequency band
* @param band
* @param persist {@code true} if the setting should be remembered.
@@ -1334,7 +1346,15 @@ public class WifiStateMachine extends StateMachine {
if (countryCode != null && !countryCode.isEmpty()) {
setCountryCode(countryCode, false);
} else {
- //use driver default
+ // On wifi-only devices, some drivers don't find hidden SSIDs unless DRIVER COUNTRY
+ // is called. Use the default country code to ping the driver.
+ ConnectivityManager cm =
+ (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (!cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) {
+ setCountryCode(mCountryCode, false);
+ }
+
+ // In other case, mcc tables from carrier do the trick of starting up the wifi driver
}
}
@@ -2799,9 +2819,12 @@ public class WifiStateMachine extends StateMachine {
break;
case CMD_SET_COUNTRY_CODE:
String country = (String) message.obj;
- if (DBG) log("set country code " + country);
- if (!mWifiNative.setCountryCode(country.toUpperCase())) {
- loge("Failed to set country code " + country);
+ String countryCode = country != null ? country.toUpperCase() : null;
+ if (DBG) log("set country code " + countryCode);
+ if (mWifiNative.setCountryCode(countryCode)) {
+ mCountryCode = countryCode;
+ } else {
+ loge("Failed to set country code " + countryCode);
}
break;
case CMD_SET_FREQUENCY_BAND:
@@ -3412,6 +3435,10 @@ public class WifiStateMachine extends StateMachine {
case CMD_SET_HIGH_PERF_MODE:
deferMessage(message);
break;
+ /* Defer scan request since we should not switch to other channels at DHCP */
+ case CMD_START_SCAN:
+ deferMessage(message);
+ break;
default:
return NOT_HANDLED;
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 039319d..135b418 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -302,7 +302,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
mContext = context;
//STOPSHIP: get this from native side
- mInterface = "p2p0";
+ mInterface = SystemProperties.get("wifi.p2pinterface", "p2p0");
mActivityMgr = (ActivityManager)context.getSystemService(Activity.ACTIVITY_SERVICE);
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");