summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk12
-rw-r--r--CleanSpec.mk1
-rw-r--r--api/11.xml560
-rw-r--r--api/current.xml417
-rw-r--r--build/phone-hdpi-512-dalvik-heap.mk4
-rw-r--r--build/phone-hdpi-dalvik-heap.mk1
-rw-r--r--build/tablet-dalvik-heap.mk4
-rw-r--r--core/java/android/accounts/AccountManagerService.java8
-rw-r--r--core/java/android/animation/package.html19
-rw-r--r--core/java/android/app/Activity.java23
-rw-r--r--core/java/android/app/ActivityManager.java7
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/app/Notification.java160
-rw-r--r--core/java/android/appwidget/AppWidgetProviderInfo.java2
-rw-r--r--core/java/android/bluetooth/BluetoothInputDevice.java13
-rw-r--r--core/java/android/bluetooth/BluetoothPan.java13
-rw-r--r--core/java/android/os/StrictMode.java141
-rw-r--r--core/java/android/provider/MediaStore.java2
-rw-r--r--core/java/android/provider/Settings.java15
-rw-r--r--core/java/android/server/BluetoothEventLoop.java34
-rw-r--r--core/java/android/view/DragEvent.java2
-rw-r--r--core/java/android/view/GLES20Canvas.java32
-rw-r--r--core/java/android/view/KeyCharacterMap.java6
-rwxr-xr-xcore/java/android/view/KeyEvent.java2
-rw-r--r--core/java/android/view/View.java1
-rw-r--r--core/java/android/view/ViewGroup.java18
-rw-r--r--core/java/android/view/ViewRoot.java15
-rw-r--r--core/java/android/view/VolumePanel.java19
-rw-r--r--core/java/android/view/WindowManager.java2
-rw-r--r--core/java/android/view/inputmethod/InputMethodInfo.java15
-rw-r--r--core/java/android/webkit/BrowserFrame.java11
-rw-r--r--core/java/android/webkit/CacheManager.java8
-rw-r--r--core/java/android/webkit/WebView.java117
-rw-r--r--core/java/android/webkit/WebViewCore.java2
-rw-r--r--core/java/android/widget/AdapterViewAnimator.java12
-rw-r--r--core/java/android/widget/AdapterViewFlipper.java8
-rw-r--r--core/java/android/widget/Advanceable.java2
-rw-r--r--core/java/android/widget/ArrayAdapter.java79
-rw-r--r--core/java/android/widget/AutoCompleteTextView.java23
-rw-r--r--core/java/android/widget/DatePicker.java17
-rw-r--r--core/java/android/widget/HorizontalScrollView.java8
-rw-r--r--core/java/android/widget/NumberPicker.java185
-rw-r--r--core/java/android/widget/PopupWindow.java10
-rw-r--r--core/java/android/widget/RemoteViews.java12
-rw-r--r--core/java/android/widget/RemoteViewsService.java50
-rw-r--r--core/java/android/widget/ScrollView.java8
-rw-r--r--core/java/android/widget/StackView.java15
-rw-r--r--core/java/android/widget/SuggestionsAdapter.java24
-rw-r--r--core/java/android/widget/TextView.java10
-rw-r--r--core/java/android/widget/TimePicker.java309
-rw-r--r--core/java/android/widget/Toast.java159
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java4
-rw-r--r--core/jni/AndroidRuntime.cpp8
-rw-r--r--core/jni/android/graphics/Region.cpp11
-rw-r--r--core/jni/android_bluetooth_common.h25
-rw-r--r--core/jni/android_server_BluetoothEventLoop.cpp50
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp13
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_selection_divider.9.pngbin0 -> 297 bytes
-rw-r--r--core/res/res/drawable-hdpi/vpn_connected.png (renamed from packages/VpnServices/res/drawable/vpn_connected.png)bin757 -> 757 bytes
-rw-r--r--core/res/res/drawable-hdpi/vpn_disconnected.png (renamed from packages/VpnServices/res/drawable/vpn_disconnected.png)bin717 -> 717 bytes
-rw-r--r--core/res/res/drawable-ldpi/vpn_connected.pngbin0 -> 757 bytes
-rw-r--r--core/res/res/drawable-ldpi/vpn_disconnected.pngbin0 -> 717 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_selection_divider.9.pngbin0 -> 262 bytes
-rw-r--r--core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.pngbin0 -> 204 bytes
-rw-r--r--core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.pngbin0 -> 202 bytes
-rw-r--r--core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.pngbin0 -> 203 bytes
-rw-r--r--core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.pngbin0 -> 201 bytes
-rw-r--r--core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.pngbin0 -> 210 bytes
-rw-r--r--core/res/res/drawable-mdpi/vpn_connected.pngbin0 -> 757 bytes
-rw-r--r--core/res/res/drawable-mdpi/vpn_disconnected.pngbin0 -> 717 bytes
-rw-r--r--core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.pngbin0 -> 393 bytes
-rw-r--r--core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.pngbin0 -> 759 bytes
-rw-r--r--core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.pngbin0 -> 983 bytes
-rw-r--r--core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin0 -> 629 bytes
-rw-r--r--core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.pngbin0 -> 979 bytes
-rw-r--r--core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.pngbin0 -> 1102 bytes
-rw-r--r--core/res/res/drawable/lockscreen_password_field_dark.xml26
-rw-r--r--core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml126
-rw-r--r--core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml4
-rw-r--r--core/res/res/layout/date_picker.xml19
-rw-r--r--core/res/res/layout/date_picker_holo.xml86
-rw-r--r--core/res/res/layout/time_picker.xml31
-rw-r--r--core/res/res/layout/time_picker_holo.xml69
-rw-r--r--core/res/res/values-xlarge-land/dimens.xml3
-rw-r--r--core/res/res/values-xlarge/dimens.xml10
-rwxr-xr-xcore/res/res/values/attrs.xml28
-rw-r--r--core/res/res/values/public.xml14
-rwxr-xr-xcore/res/res/values/strings.xml7
-rw-r--r--core/res/res/values/styles.xml36
-rw-r--r--core/res/res/values/themes.xml21
-rwxr-xr-xcore/res/res/xml-xlarge/password_kbd_qwerty.xml94
-rwxr-xr-xcore/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml139
-rwxr-xr-xcore/res/res/xml-xlarge/password_kbd_symbols.xml106
-rwxr-xr-xcore/res/res/xml-xlarge/password_kbd_symbols_shift.xml100
-rw-r--r--docs/html/guide/guide_toc.cs3
-rw-r--r--docs/html/guide/topics/graphics/2d-graphics.jd172
-rw-r--r--docs/html/guide/topics/graphics/animation.jd839
-rw-r--r--docs/html/resources/resources-data.js92
-rw-r--r--docs/html/resources/samples/images/NfcDemo.pngbin0 -> 12750 bytes
-rw-r--r--docs/html/resources/samples/images/hcgallery.pngbin0 -> 307725 bytes
-rw-r--r--drm/common/IDrmManagerService.cpp4
-rw-r--r--graphics/java/android/graphics/Region.java8
-rw-r--r--graphics/java/android/renderscript/Allocation.java166
-rw-r--r--graphics/java/android/renderscript/ScriptC.java3
-rw-r--r--include/private/surfaceflinger/SharedBufferStack.h9
-rw-r--r--include/ui/Input.h9
-rw-r--r--keystore/java/android/security/Credentials.java14
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/Caches.cpp4
-rw-r--r--libs/hwui/Caches.h3
-rw-r--r--libs/hwui/Debug.h4
-rw-r--r--libs/hwui/DisplayListRenderer.cpp26
-rw-r--r--libs/hwui/DisplayListRenderer.h5
-rw-r--r--libs/hwui/FontRenderer.cpp18
-rw-r--r--libs/hwui/LayerRenderer.cpp9
-rw-r--r--libs/hwui/LayerRenderer.h3
-rw-r--r--libs/hwui/OpenGLRenderer.cpp120
-rw-r--r--libs/hwui/OpenGLRenderer.h18
-rw-r--r--libs/hwui/Patch.cpp8
-rw-r--r--libs/hwui/PathCache.cpp185
-rw-r--r--libs/hwui/PathCache.h139
-rw-r--r--libs/hwui/Properties.h2
-rw-r--r--libs/hwui/ShapeCache.cpp72
-rw-r--r--libs/hwui/ShapeCache.h492
-rw-r--r--libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs8
-rw-r--r--libs/rs/java/tests/src/com/android/rs/test/math.rs167
-rw-r--r--libs/rs/rsContext.cpp8
-rw-r--r--libs/rs/rsScriptC.cpp25
-rw-r--r--libs/rs/rsScriptC.h2
-rw-r--r--libs/rs/rsScriptC_LibCL.cpp53
-rw-r--r--libs/rs/scriptc/rs_cl.rsh799
-rw-r--r--libs/rs/scriptc/rs_types.rsh7
-rw-r--r--libs/surfaceflinger_client/SharedBufferStack.cpp38
-rw-r--r--libs/ui/EGLUtils.cpp23
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp2
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaImageItem.java115
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaVideoItem.java113
-rwxr-xr-xmedia/jni/mediaeditor/Android.mk2
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorLogging.h7
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp14
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp15
-rw-r--r--media/libstagefright/AwesomePlayer.cpp33
-rw-r--r--media/libstagefright/MPEG4Writer.cpp9
-rw-r--r--media/libstagefright/NuCachedSource2.cpp2
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp3
-rw-r--r--packages/SystemUI/assets/fonts/AndroidClock.ttfbin2336 -> 2480 bytes
-rw-r--r--packages/SystemUI/assets/fonts/AndroidClock2.ttfbin2212 -> 2408 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.pngbin0 -> 6409 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.pngbin0 -> 2839 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.pngbin0 -> 6719 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.pngbin0 -> 7928 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.pngbin0 -> 6519 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.pngbin0 -> 8044 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.pngbin0 -> 8263 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.pngbin0 -> 3240 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.pngbin0 -> 6991 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.pngbin0 -> 5093 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.pngbin0 -> 6664 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.pngbin1914 -> 1914 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.pngbin3458 -> 3485 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.pngbin1440 -> 1950 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.pngbin0 -> 212 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.pngbin0 -> 7826 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.pngbin0 -> 41746 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.pngbin0 -> 5453 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/panel_notification.pngbin0 -> 7854 bytes
-rwxr-xr-xpackages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.pngbin128421 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml22
-rw-r--r--packages/SystemUI/res/drawable/status_bar_item_background.xml1
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar.xml5
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml16
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml158
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml158
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml2
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java99
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java162
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java2
-rw-r--r--packages/VpnServices/Android.mk16
-rw-r--r--packages/VpnServices/AndroidManifest.xml22
-rw-r--r--packages/VpnServices/MODULE_LICENSE_APACHE20
-rw-r--r--packages/VpnServices/NOTICE190
-rw-r--r--packages/VpnServices/res/values-ar/strings.xml8
-rw-r--r--packages/VpnServices/res/values-bg/strings.xml8
-rw-r--r--packages/VpnServices/res/values-ca/strings.xml8
-rw-r--r--packages/VpnServices/res/values-cs/strings.xml8
-rw-r--r--packages/VpnServices/res/values-da/strings.xml8
-rw-r--r--packages/VpnServices/res/values-de/strings.xml8
-rw-r--r--packages/VpnServices/res/values-el/strings.xml8
-rw-r--r--packages/VpnServices/res/values-en-rGB/strings.xml8
-rw-r--r--packages/VpnServices/res/values-es-rUS/strings.xml8
-rw-r--r--packages/VpnServices/res/values-es/strings.xml8
-rw-r--r--packages/VpnServices/res/values-fa/strings.xml8
-rw-r--r--packages/VpnServices/res/values-fi/strings.xml8
-rw-r--r--packages/VpnServices/res/values-fr/strings.xml8
-rw-r--r--packages/VpnServices/res/values-hr/strings.xml8
-rw-r--r--packages/VpnServices/res/values-hu/strings.xml8
-rw-r--r--packages/VpnServices/res/values-in/strings.xml8
-rw-r--r--packages/VpnServices/res/values-it/strings.xml8
-rw-r--r--packages/VpnServices/res/values-iw/strings.xml8
-rw-r--r--packages/VpnServices/res/values-ja/strings.xml8
-rw-r--r--packages/VpnServices/res/values-ko/strings.xml8
-rw-r--r--packages/VpnServices/res/values-lt/strings.xml8
-rw-r--r--packages/VpnServices/res/values-lv/strings.xml8
-rw-r--r--packages/VpnServices/res/values-nb/strings.xml8
-rw-r--r--packages/VpnServices/res/values-nl/strings.xml8
-rw-r--r--packages/VpnServices/res/values-pl/strings.xml8
-rw-r--r--packages/VpnServices/res/values-pt-rPT/strings.xml8
-rw-r--r--packages/VpnServices/res/values-pt/strings.xml8
-rw-r--r--packages/VpnServices/res/values-rm/strings.xml8
-rw-r--r--packages/VpnServices/res/values-ro/strings.xml8
-rw-r--r--packages/VpnServices/res/values-ru/strings.xml8
-rw-r--r--packages/VpnServices/res/values-sk/strings.xml8
-rw-r--r--packages/VpnServices/res/values-sl/strings.xml8
-rw-r--r--packages/VpnServices/res/values-sr/strings.xml8
-rw-r--r--packages/VpnServices/res/values-sv/strings.xml8
-rw-r--r--packages/VpnServices/res/values-th/strings.xml8
-rw-r--r--packages/VpnServices/res/values-tl/strings.xml8
-rw-r--r--packages/VpnServices/res/values-tr/strings.xml8
-rw-r--r--packages/VpnServices/res/values-uk/strings.xml8
-rw-r--r--packages/VpnServices/res/values-vi/strings.xml8
-rw-r--r--packages/VpnServices/res/values-zh-rCN/strings.xml8
-rw-r--r--packages/VpnServices/res/values-zh-rTW/strings.xml8
-rwxr-xr-xpackages/VpnServices/res/values/strings.xml10
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java188
-rw-r--r--policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java25
-rw-r--r--services/audioflinger/AudioFlinger.cpp18
-rw-r--r--services/input/InputReader.cpp2
-rw-r--r--services/input/tests/InputReader_test.cpp2
-rw-r--r--services/java/com/android/server/ConnectivityService.java3
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java60
-rw-r--r--services/java/com/android/server/WindowManagerService.java12
-rwxr-xr-xservices/java/com/android/server/am/ActivityManagerService.java3
-rw-r--r--services/sensorservice/RotationVectorSensor.cpp4
-rw-r--r--services/sensorservice/RotationVectorSensor.h4
-rw-r--r--services/surfaceflinger/Layer.cpp16
-rw-r--r--services/surfaceflinger/Layer.h1
-rw-r--r--services/surfaceflinger/LayerBase.cpp16
-rw-r--r--services/surfaceflinger/LayerBase.h7
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp44
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java72
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java2
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java2
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml18
-rw-r--r--tests/HwAccelerationTest/res/layout/view_layers_3.xml48
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java92
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java108
-rw-r--r--vpn/java/android/net/vpn/IVpnService.aidl13
-rw-r--r--vpn/java/android/net/vpn/VpnManager.java106
-rw-r--r--vpn/java/com/android/server/vpn/DaemonProxy.java (renamed from packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java)0
-rw-r--r--vpn/java/com/android/server/vpn/L2tpIpsecPskService.java (renamed from packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java)0
-rw-r--r--vpn/java/com/android/server/vpn/L2tpIpsecService.java (renamed from packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java)0
-rw-r--r--vpn/java/com/android/server/vpn/L2tpService.java (renamed from packages/VpnServices/src/com/android/server/vpn/L2tpService.java)0
-rw-r--r--vpn/java/com/android/server/vpn/PptpService.java (renamed from packages/VpnServices/src/com/android/server/vpn/PptpService.java)0
-rw-r--r--vpn/java/com/android/server/vpn/VpnConnectingError.java (renamed from packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java)0
-rw-r--r--vpn/java/com/android/server/vpn/VpnDaemons.java (renamed from packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java)0
-rw-r--r--vpn/java/com/android/server/vpn/VpnService.java (renamed from packages/VpnServices/src/com/android/server/vpn/VpnService.java)35
-rw-r--r--vpn/java/com/android/server/vpn/VpnServiceBinder.java117
-rw-r--r--wifi/java/android/net/wifi/SupplicantStateTracker.java23
-rw-r--r--wifi/java/android/net/wifi/WifiMonitor.java31
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java21
264 files changed, 6351 insertions, 3467 deletions
diff --git a/Android.mk b/Android.mk
index 5d989d1d72fd..7728b0210c74 100644
--- a/Android.mk
+++ b/Android.mk
@@ -384,10 +384,10 @@ web_docs_sample_code_flags := \
-hdf android.hasSamples 1 \
-samplecode $(sample_dir)/AccessibilityService \
resources/samples/AccessibilityService "Accessibility Service" \
- -samplecode $(sample_dir)/ApiDemos \
- resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/AccelerometerPlay \
resources/samples/AccelerometerPlay "Accelerometer Play" \
+ -samplecode $(sample_dir)/ApiDemos \
+ resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/BackupRestore \
resources/samples/BackupRestore "Backup and Restore" \
-samplecode $(sample_dir)/BluetoothChat \
@@ -396,16 +396,20 @@ web_docs_sample_code_flags := \
resources/samples/BusinessCard "Business Card" \
-samplecode $(sample_dir)/ContactManager \
resources/samples/ContactManager "Contact Manager" \
- -samplecode $(sample_dir)/CubeLiveWallpaper \
- resources/samples/CubeLiveWallpaper "Live Wallpaper" \
+ -samplecode $(sample_dir)/CubeLiveWallpaper \
+ resources/samples/CubeLiveWallpaper "Cube Live Wallpaper" \
-samplecode $(sample_dir)/Home \
resources/samples/Home "Home" \
+ -samplecode $(sample_dir)/Honeycomb-Gallery \
+ resources/samples/Honeycomb-Gallery "Honeycomb Gallery" \
-samplecode $(sample_dir)/JetBoy \
resources/samples/JetBoy "JetBoy" \
-samplecode $(sample_dir)/LunarLander \
resources/samples/LunarLander "Lunar Lander" \
-samplecode $(sample_dir)/MultiResolution \
resources/samples/MultiResolution "Multiple Resolutions" \
+ -samplecode $(sample_dir)/NFCDemo \
+ resources/samples/NFCDemo "NFC Demo" \
-samplecode $(sample_dir)/NotePad \
resources/samples/NotePad "Note Pad" \
-samplecode $(sample_dir)/SampleSyncAdapter \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1acb620bee2d..337b30f0843a 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -89,6 +89,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/target/common/obj/APPS/Music2_in
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_aacdec_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_mp3dec_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/11.xml b/api/11.xml
index 6c06a0afda1a..5f3cd5115bbd 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -2721,6 +2721,17 @@
visibility="public"
>
</field>
+<field name="calendarViewStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843613"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="candidatesTextStyleSpans"
type="int"
transient="false"
@@ -3282,6 +3293,17 @@
visibility="public"
>
</field>
+<field name="datePickerStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843612"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dateTextAppearance"
type="int"
transient="false"
@@ -8727,17 +8749,6 @@
visibility="public"
>
</field>
-<field name="solidColor"
- type="int"
- transient="false"
- volatile="false"
- value="16843594"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="soundEffectsEnabled"
type="int"
transient="false"
@@ -10905,6 +10916,17 @@
visibility="public"
>
</field>
+<field name="windowCloseOnTouchOutside"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843611"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="windowContentOverlay"
type="int"
transient="false"
@@ -15982,7 +16004,7 @@
type="int"
transient="false"
volatile="false"
- value="16974069"
+ value="16974060"
static="true"
final="true"
deprecated="not deprecated"
@@ -16033,44 +16055,44 @@
visibility="public"
>
</field>
-<field name="Widget_DropDownItem"
+<field name="Widget_DatePicker"
type="int"
transient="false"
volatile="false"
- value="16973867"
+ value="16974063"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_DropDownItem_Spinner"
+<field name="Widget_DropDownItem"
type="int"
transient="false"
volatile="false"
- value="16973868"
+ value="16973867"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_EditText"
+<field name="Widget_DropDownItem_Spinner"
type="int"
transient="false"
volatile="false"
- value="16973859"
+ value="16973868"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_EditText_NumberPickerInputText"
+<field name="Widget_EditText"
type="int"
transient="false"
volatile="false"
- value="16974061"
+ value="16973859"
static="true"
final="true"
deprecated="not deprecated"
@@ -16268,7 +16290,7 @@
type="int"
transient="false"
volatile="false"
- value="16974070"
+ value="16974061"
static="true"
final="true"
deprecated="not deprecated"
@@ -16308,44 +16330,44 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_DropDownItem"
+<field name="Widget_Holo_DatePicker"
type="int"
transient="false"
volatile="false"
- value="16973995"
+ value="16974064"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_Holo_DropDownItem_Spinner"
+<field name="Widget_Holo_DropDownItem"
type="int"
transient="false"
volatile="false"
- value="16973996"
+ value="16973995"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_Holo_EditText"
+<field name="Widget_Holo_DropDownItem_Spinner"
type="int"
transient="false"
volatile="false"
- value="16973972"
+ value="16973996"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_Holo_EditText_NumberPickerInputText"
+<field name="Widget_Holo_EditText"
type="int"
transient="false"
volatile="false"
- value="16974064"
+ value="16973972"
static="true"
final="true"
deprecated="not deprecated"
@@ -16396,28 +16418,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974065"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974063"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light"
type="int"
transient="false"
@@ -16543,7 +16543,7 @@
type="int"
transient="false"
volatile="false"
- value="16974071"
+ value="16974062"
static="true"
final="true"
deprecated="not deprecated"
@@ -16616,17 +16616,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974067"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ExpandableListView"
type="int"
transient="false"
@@ -16671,28 +16660,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974068"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974066"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ListPopupWindow"
type="int"
transient="false"
@@ -17221,28 +17188,6 @@
visibility="public"
>
</field>
-<field name="Widget_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974062"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974060"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_ImageWell"
type="int"
transient="false"
@@ -24311,6 +24256,19 @@
<parameter name="uri" type="android.net.Uri">
</parameter>
</method>
+<method name="setFinishOnTouchOutside"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="finish" type="boolean">
+</parameter>
+</method>
<method name="setIntent"
return="void"
abstract="false"
@@ -39754,6 +39712,16 @@
visibility="public"
>
</field>
+<field name="previewImage"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="provider"
type="android.content.ComponentName"
transient="false"
@@ -136099,6 +136067,17 @@
visibility="public"
>
</method>
+<method name="getPreserveEGLContextOnPause"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getRenderMode"
return="int"
abstract="false"
@@ -136270,6 +136249,19 @@
<parameter name="glWrapper" type="android.opengl.GLSurfaceView.GLWrapper">
</parameter>
</method>
+<method name="setPreserveEGLContextOnPause"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="preserveOnPause" type="boolean">
+</parameter>
+</method>
<method name="setRenderMode"
return="void"
abstract="false"
@@ -146702,6 +146694,16 @@
visibility="public"
>
</constructor>
+<constructor name="StrictMode.VmPolicy.Builder"
+ type="android.os.StrictMode.VmPolicy.Builder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="base" type="android.os.StrictMode.VmPolicy">
+</parameter>
+</constructor>
<method name="build"
return="android.os.StrictMode.VmPolicy"
abstract="false"
@@ -146713,6 +146715,17 @@
visibility="public"
>
</method>
+<method name="detectActivityLeaks"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="detectAll"
return="android.os.StrictMode.VmPolicy.Builder"
abstract="false"
@@ -146779,6 +146792,21 @@
visibility="public"
>
</method>
+<method name="setClassInstanceLimit"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="klass" type="java.lang.Class">
+</parameter>
+<parameter name="instanceLimit" type="int">
+</parameter>
+</method>
</class>
<class name="SystemClock"
extends="java.lang.Object"
@@ -160206,17 +160234,6 @@
visibility="public"
>
</field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.provider.action.MTP_SESSION_END&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="ACTION_VIDEO_CAPTURE"
type="java.lang.String"
transient="false"
@@ -163328,22 +163345,22 @@
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER"
+<field name="ACTION_INPUT_METHOD_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value="&quot;android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER&quot;"
+ value="&quot;android.settings.INPUT_METHOD_SETTINGS&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_SETTINGS"
+<field name="ACTION_INPUT_METHOD_SUBTYPE_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value="&quot;android.settings.INPUT_METHOD_SETTINGS&quot;"
+ value="&quot;android.settings.INPUT_METHOD_SUBTYPE_SETTINGS&quot;"
static="true"
final="true"
deprecated="not deprecated"
@@ -163570,6 +163587,17 @@
visibility="public"
>
</field>
+<field name="EXTRA_INPUT_METHOD_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;input_method_id&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Settings.NameValueTable"
extends="java.lang.Object"
@@ -166486,6 +166514,74 @@
<parameter name="d" type="float[]">
</parameter>
</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copy2DRangeFrom"
return="void"
abstract="false"
@@ -166665,6 +166761,58 @@
<parameter name="b" type="android.graphics.Bitmap">
</parameter>
</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copyTo"
return="void"
abstract="false"
@@ -175634,6 +175782,17 @@
visibility="public"
>
</field>
+<field name="KEY_PARAM_PAN"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;pan&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="KEY_PARAM_STREAM"
type="java.lang.String"
transient="false"
@@ -175656,6 +175815,17 @@
visibility="public"
>
</field>
+<field name="KEY_PARAM_VOLUME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;volume&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<interface name="TextToSpeech.OnInitListener"
abstract="true"
@@ -206247,25 +206417,6 @@
>
</field>
</class>
-<class name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- extends="android.util.AndroidRuntimeException"
- abstract="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- type="android.view.KeyCharacterMap.KeyCharacterMapUnavailableException"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="msg" type="java.lang.String">
-</parameter>
-</constructor>
-</class>
<class name="KeyCharacterMap.KeyData"
extends="java.lang.Object"
abstract="false"
@@ -206325,6 +206476,25 @@
>
</field>
</class>
+<class name="KeyCharacterMap.UnavailableException"
+ extends="android.util.AndroidRuntimeException"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="KeyCharacterMap.UnavailableException"
+ type="android.view.KeyCharacterMap.UnavailableException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msg" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
<class name="KeyEvent"
extends="android.view.InputEvent"
abstract="false"
@@ -219396,6 +219566,14 @@
<parameter name="view" type="android.view.View">
</parameter>
</constructor>
+<constructor name="View.DragShadowBuilder"
+ type="android.view.View.DragShadowBuilder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
<method name="getView"
return="android.view.View"
abstract="false"
@@ -231248,8 +231426,21 @@
visibility="public"
>
</method>
-<method name="getSubtypes"
- return="java.util.ArrayList&lt;android.view.inputmethod.InputMethodSubtype&gt;"
+<method name="getSubtypeAt"
+ return="android.view.inputmethod.InputMethodSubtype"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
+<method name="getSubtypeCount"
+ return="int"
abstract="false"
native="false"
synchronized="false"
@@ -236046,6 +236237,48 @@
</parameter>
</method>
</class>
+<class name="WebStorage.Origin"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getOrigin"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getQuota"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUsage"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
<interface name="WebStorage.QuotaUpdater"
abstract="true"
static="true"
@@ -240442,6 +240675,17 @@
visibility="public"
>
</method>
+<method name="fyiWillBeAdvancedByHostKThx"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAdapter"
return="android.widget.Adapter"
abstract="false"
@@ -240697,17 +240941,6 @@
visibility="public"
>
</method>
-<method name="willBeAdvancedByHost"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
</class>
<class name="AdapterViewFlipper"
extends="android.widget.AdapterViewAnimator"
@@ -249267,7 +249500,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangedListener">
+<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangeListener">
</parameter>
</method>
<method name="setValue"
@@ -249374,7 +249607,7 @@
>
</field>
</interface>
-<interface name="NumberPicker.OnValueChangedListener"
+<interface name="NumberPicker.OnValueChangeListener"
abstract="true"
static="true"
final="false"
@@ -252338,21 +252571,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="viewId" type="int">
-</parameter>
-<parameter name="intent" type="android.content.Intent">
-</parameter>
-</method>
-<method name="setRemoteAdapter"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
<parameter name="appWidgetId" type="int">
</parameter>
<parameter name="viewId" type="int">
diff --git a/api/current.xml b/api/current.xml
index 73581f16e829..5f3cd5115bbd 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2721,6 +2721,17 @@
visibility="public"
>
</field>
+<field name="calendarViewStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843613"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="candidatesTextStyleSpans"
type="int"
transient="false"
@@ -3282,6 +3293,17 @@
visibility="public"
>
</field>
+<field name="datePickerStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843612"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dateTextAppearance"
type="int"
transient="false"
@@ -8727,17 +8749,6 @@
visibility="public"
>
</field>
-<field name="solidColor"
- type="int"
- transient="false"
- volatile="false"
- value="16843594"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="soundEffectsEnabled"
type="int"
transient="false"
@@ -15993,7 +16004,7 @@
type="int"
transient="false"
volatile="false"
- value="16974069"
+ value="16974060"
static="true"
final="true"
deprecated="not deprecated"
@@ -16044,44 +16055,44 @@
visibility="public"
>
</field>
-<field name="Widget_DropDownItem"
+<field name="Widget_DatePicker"
type="int"
transient="false"
volatile="false"
- value="16973867"
+ value="16974063"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_DropDownItem_Spinner"
+<field name="Widget_DropDownItem"
type="int"
transient="false"
volatile="false"
- value="16973868"
+ value="16973867"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_EditText"
+<field name="Widget_DropDownItem_Spinner"
type="int"
transient="false"
volatile="false"
- value="16973859"
+ value="16973868"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_EditText_NumberPickerInputText"
+<field name="Widget_EditText"
type="int"
transient="false"
volatile="false"
- value="16974061"
+ value="16973859"
static="true"
final="true"
deprecated="not deprecated"
@@ -16279,7 +16290,7 @@
type="int"
transient="false"
volatile="false"
- value="16974070"
+ value="16974061"
static="true"
final="true"
deprecated="not deprecated"
@@ -16319,44 +16330,44 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_DropDownItem"
+<field name="Widget_Holo_DatePicker"
type="int"
transient="false"
volatile="false"
- value="16973995"
+ value="16974064"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_Holo_DropDownItem_Spinner"
+<field name="Widget_Holo_DropDownItem"
type="int"
transient="false"
volatile="false"
- value="16973996"
+ value="16973995"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_Holo_EditText"
+<field name="Widget_Holo_DropDownItem_Spinner"
type="int"
transient="false"
volatile="false"
- value="16973972"
+ value="16973996"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="Widget_Holo_EditText_NumberPickerInputText"
+<field name="Widget_Holo_EditText"
type="int"
transient="false"
volatile="false"
- value="16974064"
+ value="16973972"
static="true"
final="true"
deprecated="not deprecated"
@@ -16407,28 +16418,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974065"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974063"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light"
type="int"
transient="false"
@@ -16554,7 +16543,7 @@
type="int"
transient="false"
volatile="false"
- value="16974071"
+ value="16974062"
static="true"
final="true"
deprecated="not deprecated"
@@ -16627,17 +16616,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974067"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ExpandableListView"
type="int"
transient="false"
@@ -16682,28 +16660,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974068"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974066"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ListPopupWindow"
type="int"
transient="false"
@@ -17232,28 +17188,6 @@
visibility="public"
>
</field>
-<field name="Widget_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974062"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974060"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_ImageWell"
type="int"
transient="false"
@@ -39778,6 +39712,16 @@
visibility="public"
>
</field>
+<field name="previewImage"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="provider"
type="android.content.ComponentName"
transient="false"
@@ -146771,6 +146715,17 @@
visibility="public"
>
</method>
+<method name="detectActivityLeaks"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="detectAll"
return="android.os.StrictMode.VmPolicy.Builder"
abstract="false"
@@ -160279,17 +160234,6 @@
visibility="public"
>
</field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.provider.action.MTP_SESSION_END&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="ACTION_VIDEO_CAPTURE"
type="java.lang.String"
transient="false"
@@ -163401,22 +163345,22 @@
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER"
+<field name="ACTION_INPUT_METHOD_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value="&quot;android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER&quot;"
+ value="&quot;android.settings.INPUT_METHOD_SETTINGS&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_SETTINGS"
+<field name="ACTION_INPUT_METHOD_SUBTYPE_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value="&quot;android.settings.INPUT_METHOD_SETTINGS&quot;"
+ value="&quot;android.settings.INPUT_METHOD_SUBTYPE_SETTINGS&quot;"
static="true"
final="true"
deprecated="not deprecated"
@@ -163643,6 +163587,17 @@
visibility="public"
>
</field>
+<field name="EXTRA_INPUT_METHOD_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;input_method_id&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Settings.NameValueTable"
extends="java.lang.Object"
@@ -166559,6 +166514,74 @@
<parameter name="d" type="float[]">
</parameter>
</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copy2DRangeFrom"
return="void"
abstract="false"
@@ -166738,6 +166761,58 @@
<parameter name="b" type="android.graphics.Bitmap">
</parameter>
</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copyTo"
return="void"
abstract="false"
@@ -206342,25 +206417,6 @@
>
</field>
</class>
-<class name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- extends="android.util.AndroidRuntimeException"
- abstract="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- type="android.view.KeyCharacterMap.KeyCharacterMapUnavailableException"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="msg" type="java.lang.String">
-</parameter>
-</constructor>
-</class>
<class name="KeyCharacterMap.KeyData"
extends="java.lang.Object"
abstract="false"
@@ -206420,6 +206476,25 @@
>
</field>
</class>
+<class name="KeyCharacterMap.UnavailableException"
+ extends="android.util.AndroidRuntimeException"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="KeyCharacterMap.UnavailableException"
+ type="android.view.KeyCharacterMap.UnavailableException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msg" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
<class name="KeyEvent"
extends="android.view.InputEvent"
abstract="false"
@@ -231351,8 +231426,21 @@
visibility="public"
>
</method>
-<method name="getSubtypes"
- return="java.util.ArrayList&lt;android.view.inputmethod.InputMethodSubtype&gt;"
+<method name="getSubtypeAt"
+ return="android.view.inputmethod.InputMethodSubtype"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
+<method name="getSubtypeCount"
+ return="int"
abstract="false"
native="false"
synchronized="false"
@@ -240587,6 +240675,17 @@
visibility="public"
>
</method>
+<method name="fyiWillBeAdvancedByHostKThx"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAdapter"
return="android.widget.Adapter"
abstract="false"
@@ -240842,17 +240941,6 @@
visibility="public"
>
</method>
-<method name="willBeAdvancedByHost"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
</class>
<class name="AdapterViewFlipper"
extends="android.widget.AdapterViewAnimator"
@@ -249412,7 +249500,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangedListener">
+<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangeListener">
</parameter>
</method>
<method name="setValue"
@@ -249519,7 +249607,7 @@
>
</field>
</interface>
-<interface name="NumberPicker.OnValueChangedListener"
+<interface name="NumberPicker.OnValueChangeListener"
abstract="true"
static="true"
final="false"
@@ -252483,21 +252571,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="viewId" type="int">
-</parameter>
-<parameter name="intent" type="android.content.Intent">
-</parameter>
-</method>
-<method name="setRemoteAdapter"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
<parameter name="appWidgetId" type="int">
</parameter>
<parameter name="viewId" type="int">
@@ -260298,7 +260371,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/build/phone-hdpi-512-dalvik-heap.mk b/build/phone-hdpi-512-dalvik-heap.mk
index afc45ee11486..630cf035a741 100644
--- a/build/phone-hdpi-512-dalvik-heap.mk
+++ b/build/phone-hdpi-512-dalvik-heap.mk
@@ -19,5 +19,5 @@
PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapstartsize=5m \
- dalvik.vm.smallheapsize=32m \
- dalvik.vm.heapsize=32m
+ dalvik.vm.growthlimit=32m \
+ dalvik.vm.heapsize=128m
diff --git a/build/phone-hdpi-dalvik-heap.mk b/build/phone-hdpi-dalvik-heap.mk
index ee30b92079cd..ab33b9654bed 100644
--- a/build/phone-hdpi-dalvik-heap.mk
+++ b/build/phone-hdpi-dalvik-heap.mk
@@ -18,5 +18,4 @@
PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapstartsize=5m \
- dalvik.vm.smallheapsize=32m \
dalvik.vm.heapsize=32m
diff --git a/build/tablet-dalvik-heap.mk b/build/tablet-dalvik-heap.mk
index 9cb2f6bdebc1..37c3ec531a80 100644
--- a/build/tablet-dalvik-heap.mk
+++ b/build/tablet-dalvik-heap.mk
@@ -18,5 +18,5 @@
PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapstartsize=5m \
- dalvik.vm.smallheapsize=48m \
- dalvik.vm.heapsize=48m
+ dalvik.vm.growthlimit=48m \
+ dalvik.vm.heapsize=256m
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index e6eaf71634aa..2c99f14d2554 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -722,6 +722,9 @@ public class AccountManagerService
final String[] argsAccountId = {String.valueOf(accountId)};
db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
+ synchronized (mCacheLock) {
+ mAuthTokenCache.remove(account);
+ }
db.setTransactionSuccessful();
}
} finally {
@@ -1812,6 +1815,11 @@ public class AccountManagerService
try {
db.execSQL("DELETE from " + TABLE_AUTHTOKENS);
db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''");
+
+ synchronized (mCacheLock) {
+ mAuthTokenCache = new HashMap<Account, HashMap<String, String>>();
+ }
+
db.setTransactionSuccessful();
} finally {
db.endTransaction();
diff --git a/core/java/android/animation/package.html b/core/java/android/animation/package.html
index b66669b49018..ff4326092c41 100644
--- a/core/java/android/animation/package.html
+++ b/core/java/android/animation/package.html
@@ -1,6 +1,21 @@
<html>
<body>
-Provides classes for animating values over time, and setting those values on target
-objects.
+<p>
+These classes provide functionality for the property animation system, which allows you
+to animate object properties of any type. <code>int</code>, <code>float</code>, and hexadecimal
+color values are supported by default. You can animate any other type by telling the system how
+to calculate the values for that given type with a custom {@link android.animation.TypeEvaluator}.
+</p>
+
+<p>
+You can set many different types of interpolators (contained in {@link android.view.animation}),
+specify {@link android.animation.Keyframe keyframes}, or group animations to play sequentially
+or simultaneously (with {@link android.animation.AnimatorSet}) to further control your animation
+behaviors.</p>
+
+<p>
+For a guide on how to use the property animation system, see the
+<a href="{@docRoot}guide/topics/media/index.html">Animation</a> developer guide.
+</p>
</body>
</html>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0a640708a02f..2aef860a62b0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1762,8 +1762,11 @@ public class Activity extends ContextThemeWrapper
/**
* Set the activity content from a layout resource. The resource will be
* inflated, adding all top-level views to the activity.
- *
+ *
* @param layoutResID Resource ID to be inflated.
+ *
+ * @see #setContentView(android.view.View)
+ * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
@@ -1773,9 +1776,17 @@ public class Activity extends ContextThemeWrapper
/**
* Set the activity content to an explicit view. This view is placed
* directly into the activity's view hierarchy. It can itself be a complex
- * view hierarhcy.
+ * view hierarchy. When calling this method, the layout parameters of the
+ * specified view are ignored. Both the width and the height of the view are
+ * set by default to {@link ViewGroup.LayoutParams#MATCH_PARENT}. To use
+ * your own layout parameters, invoke
+ * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}
+ * instead.
*
* @param view The desired content to display.
+ *
+ * @see #setContentView(int)
+ * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
public void setContentView(View view) {
getWindow().setContentView(view);
@@ -1785,10 +1796,13 @@ public class Activity extends ContextThemeWrapper
/**
* Set the activity content to an explicit view. This view is placed
* directly into the activity's view hierarchy. It can itself be a complex
- * view hierarhcy.
+ * view hierarchy.
*
* @param view The desired content to display.
* @param params Layout parameters for the view.
+ *
+ * @see #setContentView(android.view.View)
+ * @see #setContentView(int)
*/
public void setContentView(View view, ViewGroup.LayoutParams params) {
getWindow().setContentView(view, params);
@@ -4433,6 +4447,9 @@ public class Activity extends ContextThemeWrapper
mStopped = true;
}
mResumed = false;
+
+ // Check for Activity leaks, if enabled.
+ StrictMode.conditionallyCheckInstanceCounts();
}
final void performDestroy() {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d5aa9619962c..133a7d04003f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -64,8 +64,11 @@ public class ActivityManager {
static public int staticGetMemoryClass() {
// Really brain dead right now -- just take this from the configured
// vm heap size, and assume it is in megabytes and thus ends with "m".
- String vmHeapSize = SystemProperties.get("dalvik.vm.smallheapsize", "16m");
- return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+ String vmHeapSize = SystemProperties.get("dalvik.vm.growthlimit", "");
+ if (vmHeapSize != null && !"".equals(vmHeapSize)) {
+ return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+ }
+ return staticGetLargeMemoryClass();
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index db046ef73597..7cf60f99efbd 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3463,7 +3463,7 @@ public final class ActivityThread {
}
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
- // XXX bump up Dalvik's heap.
+ dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
}
// If the app is being launched for full backup or restore, bring it up in
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0243b02524e4..de84c566e5f7 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -34,6 +34,9 @@ import java.text.NumberFormat;
* A class that represents how a persistent notification is to be presented to
* the user using the {@link android.app.NotificationManager}.
*
+ * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
+ * easier to construct Notifications.</p>
+ *
* <p>For a guide to creating notifications, see the
* <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
* Bar Notifications</a> document in the Dev Guide.</p>
@@ -119,15 +122,8 @@ public class Notification implements Parcelable
/**
* An intent to launch instead of posting the notification to the status bar.
- * Only for use with extremely high-priority notifications demanding the user's
- * <strong>immediate</strong> attention, such as an incoming phone call or
- * alarm clock that the user has explicitly set to a particular time.
- * If this facility is used for something else, please give the user an option
- * to turn it off and use a normal notification, as this can be extremely
- * disruptive.
- *
- * <p>Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification
- * will reach the user even when other notifications are suppressed.
+ *
+ * @see Notification.Builder#setFullScreenIntent
*/
public PendingIntent fullScreenIntent;
@@ -278,7 +274,7 @@ public class Notification implements Parcelable
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if the notification should be canceled when it is clicked by the
- * user.
+ * user. On tablets, the
*/
public static final int FLAG_AUTO_CANCEL = 0x00000010;
@@ -618,6 +614,10 @@ public class Notification implements Parcelable
return sb.toString();
}
+ /**
+ * Builder class for {@link Notification} objects. Allows easier control over
+ * all the flags, as well as help constructing the typical notification layouts.
+ */
public static class Builder {
private Context mContext;
@@ -644,6 +644,16 @@ public class Notification implements Parcelable
private int mDefaults;
private int mFlags;
+ /**
+ * Constructor.
+ *
+ * Automatically sets the when field to {@link System#currentTimeMillis()
+ * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
+ *
+ * @param context A {@link Context} that will be used to construct the
+ * RemoteViews. The Context will not be held past the lifetime of this
+ * Builder object.
+ */
public Builder(Context context) {
mContext = context;
@@ -652,96 +662,192 @@ public class Notification implements Parcelable
mAudioStreamType = STREAM_DEFAULT;
}
+ /**
+ * Set the time that the event occurred. Notifications in the panel are
+ * sorted by this time.
+ */
public Builder setWhen(long when) {
mWhen = when;
return this;
}
+ /**
+ * Set the small icon to use in the notification layouts. Different classes of devices
+ * may return different sizes. See the UX guidelines for more information on how to
+ * design these icons.
+ *
+ * @param icon A resource ID in the application's package of the drawble to use.
+ */
public Builder setSmallIcon(int icon) {
mSmallIcon = icon;
return this;
}
+ /**
+ * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
+ * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
+ * LevelListDrawable}.
+ *
+ * @param icon A resource ID in the application's package of the drawble to use.
+ * @param level The level to use for the icon.
+ *
+ * @see android.graphics.drawable.LevelListDrawable
+ */
public Builder setSmallIcon(int icon, int level) {
mSmallIcon = icon;
mSmallIconLevel = level;
return this;
}
+ /**
+ * Set the title (first row) of the notification, in a standard notification.
+ */
public Builder setContentTitle(CharSequence title) {
mContentTitle = title;
return this;
}
+ /**
+ * Set the text (second row) of the notification, in a standard notification.
+ */
public Builder setContentText(CharSequence text) {
mContentText = text;
return this;
}
+ /**
+ * Set the large number at the right-hand side of the notification. This is
+ * equivalent to setContentInfo, although it might show the number in a different
+ * font size for readability.
+ */
public Builder setNumber(int number) {
mNumber = number;
return this;
}
+ /**
+ * Set the large text at the right-hand side of the notification.
+ */
public Builder setContentInfo(CharSequence info) {
mContentInfo = info;
return this;
}
+ /**
+ * Supply a custom RemoteViews to use instead of the standard one.
+ */
public Builder setContent(RemoteViews views) {
mContentView = views;
return this;
}
+ /**
+ * Supply a {@link PendingIntent} to send when the notification is clicked.
+ * If you do not supply an intent, you can now add PendingIntents to individual
+ * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
+ * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
+ */
public Builder setContentIntent(PendingIntent intent) {
mContentIntent = intent;
return this;
}
+ /**
+ * Supply a {@link PendingIntent} to send when the notification is cleared by the user
+ * directly from the notification panel. For example, this intent is sent when the user
+ * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
+ * intent is not sent when the application calls {@link NotificationManager#cancel
+ * NotificationManager.cancel(int)}.
+ */
public Builder setDeleteIntent(PendingIntent intent) {
mDeleteIntent = intent;
return this;
}
+ /**
+ * An intent to launch instead of posting the notification to the status bar.
+ * Only for use with extremely high-priority notifications demanding the user's
+ * <strong>immediate</strong> attention, such as an incoming phone call or
+ * alarm clock that the user has explicitly set to a particular time.
+ * If this facility is used for something else, please give the user an option
+ * to turn it off and use a normal notification, as this can be extremely
+ * disruptive.
+ *
+ * @param intent The pending intent to launch.
+ * @param highPriority Passing true will cause this notification to be sent
+ * even if other notifications are suppressed.
+ */
public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
mFullScreenIntent = intent;
setFlag(FLAG_HIGH_PRIORITY, highPriority);
return this;
}
+ /**
+ * Set the text that is displayed in the status bar when the notification first
+ * arrives.
+ */
public Builder setTicker(CharSequence tickerText) {
mTickerText = tickerText;
return this;
}
+ /**
+ * Set the text that is displayed in the status bar when the notification first
+ * arrives, and also a RemoteViews object that may be displayed instead on some
+ * devices.
+ */
public Builder setTicker(CharSequence tickerText, RemoteViews views) {
mTickerText = tickerText;
mTickerView = views;
return this;
}
+ /**
+ * Set the large icon that is shown in the ticker and notification.
+ */
public Builder setLargeIcon(Bitmap icon) {
mLargeIcon = icon;
return this;
}
+ /**
+ * Set the sound to play. It will play on the default stream.
+ */
public Builder setSound(Uri sound) {
mSound = sound;
mAudioStreamType = STREAM_DEFAULT;
return this;
}
+ /**
+ * Set the sound to play. It will play on the stream you supply.
+ *
+ * @see #STREAM_DEFAULT
+ * @see AudioManager for the <code>STREAM_</code> constants.
+ */
public Builder setSound(Uri sound, int streamType) {
mSound = sound;
mAudioStreamType = streamType;
return this;
}
+ /**
+ * Set the vibration pattern to use.
+ *
+ * @see android.os.Vibrator for a discussion of the <code>pattern</code>
+ * parameter.
+ */
public Builder setVibrate(long[] pattern) {
mVibrate = pattern;
return this;
}
+ /**
+ * Set the argb value that you would like the LED on the device to blnk, as well as the
+ * rate. The rate is specified in terms of the number of milliseconds to be on
+ * and then the number of milliseconds to be off.
+ */
public Builder setLights(int argb, int onMs, int offMs) {
mLedArgb = argb;
mLedOnMs = onMs;
@@ -749,21 +855,51 @@ public class Notification implements Parcelable
return this;
}
+ /**
+ * Set whether this is an ongoing notification.
+ *
+ * <p>Ongoing notifications differ from regular notifications in the following ways:
+ * <ul>
+ * <li>Ongoing notifications are sorted above the regular notifications in the
+ * notification panel.</li>
+ * <li>Ongoing notifications do not have an 'X' close button, and are not affected
+ * by the "Clear all" button.
+ * </ul>
+ */
public Builder setOngoing(boolean ongoing) {
setFlag(FLAG_ONGOING_EVENT, ongoing);
return this;
}
+ /**
+ * Set this flag if you would only like the sound, vibrate
+ * and ticker to be played if the notification is not already showing.
+ */
public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
return this;
}
+ /**
+ * Setting this flag will make it so the notification is automatically
+ * canceled when the user clicks it in the panel. The PendingIntent
+ * set with {@link #setDeleteIntent} will be broadcast when the notification
+ * is canceled.
+ */
public Builder setAutoCancel(boolean autoCancel) {
setFlag(FLAG_AUTO_CANCEL, autoCancel);
return this;
}
+ /**
+ * Set the default notification options that will be used.
+ * <p>
+ * The value should be one or more of the following fields combined with
+ * bitwise-or:
+ * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
+ * <p>
+ * For all default values, use {@link #DEFAULT_ALL}.
+ */
public Builder setDefaults(int defaults) {
mDefaults = defaults;
return this;
@@ -834,6 +970,10 @@ public class Notification implements Parcelable
}
}
+ /**
+ * Combine all of the options that have been set and return a new {@link Notification}
+ * object.
+ */
public Notification getNotification() {
Notification n = new Notification();
n.when = mWhen;
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index a3db01dfe683..fe33782f6e2d 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -121,8 +121,6 @@ public class AppWidgetProviderInfo implements Parcelable {
*
* <p>This field corresponds to the <code>android:previewImage</code> attribute in
* the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
- *
- * @hide Pending API approval
*/
public int previewImage;
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index bc8a836183bc..a70de59a48f6 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -85,6 +85,19 @@ public final class BluetoothInputDevice {
*/
public static final int PRIORITY_UNDEFINED = -1;
+ /**
+ * Return codes for the connect and disconnect Bluez / Dbus calls.
+ */
+ public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+
+ public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+
+ public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+
+ public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+
+ public static final int INPUT_OPERATION_SUCCESS = 5004;
+
private final IBluetooth mService;
private final Context mContext;
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 7dee25e4afa8..1f07349b4c13 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -70,6 +70,19 @@ public final class BluetoothPan {
public static final int STATE_CONNECTED = 2;
public static final int STATE_DISCONNECTING = 3;
+ /**
+ * Return codes for the connect and disconnect Bluez / Dbus calls.
+ */
+ public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000;
+
+ public static final int PAN_CONNECT_FAILED_ALREADY_CONNECTED = 1001;
+
+ public static final int PAN_CONNECT_FAILED_ATTEMPT_FAILED = 1002;
+
+ public static final int PAN_OPERATION_GENERIC_FAILURE = 1003;
+
+ public static final int PAN_OPERATION_SUCCESS = 1004;
+
private final IBluetooth mService;
private final Context mContext;
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 997ea53cfc97..ae92b09ed484 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -30,6 +30,7 @@ import com.android.internal.os.RuntimeInit;
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -184,6 +185,15 @@ public final class StrictMode {
/**
* @hide
*/
+ private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000; // for VmPolicy
+
+ private static final int ALL_VM_DETECT_BITS =
+ DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS |
+ DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS;
+
+ /**
+ * @hide
+ */
public static final int PENALTY_LOG = 0x10; // normal android.util.Log
// Used for both process and thread policy:
@@ -573,11 +583,15 @@ public final class StrictMode {
} else if (mClassInstanceLimit == null) {
mClassInstanceLimit = new HashMap<Class, Integer>();
}
+ mMask |= DETECT_VM_INSTANCE_LEAKS;
mClassInstanceLimit.put(klass, instanceLimit);
return this;
}
- private Builder detectActivityLeaks() {
+ /**
+ * Detect leaks of {@link android.app.Activity} subclasses.
+ */
+ public Builder detectActivityLeaks() {
return enable(DETECT_VM_ACTIVITY_LEAKS);
}
@@ -585,8 +599,8 @@ public final class StrictMode {
* Detect everything that's potentially suspect.
*
* <p>In the Honeycomb release this includes leaks of
- * SQLite cursors and other closable objects but will
- * likely expand in future releases.
+ * SQLite cursors, Activities, and other closable objects
+ * but will likely expand in future releases.
*/
public Builder detectAll() {
return enable(DETECT_VM_ACTIVITY_LEAKS |
@@ -1347,6 +1361,41 @@ public final class StrictMode {
}
/**
+ * @hide
+ */
+ public static void conditionallyCheckInstanceCounts() {
+ VmPolicy policy = getVmPolicy();
+ if (policy.classInstanceLimit.size() == 0) {
+ return;
+ }
+ Runtime.getRuntime().gc();
+ // Note: classInstanceLimit is immutable, so this is lock-free
+ for (Class klass : policy.classInstanceLimit.keySet()) {
+ int limit = policy.classInstanceLimit.get(klass);
+ long instances = VMDebug.countInstancesOfClass(klass, false);
+ if (instances <= limit) {
+ continue;
+ }
+ Throwable tr = new InstanceCountViolation(klass, instances, limit);
+ onVmPolicyViolation(tr.getMessage(), tr);
+ }
+ }
+
+ private static long sLastInstanceCountCheckMillis = 0;
+ private static boolean sIsIdlerRegistered = false; // guarded by sProcessIdleHandler
+ private static final MessageQueue.IdleHandler sProcessIdleHandler =
+ new MessageQueue.IdleHandler() {
+ public boolean queueIdle() {
+ long now = SystemClock.uptimeMillis();
+ if (now - sLastInstanceCountCheckMillis > 30 * 1000) {
+ sLastInstanceCountCheckMillis = now;
+ conditionallyCheckInstanceCounts();
+ }
+ return true;
+ }
+ };
+
+ /**
* Sets the policy for what actions in the VM process (on any
* thread) should be detected, as well as the penalty if such
* actions occur.
@@ -1357,6 +1406,19 @@ public final class StrictMode {
sVmPolicy = policy;
sVmPolicyMask = policy.mask;
setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
+
+ Looper looper = Looper.getMainLooper();
+ if (looper != null) {
+ MessageQueue mq = looper.mQueue;
+ synchronized (sProcessIdleHandler) {
+ if (policy.classInstanceLimit.size() == 0) {
+ mq.removeIdleHandler(sProcessIdleHandler);
+ } else if (!sIsIdlerRegistered) {
+ mq.addIdleHandler(sProcessIdleHandler);
+ sIsIdlerRegistered = true;
+ }
+ }
+ }
}
/**
@@ -1406,19 +1468,39 @@ public final class StrictMode {
onVmPolicyViolation(message, originStack);
}
+ // Map from VM violation fingerprint to uptime millis.
+ private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>();
+
/**
* @hide
*/
public static void onVmPolicyViolation(String message, Throwable originStack) {
- if ((sVmPolicyMask & PENALTY_LOG) != 0) {
- Log.e(TAG, message, originStack);
+ final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
+ final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
+ final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0;
+ final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+
+ final Integer fingerprint = info.hashCode();
+ final long now = SystemClock.uptimeMillis();
+ long lastViolationTime = 0;
+ long timeSinceLastViolationMillis = Long.MAX_VALUE;
+ synchronized (sLastVmViolationTime) {
+ if (sLastVmViolationTime.containsKey(fingerprint)) {
+ lastViolationTime = sLastVmViolationTime.get(fingerprint);
+ timeSinceLastViolationMillis = now - lastViolationTime;
+ }
+ if (timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
+ sLastVmViolationTime.put(fingerprint, now);
+ }
}
- boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
- boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
+ Log.d(TAG, "Time since last vm violation: " + timeSinceLastViolationMillis);
- int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
- ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+ if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
+ Log.e(TAG, message, originStack);
+ }
+
+ int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicyMask);
if (penaltyDropbox && !penaltyDeath) {
// Common case for userdebug/eng builds. If no death and
@@ -1428,7 +1510,7 @@ public final class StrictMode {
return;
}
- if (penaltyDropbox) {
+ if (penaltyDropbox && lastViolationTime == 0) {
// The violationMask, passed to ActivityManager, is a
// subset of the original StrictMode policy bitmask, with
// only the bit violated and penalty bits to be executed
@@ -1786,6 +1868,12 @@ public final class StrictMode {
public String broadcastIntentAction;
/**
+ * If this is a instance count violation, the number of instances in memory,
+ * else -1.
+ */
+ public long numInstances = -1;
+
+ /**
* Create an uninitialized instance of ViolationInfo
*/
public ViolationInfo() {
@@ -1806,6 +1894,9 @@ public final class StrictMode {
broadcastIntentAction = broadcastIntent.getAction();
}
ThreadSpanState state = sThisThreadSpanState.get();
+ if (tr instanceof InstanceCountViolation) {
+ this.numInstances = ((InstanceCountViolation) tr).mInstances;
+ }
synchronized (state) {
int spanActiveCount = state.mActiveSize;
if (spanActiveCount > MAX_SPAN_TAGS) {
@@ -1867,6 +1958,7 @@ public final class StrictMode {
violationNumThisLoop = in.readInt();
numAnimationsRunning = in.readInt();
violationUptimeMillis = in.readLong();
+ numInstances = in.readLong();
broadcastIntentAction = in.readString();
tags = in.readStringArray();
}
@@ -1881,6 +1973,7 @@ public final class StrictMode {
dest.writeInt(violationNumThisLoop);
dest.writeInt(numAnimationsRunning);
dest.writeLong(violationUptimeMillis);
+ dest.writeLong(numInstances);
dest.writeString(broadcastIntentAction);
dest.writeStringArray(tags);
}
@@ -1895,6 +1988,9 @@ public final class StrictMode {
if (durationMillis != -1) {
pw.println(prefix + "durationMillis: " + durationMillis);
}
+ if (numInstances != -1) {
+ pw.println(prefix + "numInstances: " + numInstances);
+ }
if (violationNumThisLoop != 0) {
pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop);
}
@@ -1914,4 +2010,29 @@ public final class StrictMode {
}
}
+
+ // Dummy throwable, for now, since we don't know when or where the
+ // leaked instances came from. We might in the future, but for
+ // now we suppress the stack trace because it's useless and/or
+ // misleading.
+ private static class InstanceCountViolation extends Throwable {
+ final Class mClass;
+ final long mInstances;
+ final int mLimit;
+
+ private static final StackTraceElement[] FAKE_STACK = new StackTraceElement[1];
+ static {
+ FAKE_STACK[0] = new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit",
+ "StrictMode.java", 1);
+ }
+
+ public InstanceCountViolation(Class klass, long instances, int limit) {
+ // Note: now including instances here, otherwise signatures would all be different.
+ super(klass.toString() + "; limit=" + limit);
+ setStackTrace(FAKE_STACK);
+ mClass = klass;
+ mInstances = instances;
+ mLimit = limit;
+ }
+ }
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 9f0ea325b3c0..82fe7dede98d 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -57,6 +57,8 @@ public final class MediaStore {
* Broadcast Action: A broadcast to indicate the end of an MTP session with the host.
* This broadcast is only sent if MTP activity has modified the media database during the
* most recent MTP session.
+ *
+ * @hide
*/
public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cec99e96b7be..6f23215bb676 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -280,18 +280,25 @@ public final class Settings {
"android.settings.INPUT_METHOD_SETTINGS";
/**
- * Activity Action: Show enabler activity to enable/disable input methods and subtypes.
+ * Activity Action: Show settings to enable/disable input method subtypes.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
* safeguard against this.
* <p>
+ * To tell which input method's subtypes are displayed in the settings, add
+ * {@link #EXTRA_INPUT_METHOD_ID} extra to this Intent with the input method id.
+ * If there is no extra in this Intent, subtypes from all installed input methods
+ * will be displayed in the settings.
+ *
+ * @see android.view.inputmethod.InputMethodInfo#getId
+ * <p>
* Input: Nothing.
* <p>
* Output: Nothing.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER =
- "android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER";
+ public static final String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS =
+ "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
/**
* Activity Action: Show settings to manage the user input dictionary.
@@ -555,6 +562,8 @@ public final class Settings {
public static final String EXTRA_AUTHORITIES =
"authorities";
+ public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
+
private static final String JID_RESOURCE_PREFIX = "android";
public static final String AUTHORITY = "settings";
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 539a696bdb8e..cd3bc3e7c32a 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -748,9 +748,9 @@ class BluetoothEventLoop {
}
}
- private void onInputDeviceConnectionResult(String path, boolean result) {
+ private void onInputDeviceConnectionResult(String path, int result) {
// Success case gets handled by Property Change signal
- if (!result) {
+ if (result != BluetoothInputDevice.INPUT_OPERATION_SUCCESS) {
String address = mBluetoothService.getAddressFromObjectPath(path);
if (address == null) return;
@@ -758,9 +758,18 @@ class BluetoothEventLoop {
BluetoothDevice device = mAdapter.getRemoteDevice(address);
int state = mBluetoothService.getInputDeviceState(device);
if (state == BluetoothInputDevice.STATE_CONNECTING) {
- connected = false;
+ if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
+ connected = true;
+ } else {
+ connected = false;
+ }
} else if (state == BluetoothInputDevice.STATE_DISCONNECTING) {
- connected = true;
+ if (result == BluetoothInputDevice.INPUT_DISCONNECT_FAILED_NOT_CONNECTED) {
+ connected = false;
+ } else {
+ // There is no better way to handle this, this shouldn't happen
+ connected = true;
+ }
} else {
Log.e(TAG, "Error onInputDeviceConnectionResult. State is:" + state);
}
@@ -768,10 +777,10 @@ class BluetoothEventLoop {
}
}
- private void onPanDeviceConnectionResult(String path, boolean result) {
+ private void onPanDeviceConnectionResult(String path, int result) {
log ("onPanDeviceConnectionResult " + path + " " + result);
// Success case gets handled by Property Change signal
- if (!result) {
+ if (result != BluetoothPan.PAN_OPERATION_SUCCESS) {
String address = mBluetoothService.getAddressFromObjectPath(path);
if (address == null) return;
@@ -779,9 +788,18 @@ class BluetoothEventLoop {
BluetoothDevice device = mAdapter.getRemoteDevice(address);
int state = mBluetoothService.getPanDeviceState(device);
if (state == BluetoothPan.STATE_CONNECTING) {
- connected = false;
+ if (result == BluetoothPan.PAN_CONNECT_FAILED_ALREADY_CONNECTED) {
+ connected = true;
+ } else {
+ connected = false;
+ }
} else if (state == BluetoothPan.STATE_DISCONNECTING) {
- connected = true;
+ if (result == BluetoothPan.PAN_DISCONNECT_FAILED_NOT_CONNECTED) {
+ connected = false;
+ } else {
+ // There is no better way to handle this, this shouldn't happen
+ connected = true;
+ }
} else {
Log.e(TAG, "Error onPanDeviceConnectionResult. State is: "
+ state + " result: "+ result);
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 6634f008ecc0..25b680e65b94 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -274,7 +274,7 @@ public static final int ACTION_DRAG_EXITED = 6;
public String toString() {
return "DragEvent{" + Integer.toHexString(System.identityHashCode(this))
+ " action=" + mAction + " @ (" + mX + ", " + mY + ") desc=" + mClipDescription
- + " data=" + mClipData + " result=" + mDragResult
+ + " data=" + mClipData + " local=" + mLocalState + " result=" + mDragResult
+ "}";
}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 99b686e075d0..d82f051eebd4 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -452,11 +452,14 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public int saveLayer(float left, float top, float right, float bottom, Paint paint,
int saveFlags) {
- boolean hasColorFilter = paint != null && setupColorFilter(paint);
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
- if (hasColorFilter) nResetModifiers(mRenderer);
- return count;
+ if (left < right && top < bottom) {
+ boolean hasColorFilter = paint != null && setupColorFilter(paint);
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
+ if (hasColorFilter) nResetModifiers(mRenderer);
+ return count;
+ }
+ return save(saveFlags);
}
private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
@@ -471,7 +474,10 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
int saveFlags) {
- return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+ if (left < right && top < bottom) {
+ return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+ }
+ return save(saveFlags);
}
private native int nSaveLayerAlpha(int renderer, float left, float top, float right,
@@ -629,9 +635,13 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawCircle(float cx, float cy, float radius, Paint paint) {
- throw new UnsupportedOperationException();
+ boolean hasModifier = setupModifiers(paint);
+ nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
+ if (hasModifier) nResetModifiers(mRenderer);
}
+ private native void nDrawCircle(int renderer, float cx, float cy, float radius, int paint);
+
@Override
public void drawColor(int color) {
drawColor(color, PorterDuff.Mode.SRC_OVER);
@@ -767,9 +777,15 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
- // TODO: Implement
+ boolean hasModifier = setupModifiers(paint);
+ nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
+ rx, ry, paint.mNativePaint);
+ if (hasModifier) nResetModifiers(mRenderer);
}
+ private native void nDrawRoundRect(int renderer, float left, float top,
+ float right, float bottom, float rx, float y, int paint);
+
@Override
public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
if ((index | count | (index + count) | (text.length - index - count)) < 0) {
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 7ca5a1917f40..3ff7fcd6d778 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -170,7 +170,7 @@ public class KeyCharacterMap {
*
* @param deviceId The device id of the keyboard.
* @return The associated key character map.
- * @throws {@link KeyCharacterMapUnavailableException} if the key character map
+ * @throws {@link UnavailableException} if the key character map
* could not be loaded because it was malformed or the default key character map
* is missing from the system.
*/
@@ -692,8 +692,8 @@ public class KeyCharacterMap {
/**
* Thrown by {@link KeyCharacterMap#load} when a key character map could not be loaded.
*/
- public static class KeyCharacterMapUnavailableException extends AndroidRuntimeException {
- public KeyCharacterMapUnavailableException(String msg) {
+ public static class UnavailableException extends AndroidRuntimeException {
+ public UnavailableException(String msg) {
super(msg);
}
}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index ecf1aefc935e..941331a224dc 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -2163,7 +2163,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
* Gets the {@link KeyCharacterMap} associated with the keyboard device.
*
* @return The associated key character map.
- * @throws {@link KeyCharacterMapUnavailableException} if the key character map
+ * @throws {@link UnavailableException} if the key character map
* could not be loaded because it was malformed or the default key character map
* is missing from the system.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 270ea7689e1a..2447f8cd986f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -58,7 +58,6 @@ import android.util.PoolableManager;
import android.util.Pools;
import android.util.SparseArray;
import android.view.ContextMenu.ContextMenuInfo;
-import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d1781cc0d96c..115431e2fac6 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -935,15 +935,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
} break;
case DragEvent.ACTION_DRAG_ENDED: {
- // If a child was notified about an ongoing drag, it's told that it's over
- for (View child : mDragNotifiedChildren) {
- child.dispatchDragEvent(event);
- }
-
// Release the bookkeeping now that the drag lifecycle has ended
- mDragNotifiedChildren.clear();
- mCurrentDrag.recycle();
- mCurrentDrag = null;
+ if (mDragNotifiedChildren != null) {
+ for (View child : mDragNotifiedChildren) {
+ // If a child was notified about an ongoing drag, it's told that it's over
+ child.dispatchDragEvent(event);
+ }
+
+ mDragNotifiedChildren.clear();
+ mCurrentDrag.recycle();
+ mCurrentDrag = null;
+ }
// We consider drag-ended to have been handled if one of our children
// had offered to handle the drag.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 961b633170d8..97983ba050ca 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -489,17 +489,17 @@ public final class ViewRoot extends Handler implements ViewParent,
// Try to enable hardware acceleration if requested
if (attrs != null &&
(attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
- // Don't enable hardware acceleration when we're not on the main thread
- if (Looper.getMainLooper() != Looper.myLooper()) {
- Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware acceleration "
- + "outside of the main thread, aborting");
- return;
- }
-
// Only enable hardware acceleration if we are not in the system process
// The window manager creates ViewRoots to display animated preview windows
// of launching apps and we don't want those to be hardware accelerated
if (!HardwareRenderer.sRendererDisabled) {
+ // Don't enable hardware acceleration when we're not on the main thread
+ if (Looper.getMainLooper() != Looper.myLooper()) {
+ Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
+ + "acceleration outside of the main thread, aborting");
+ return;
+ }
+
final boolean translucent = attrs.format != PixelFormat.OPAQUE;
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
@@ -2803,6 +2803,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// Report the drop result when we're done
if (what == DragEvent.ACTION_DROP) {
+ mDragDescription = null;
try {
Log.i(TAG, "Reporting drop result: " + result);
sWindowSession.reportDropResult(mWindow, result);
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index e21824e0647d..e447dbb8a5f2 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -284,10 +284,11 @@ public class VolumePanel extends Handler
synchronized (this) {
ToneGenerator toneGen = getOrCreateToneGenerator(streamType);
- toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
+ if (toneGen != null) {
+ toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
+ sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
+ }
}
-
- sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
}
protected void onStopSounds() {
@@ -319,10 +320,16 @@ public class VolumePanel extends Handler
private ToneGenerator getOrCreateToneGenerator(int streamType) {
synchronized (this) {
if (mToneGenerators[streamType] == null) {
- return mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
- } else {
- return mToneGenerators[streamType];
+ try {
+ mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
+ } catch (RuntimeException e) {
+ if (LOGD) {
+ Log.d(TAG, "ToneGenerator constructor failed with "
+ + "RuntimeException: " + e);
+ }
+ }
}
+ return mToneGenerators[streamType];
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c54a3cf15310..8eb42690229c 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -817,7 +817,7 @@ public interface WindowManager extends ViewManager {
public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;
/**
- * Desired operating mode for any soft input area. May any combination
+ * Desired operating mode for any soft input area. May be any combination
* of:
*
* <ul>
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index defd104510bb..32eec9fa0e55 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -265,10 +265,19 @@ public final class InputMethodInfo implements Parcelable {
}
/**
- * Return the subtypes of Input Method.
+ * Return the count of the subtypes of Input Method.
*/
- public ArrayList<InputMethodSubtype> getSubtypes() {
- return mSubtypes;
+ public int getSubtypeCount() {
+ return mSubtypes.size();
+ }
+
+ /**
+ * Return the Input Method's subtype at the specified index.
+ *
+ * @param index the index of the subtype to return.
+ */
+ public InputMethodSubtype getSubtypeAt(int index) {
+ return mSubtypes.get(index);
}
/**
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index e246717b7241..ec3c32971c26 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -1177,6 +1177,17 @@ class BrowserFrame extends Handler {
contentDisposition, mimeType, contentLength);
}
+ /**
+ * Called by JNI when we load a page over SSL.
+ */
+ private void setCertificate(String issuedTo, String issuedBy,
+ long validNotBeforeMillis, long validNotAfterMillis) {
+ Date validNotBefore = new Date(validNotBeforeMillis);
+ Date validNotAfter = new Date(validNotAfterMillis);
+ mCallbackProxy.onReceivedCertificate(new SslCertificate(
+ issuedTo, issuedBy, validNotBefore, validNotAfter));
+ }
+
//==========================================================================
// native functions
//==========================================================================
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 6073f7a92414..a553a4592720 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -244,6 +244,9 @@ public final class CacheManager {
* obtained from {@link android.webkit.CacheManager.CacheResult#getLocalPath}, this
* identifies the cache file.
*
+ * Cache files are not guaranteed to be in this directory before
+ * CacheManager#getCacheFile(String, Map<String, String>) is called.
+ *
* @return File The base directory of the cache.
*
* @deprecated Access to the HTTP cache will be removed in a future release.
@@ -611,8 +614,9 @@ public final class CacheManager {
return true;
}
// delete rows in the cache database
- WebViewWorker.getHandler().sendEmptyMessage(
- WebViewWorker.MSG_CLEAR_CACHE);
+ if (!JniUtil.useChromiumHttpStack())
+ WebViewWorker.getHandler().sendEmptyMessage(WebViewWorker.MSG_CLEAR_CACHE);
+
// delete cache files in a separate thread to not block UI.
final Runnable clearCache = new Runnable() {
public void run() {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9e09c286f1d0..f5ad6feb0fac 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -408,10 +408,13 @@ public class WebView extends AbsoluteLayout
PluginFullScreenHolder mFullScreenHolder;
/**
- * Position of the last touch event.
+ * Position of the last touch event in pixels.
+ * Use integer to prevent loss of dragging delta calculation accuracy;
+ * which was done in float and converted to integer, and resulted in gradual
+ * and compounding touch position and view dragging mismatch.
*/
- private float mLastTouchX;
- private float mLastTouchY;
+ private int mLastTouchX;
+ private int mLastTouchY;
/**
* Time of the last touch event.
@@ -496,6 +499,15 @@ public class WebView extends AbsoluteLayout
// if true, multi-touch events will be passed to webkit directly before UI
private boolean mDeferMultitouch = false;
+ // Currently, multi-touch events are sent to WebKit first then back to
+ // WebView while single-touch events are handled in WebView first.
+ // So there is a chance that a single-touch move event is handled in WebView
+ // before multi-touch events are finished.
+ // if mIsHandlingMultiTouch is true, which means multi-touch event handling
+ // is not finished, then any single-touch move event will be skipped.
+ // FIXME: send single-touch events to WebKit first then back to WebView.
+ private boolean mIsHandlingMultiTouch = false;
+
// to avoid interfering with the current touch events, track them
// separately. Currently no snapping or fling in the deferred process mode
private int mDeferTouchMode = TOUCH_DONE_MODE;
@@ -2218,8 +2230,8 @@ public class WebView extends AbsoluteLayout
if (type == HitTestResult.UNKNOWN_TYPE
|| type == HitTestResult.SRC_ANCHOR_TYPE) {
// Now check to see if it is an image.
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
String text = nativeImageURI(contentX, contentY);
if (text != null) {
result.setType(type == HitTestResult.UNKNOWN_TYPE ?
@@ -2256,8 +2268,8 @@ public class WebView extends AbsoluteLayout
if (hrefMsg == null) {
return;
}
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
contentX, contentY, hrefMsg);
}
@@ -2271,8 +2283,8 @@ public class WebView extends AbsoluteLayout
*/
public void requestImageRef(Message msg) {
if (0 == mNativeClass) return; // client isn't initialized
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
String ref = nativeImageURI(contentX, contentY);
Bundle data = msg.getData();
data.putString("url", ref);
@@ -3856,8 +3868,8 @@ public class WebView extends AbsoluteLayout
* @hide pending API council approval
*/
public boolean selectText() {
- int x = viewToContentX((int) mLastTouchX + mScrollX);
- int y = viewToContentY((int) mLastTouchY + mScrollY);
+ int x = viewToContentX(mLastTouchX + mScrollX);
+ int y = viewToContentY(mLastTouchY + mScrollY);
return selectText(x, y);
}
@@ -4858,8 +4870,8 @@ public class WebView extends AbsoluteLayout
mSelectX = contentToViewX(rect.left);
mSelectY = contentToViewY(rect.top);
} else if (mLastTouchY > getVisibleTitleHeight()) {
- mSelectX = mScrollX + (int) mLastTouchX;
- mSelectY = mScrollY + (int) mLastTouchY;
+ mSelectX = mScrollX + mLastTouchX;
+ mSelectY = mScrollY + mLastTouchY;
} else {
mSelectX = mScrollX + getViewWidth() / 2;
mSelectY = mScrollY + getViewHeightWithTitle() / 2;
@@ -5235,7 +5247,7 @@ public class WebView extends AbsoluteLayout
if (event.getAction() == KeyEvent.ACTION_DOWN) {
mGotKeyDown = true;
} else {
- if (!mGotKeyDown) {
+ if (!mGotKeyDown && event.getAction() != KeyEvent.ACTION_MULTIPLE) {
/*
* We got a key up for which we were not the recipient of
* the original key down. Don't give it to the view.
@@ -5353,11 +5365,19 @@ public class WebView extends AbsoluteLayout
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "passing " + ev.getPointerCount() + " points to webkit");
}
+ if (!mIsHandlingMultiTouch) {
+ mIsHandlingMultiTouch = true;
+ }
passMultiTouchToWebKit(ev);
return true;
+ } else {
+ // Skip ACTION_MOVE for single touch if it's still handling multi-touch.
+ if (mIsHandlingMultiTouch && ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ return false;
+ }
}
- return handleTouchEventCommon(ev, ev.getX(), ev.getY());
+ return handleTouchEventCommon(ev, ev.getActionMasked(), Math.round(ev.getX()), Math.round(ev.getY()));
}
/*
@@ -5365,8 +5385,7 @@ public class WebView extends AbsoluteLayout
* (x, y) denotes current focus point, which is the touch point for single touch
* and the middle point for multi-touch.
*/
- private boolean handleTouchEventCommon(MotionEvent ev, float x, float y) {
- int action = ev.getAction();
+ private boolean handleTouchEventCommon(MotionEvent ev, int action, int x, int y) {
long eventTime = ev.getEventTime();
@@ -5377,17 +5396,16 @@ public class WebView extends AbsoluteLayout
x = Math.min(x, getViewWidth() - 1);
y = Math.min(y, getViewHeightWithTitle() - 1);
- float fDeltaX = mLastTouchX - x;
- float fDeltaY = mLastTouchY - y;
- int deltaX = (int) fDeltaX;
- int deltaY = (int) fDeltaY;
- int contentX = viewToContentX((int) x + mScrollX);
- int contentY = viewToContentY((int) y + mScrollY);
+ int deltaX = mLastTouchX - x;
+ int deltaY = mLastTouchY - y;
+ int contentX = viewToContentX(x + mScrollX);
+ int contentY = viewToContentY(y + mScrollY);
switch (action) {
case MotionEvent.ACTION_DOWN: {
mPreventDefault = PREVENT_DEFAULT_NO;
mConfirmMove = false;
+ mIsHandlingMultiTouch = false;
mInitialHitTestResult = null;
if (!mScroller.isFinished()) {
// stop the current scroll animation, but if this is
@@ -5607,8 +5625,6 @@ public class WebView extends AbsoluteLayout
mTouchMode = TOUCH_DRAG_MODE;
mLastTouchX = x;
mLastTouchY = y;
- fDeltaX = 0.0f;
- fDeltaY = 0.0f;
deltaX = 0;
deltaY = 0;
@@ -5619,9 +5635,7 @@ public class WebView extends AbsoluteLayout
// do pan
boolean done = false;
boolean keepScrollBarsVisible = false;
- if (Math.abs(fDeltaX) < 1.0f && Math.abs(fDeltaY) < 1.0f) {
- mLastTouchX = x;
- mLastTouchY = y;
+ if (deltaX == 0 && deltaY == 0) {
keepScrollBarsVisible = done = true;
} else {
if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
@@ -5670,12 +5684,6 @@ public class WebView extends AbsoluteLayout
mLastTouchY = y;
}
mHeldMotionless = MOTIONLESS_FALSE;
- } else {
- // keep the scrollbar on the screen even there is no
- // scroll
- mLastTouchX = x;
- mLastTouchY = y;
- keepScrollBarsVisible = true;
}
mLastTouchTime = eventTime;
mUserScroll = true;
@@ -5856,7 +5864,7 @@ public class WebView extends AbsoluteLayout
private void passMultiTouchToWebKit(MotionEvent ev) {
TouchEventData ted = new TouchEventData();
- ted.mAction = ev.getAction() & MotionEvent.ACTION_MASK;
+ ted.mAction = ev.getActionMasked();
final int count = ev.getPointerCount();
ted.mIds = new int[count];
ted.mPoints = new Point[count];
@@ -5875,7 +5883,7 @@ public class WebView extends AbsoluteLayout
mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
- private boolean handleMultiTouchInWebView(MotionEvent ev) {
+ private void handleMultiTouchInWebView(MotionEvent ev) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime()
+ " mTouchMode=" + mTouchMode
@@ -5888,7 +5896,7 @@ public class WebView extends AbsoluteLayout
// A few apps use WebView but don't instantiate gesture detector.
// We don't need to support multi touch for them.
- if (detector == null) return false;
+ if (detector == null) return;
float x = ev.getX();
float y = ev.getY();
@@ -5923,7 +5931,7 @@ public class WebView extends AbsoluteLayout
cancelLongPress();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
if (!mZoomManager.supportsPanDuringZoom()) {
- return false;
+ return;
}
mTouchMode = TOUCH_DRAG_MODE;
if (mVelocityTracker == null) {
@@ -5937,16 +5945,17 @@ public class WebView extends AbsoluteLayout
action = MotionEvent.ACTION_DOWN;
} else if (action == MotionEvent.ACTION_POINTER_UP) {
// set mLastTouchX/Y to the remaining point
- mLastTouchX = x;
- mLastTouchY = y;
+ mLastTouchX = Math.round(x);
+ mLastTouchY = Math.round(y);
+ mIsHandlingMultiTouch = false;
} else if (action == MotionEvent.ACTION_MOVE) {
// negative x or y indicate it is on the edge, skip it.
if (x < 0 || y < 0) {
- return false;
+ return;
}
}
- return handleTouchEventCommon(ev, x, y);
+ handleTouchEventCommon(ev, action, Math.round(x), Math.round(y));
}
private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) {
@@ -5967,8 +5976,8 @@ public class WebView extends AbsoluteLayout
private void startTouch(float x, float y, long eventTime) {
// Remember where the motion event started
- mLastTouchX = x;
- mLastTouchY = y;
+ mLastTouchX = Math.round(x);
+ mLastTouchY = Math.round(y);
mLastTouchTime = eventTime;
mVelocityTracker = VelocityTracker.obtain();
mSnapScrollMode = SNAP_NONE;
@@ -6598,8 +6607,8 @@ public class WebView extends AbsoluteLayout
return;
}
// mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
contentX + mNavSlop, contentY + mNavSlop);
nativeSelectBestAt(rect);
@@ -6630,8 +6639,8 @@ public class WebView extends AbsoluteLayout
if (!inEditingMode()) {
return;
}
- mLastTouchX = x + (float) (mWebTextView.getLeft() - mScrollX);
- mLastTouchY = y + (float) (mWebTextView.getTop() - mScrollY);
+ mLastTouchX = Math.round(x + mWebTextView.getLeft() - mScrollX);
+ mLastTouchY = Math.round(y + mWebTextView.getTop() - mScrollY);
mLastTouchTime = eventTime;
if (!mScroller.isFinished()) {
abortAnimation();
@@ -6690,8 +6699,8 @@ public class WebView extends AbsoluteLayout
mTouchMode = TOUCH_DONE_MODE;
switchOutDrawHistory();
// mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
if (getSettings().supportTouchOnly()) {
removeTouchHighlight(false);
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -7052,8 +7061,8 @@ public class WebView extends AbsoluteLayout
|| (msg.arg1 == MotionEvent.ACTION_MOVE
&& mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN)) {
cancelWebCoreTouchEvent(
- viewToContentX((int) mLastTouchX + mScrollX),
- viewToContentY((int) mLastTouchY + mScrollY),
+ viewToContentX(mLastTouchX + mScrollX),
+ viewToContentY(mLastTouchY + mScrollY),
true);
}
break;
@@ -7104,8 +7113,8 @@ public class WebView extends AbsoluteLayout
ted.mIds = new int[1];
ted.mIds[0] = 0;
ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(viewToContentX((int) mLastTouchX + mScrollX),
- viewToContentY((int) mLastTouchY + mScrollY));
+ ted.mPoints[0] = new Point(viewToContentX(mLastTouchX + mScrollX),
+ viewToContentY(mLastTouchY + mScrollY));
// metaState for long press is tricky. Should it be the
// state when the press started or when the press was
// released? Or some intermediary key state? For
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index c56f25270c6c..4fe16781027c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1770,7 +1770,7 @@ final class WebViewCore {
private void clearCache(boolean includeDiskFiles) {
mBrowserFrame.clearCache();
- if (includeDiskFiles && !JniUtil.useChromiumHttpStack()) {
+ if (includeDiskFiles) {
CacheManager.removeAllCacheFiles();
}
}
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index c27082f928f9..4c1279ff1e0c 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -981,11 +981,21 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
// items from the Adapter.
}
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} in order to advance the current view when
+ * it is being used within an app widget.
+ */
public void advance() {
showNext();
}
- public void willBeAdvancedByHost() {
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
+ * automatically advancing the views of this {@link AdapterViewAnimator} by calling
+ * {@link AdapterViewAnimator#advance()} at some point in the future. This allows subclasses to
+ * perform any required setup, for example, to stop automatically advancing their children.
+ */
+ public void fyiWillBeAdvancedByHostKThx() {
}
@Override
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index 772168863775..273c2588e90c 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -258,8 +258,14 @@ public class AdapterViewFlipper extends AdapterViewAnimator {
}
};
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
+ * automatically advancing the views of this {@link AdapterViewFlipper} by calling
+ * {@link AdapterViewFlipper#advance()} at some point in the future. This allows
+ * {@link AdapterViewFlipper} to prepare by no longer Advancing its children.
+ */
@Override
- public void willBeAdvancedByHost() {
+ public void fyiWillBeAdvancedByHostKThx() {
mAdvancedByHost = true;
updateRunning(false);
}
diff --git a/core/java/android/widget/Advanceable.java b/core/java/android/widget/Advanceable.java
index bb162de98a9e..dc13ebb7764f 100644
--- a/core/java/android/widget/Advanceable.java
+++ b/core/java/android/widget/Advanceable.java
@@ -34,5 +34,5 @@ public interface Advanceable {
* Called by the AppWidgetHost once before it begins to call advance(), allowing the
* collection to do any required setup.
*/
- public void willBeAdvancedByHost();
+ public void fyiWillBeAdvancedByHostKThx();
}
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index b4ece241ec03..593cb59c9fbb 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -25,9 +25,9 @@ import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
-import java.util.Comparator;
import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* A concrete BaseAdapter that is backed by an array of arbitrary
@@ -86,6 +86,8 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
private Context mContext;
+ // A copy of the original mObjects array, initialized from and then used instead as soon as
+ // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values.
private ArrayList<T> mOriginalValues;
private ArrayFilter mFilter;
@@ -170,15 +172,14 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param object The object to add at the end of the array.
*/
public void add(T object) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.add(object);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.add(object);
}
- } else {
- mObjects.add(object);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -187,15 +188,14 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param collection The Collection to add at the end of the array.
*/
public void addAll(Collection<? extends T> collection) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.addAll(collection);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.addAll(collection);
}
- } else {
- mObjects.addAll(collection);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -204,19 +204,18 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param items The items to add at the end of the array.
*/
public void addAll(T ... items) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
for (T item : items) {
mOriginalValues.add(item);
}
- if (mNotifyOnChange) notifyDataSetChanged();
- }
- } else {
- for (T item : items) {
- mObjects.add(item);
+ } else {
+ for (T item : items) {
+ mObjects.add(item);
+ }
}
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -226,15 +225,14 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param index The index at which the object must be inserted.
*/
public void insert(T object, int index) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.add(index, object);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.add(index, object);
}
- } else {
- mObjects.add(index, object);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -243,12 +241,12 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param object The object to remove.
*/
public void remove(T object) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.remove(object);
+ } else {
+ mObjects.remove(object);
}
- } else {
- mObjects.remove(object);
}
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -257,12 +255,12 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* Remove all elements from the list.
*/
public void clear() {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.clear();
+ } else {
+ mObjects.clear();
}
- } else {
- mObjects.clear();
}
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -274,7 +272,13 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* in this adapter.
*/
public void sort(Comparator<? super T> comparator) {
- Collections.sort(mObjects, comparator);
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
+ Collections.sort(mOriginalValues, comparator);
+ } else {
+ Collections.sort(mObjects, comparator);
+ }
+ }
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -482,6 +486,7 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
final String[] words = valueText.split(" ");
final int wordCount = words.length;
+ // Start at index 0, in case valueText starts with space(s)
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newValues.add(value);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 4d8d21f4a3e0..707b92d5c164 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -16,6 +16,8 @@
package android.widget;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
@@ -36,8 +38,6 @@ import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
-import com.android.internal.R;
-
/**
* <p>An editable text view that shows completion suggestions automatically
@@ -113,6 +113,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
private Validator mValidator = null;
+ // Set to true when text is set directly and no filtering shall be performed
private boolean mBlockCompletion;
private PassThroughClickListener mPassThroughClickListener;
@@ -721,6 +722,10 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
return;
}
+ updateList();
+ }
+
+ private void updateList() {
// the drop down is shown only when a minimum number of characters
// was typed in the text view
if (enoughToFilter()) {
@@ -840,7 +845,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
mBlockCompletion = true;
replaceText(convertSelectionToString(selectedItem));
- mBlockCompletion = false;
+ mBlockCompletion = false;
if (mItemClickListener != null) {
final ListPopupWindow list = mPopup;
@@ -903,10 +908,10 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
/** {@inheritDoc} */
public void onFilterComplete(int count) {
- updateDropDownForFilter(count);
+ updateDropDownForFilter(count, true);
}
- private void updateDropDownForFilter(int count) {
+ private void updateDropDownForFilter(int count, boolean forceShow) {
// Not attached to window, don't update drop-down
if (getWindowVisibility() == View.GONE) return;
@@ -919,7 +924,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter()) {
- if (hasFocus() && hasWindowFocus()) {
+ if (hasFocus() && hasWindowFocus() && (forceShow || isPopupShowing())) {
showDropDown();
}
} else if (!dropDownAlwaysVisible) {
@@ -1182,12 +1187,14 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
// If the popup is not showing already, showing it will cause
// the list of data set observers attached to the adapter to
// change. We can't do it from here, because we are in the middle
- // of iterating throught he list of observers.
+ // of iterating through the list of observers.
post(new Runnable() {
public void run() {
final ListAdapter adapter = mAdapter;
if (adapter != null) {
- updateDropDownForFilter(adapter.getCount());
+ // This will re-layout, thus resetting mDataChanged, so that the
+ // listView click listener stays responsive
+ updateDropDownForFilter(adapter.getCount(), false);
}
}
});
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 2c530050e736..f1786e28c501 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -30,7 +30,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
-import android.widget.NumberPicker.OnValueChangedListener;
+import android.widget.NumberPicker.OnValueChangeListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -129,29 +129,32 @@ public class DatePicker extends FrameLayout {
}
public DatePicker(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, R.attr.datePickerStyle);
}
public DatePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
+ TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
+ defStyle, 0);
boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
DEFAULT_SPINNERS_SHOWN);
boolean calendarViewShown = attributesArray.getBoolean(
R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
- int startYear = attributesArray
- .getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
+ int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
+ DEFAULT_START_YEAR);
int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
+ int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_layout,
+ R.layout.date_picker);
attributesArray.recycle();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.date_picker, this, true);
+ inflater.inflate(layoutResourceId, this, true);
- OnValueChangedListener onChangeListener = new OnValueChangedListener() {
+ OnValueChangeListener onChangeListener = new OnValueChangeListener() {
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
updateDate(mYearSpinner.getValue(), mMonthSpinner.getValue(), mDaySpinner
.getValue());
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index f6b1dbc99b40..db22a0cb1e31 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -511,8 +511,10 @@ public class HorizontalScrollView extends FrameLayout {
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
- final float x = ev.getX();
- mIsBeingDragged = true;
+ mIsBeingDragged = getChildCount() != 0;
+ if (!mIsBeingDragged) {
+ return false;
+ }
/*
* If being flinged and user touches, stop the fling. isFinished
@@ -523,7 +525,7 @@ public class HorizontalScrollView extends FrameLayout {
}
// Remember where the motion event started
- mLastMotionX = x;
+ mLastMotionX = ev.getX();
mActivePointerId = ev.getPointerId(0);
break;
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 63dbfbfc0352..08db2071da44 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -32,6 +32,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.Align;
+import android.graphics.drawable.Drawable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
@@ -39,6 +40,7 @@ import android.text.TextUtils;
import android.text.method.NumberKeyListener;
import android.util.AttributeSet;
import android.util.SparseArray;
+import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -46,7 +48,7 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.LayoutInflater.Filter;
-import android.view.animation.OvershootInterpolator;
+import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.InputMethodManager;
/**
@@ -62,8 +64,6 @@ import android.view.inputmethod.InputMethodManager;
* <p>
* For an example of using this widget, see {@link android.widget.TimePicker}.
* </p>
- *
- * @attr ref android.R.styleable#NumberPicker_solidColor
*/
@Widget
public class NumberPicker extends LinearLayout {
@@ -111,6 +111,11 @@ public class NumberPicker extends LinearLayout {
private static final float TOP_AND_BOTTOM_FADING_EDGE_STRENGTH = 0.9f;
/**
+ * The default unscaled height of the selection divider.
+ */
+ private final int UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT = 2;
+
+ /**
* The numbers accepted by the input text's {@link Filter}
*/
private static final char[] DIGIT_CHARACTERS = new char[] {
@@ -183,7 +188,7 @@ public class NumberPicker extends LinearLayout {
/**
* Listener to be notified upon current value change.
*/
- private OnValueChangedListener mOnValueChangedListener;
+ private OnValueChangeListener mOnValueChangeListener;
/**
* Listener to be notified upon scroll state change.
@@ -325,6 +330,21 @@ public class NumberPicker extends LinearLayout {
private final int mSolidColor;
/**
+ * Flag indicating if this widget supports flinging.
+ */
+ private final boolean mFlingable;
+
+ /**
+ * Divider for showing item to be selected while scrolling
+ */
+ private final Drawable mSelectionDivider;
+
+ /**
+ * The height of the selection divider.
+ */
+ private final int mSelectionDividerHeight;
+
+ /**
* Reusable {@link Rect} instance.
*/
private final Rect mTempRect = new Rect();
@@ -335,9 +355,14 @@ public class NumberPicker extends LinearLayout {
private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
/**
+ * The duration of the animation for showing the input controls.
+ */
+ private final long mShowInputControlsAnimimationDuration;
+
+ /**
* Interface to listen for changes of the current value.
*/
- public interface OnValueChangedListener {
+ public interface OnValueChangeListener {
/**
* Called upon a change of the current value.
@@ -427,11 +452,19 @@ public class NumberPicker extends LinearLayout {
// process style attributes
TypedArray attributesArray = context.obtainStyledAttributes(attrs,
R.styleable.NumberPicker, defStyle, 0);
- int orientation = attributesArray.getInt(R.styleable.NumberPicker_orientation, VERTICAL);
- setOrientation(orientation);
mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0);
+ mFlingable = attributesArray.getBoolean(R.styleable.NumberPicker_flingable, true);
+ mSelectionDivider = attributesArray.getDrawable(R.styleable.NumberPicker_selectionDivider);
+ int defSelectionDividerHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT,
+ getResources().getDisplayMetrics());
+ mSelectionDividerHeight = attributesArray.getDimensionPixelSize(
+ R.styleable.NumberPicker_selectionDividerHeight, defSelectionDividerHeight);
attributesArray.recycle();
+ mShowInputControlsAnimimationDuration = getResources().getInteger(
+ R.integer.config_longAnimTime);
+
// By default Linearlayout that we extend is not drawn. This is
// its draw() method is not called but dispatchDraw() is called
// directly (see ViewGroup.drawChild()). However, this class uses
@@ -521,8 +554,6 @@ public class NumberPicker extends LinearLayout {
mShowInputControlsAnimator = new AnimatorSet();
mShowInputControlsAnimator.playTogether(fadeScroller, showIncrementButton,
showDecrementButton);
- mShowInputControlsAnimator.setDuration(getResources().getInteger(
- R.integer.config_longAnimTime));
mShowInputControlsAnimator.addListener(new AnimatorListenerAdapter() {
private boolean mCanceled = false;
@@ -547,23 +578,30 @@ public class NumberPicker extends LinearLayout {
// create the fling and adjust scrollers
mFlingScroller = new Scroller(getContext(), null, true);
- mAdjustScroller = new Scroller(getContext(), new OvershootInterpolator());
+ mAdjustScroller = new Scroller(getContext(), new DecelerateInterpolator(2.5f));
updateInputTextView();
updateIncrementAndDecrementButtonsVisibilityState();
+
+ if (mFlingable) {
+ // Start with shown selector wheel and hidden controls. When made
+ // visible hide the selector and fade-in the controls to suggest
+ // fling interaction.
+ setDrawSelectorWheel(true);
+ hideInputControls();
+ }
}
@Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- super.onWindowFocusChanged(hasWindowFocus);
- if (!hasWindowFocus) {
- removeAllCallbacks();
- }
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ // need to do this when we know our size
+ initializeScrollWheel();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (!isEnabled()) {
+ if (!isEnabled() || !mFlingable) {
return false;
}
switch (event.getActionMasked()) {
@@ -578,7 +616,7 @@ public class NumberPicker extends LinearLayout {
if (!scrollersFinished) {
mFlingScroller.forceFinished(true);
mAdjustScroller.forceFinished(true);
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
mBeginEditOnUpEvent = scrollersFinished;
mAdjustScrollerOnUpEvent = true;
@@ -597,7 +635,7 @@ public class NumberPicker extends LinearLayout {
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
setDrawSelectorWheel(true);
hideInputControls();
return true;
@@ -625,7 +663,7 @@ public class NumberPicker extends LinearLayout {
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
}
}
int deltaMoveY = (int) (currentMoveY - mLastMotionEventY);
@@ -636,7 +674,7 @@ public class NumberPicker extends LinearLayout {
case MotionEvent.ACTION_UP:
if (mBeginEditOnUpEvent) {
setDrawSelectorWheel(false);
- showInputControls();
+ showInputControls(mShowInputControlsAnimimationDuration);
mInputText.requestFocus();
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
@@ -649,7 +687,7 @@ public class NumberPicker extends LinearLayout {
int initialVelocity = (int) velocityTracker.getYVelocity();
if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
fling(initialVelocity);
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_FLING);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
} else {
if (mAdjustScrollerOnUpEvent) {
if (mFlingScroller.isFinished() && mAdjustScroller.isFinished()) {
@@ -731,18 +769,6 @@ public class NumberPicker extends LinearLayout {
@Override
public void scrollBy(int x, int y) {
int[] selectorIndices = getSelectorIndices();
- if (mInitialScrollOffset == Integer.MIN_VALUE) {
- int totalTextHeight = selectorIndices.length * mTextSize;
- int totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
- int textGapCount = selectorIndices.length - 1;
- int selectorTextGapHeight = totalTextGapHeight / textGapCount;
- // compensate for integer division loss of the components used to
- // calculate the text gap
- int integerDivisionLoss = (mTextSize + mBottom - mTop) % textGapCount;
- mInitialScrollOffset = mCurrentScrollOffset = mTextSize - integerDivisionLoss / 2;
- mSelectorElementHeight = mTextSize + selectorTextGapHeight;
- }
-
if (!mWrapSelectorWheel && y > 0
&& selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
mCurrentScrollOffset = mInitialScrollOffset;
@@ -782,8 +808,8 @@ public class NumberPicker extends LinearLayout {
*
* @param onValueChangedListener The listener.
*/
- public void setOnValueChangedListener(OnValueChangedListener onValueChangedListener) {
- mOnValueChangedListener = onValueChangedListener;
+ public void setOnValueChangedListener(OnValueChangeListener onValueChangedListener) {
+ mOnValueChangeListener = onValueChangedListener;
}
/**
@@ -813,6 +839,7 @@ public class NumberPicker extends LinearLayout {
}
mFormatter = formatter;
resetSelectorWheelIndices();
+ updateInputTextView();
}
/**
@@ -1021,6 +1048,17 @@ public class NumberPicker extends LinearLayout {
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ // make sure we show the controls only the very
+ // first time the user sees this widget
+ if (mFlingable) {
+ // animate a bit slower the very first time
+ showInputControls(mShowInputControlsAnimimationDuration * 2);
+ }
+ }
+
+ @Override
protected void onDetachedFromWindow() {
removeAllCallbacks();
}
@@ -1039,9 +1077,7 @@ public class NumberPicker extends LinearLayout {
// However, in View.draw(), the fading is applied after all the children
// have been drawn and we do not want this fading to be applied to the
// buttons which are currently showing in. Therefore, we draw our
- // children
- // after we have completed drawing ourselves.
-
+ // children after we have completed drawing ourselves.
super.draw(canvas);
// Draw our children if we are not showing the selector wheel of fading
@@ -1067,6 +1103,7 @@ public class NumberPicker extends LinearLayout {
float x = (mRight - mLeft) / 2;
float y = mCurrentScrollOffset;
+ // draw the selector wheel
int[] selectorIndices = getSelectorIndices();
for (int i = 0; i < selectorIndices.length; i++) {
int selectorIndex = selectorIndices[i];
@@ -1074,6 +1111,23 @@ public class NumberPicker extends LinearLayout {
canvas.drawText(scrollSelectorValue, x, y, mSelectorPaint);
y += mSelectorElementHeight;
}
+
+ // draw the selection dividers (only if scrolling and drawable specified)
+ if (mSelectionDivider != null) {
+ mSelectionDivider.setAlpha(mSelectorPaint.getAlpha());
+ // draw the top divider
+ int topOfTopDivider =
+ (getHeight() - mSelectorElementHeight - mSelectionDividerHeight) / 2;
+ int bottomOfTopDivider = topOfTopDivider + mSelectionDividerHeight;
+ mSelectionDivider.setBounds(0, topOfTopDivider, mRight, bottomOfTopDivider);
+ mSelectionDivider.draw(canvas);
+
+ // draw the bottom divider
+ int topOfBottomDivider = topOfTopDivider + mSelectorElementHeight;
+ int bottomOfBottomDivider = bottomOfTopDivider + mSelectorElementHeight;
+ mSelectionDivider.setBounds(0, topOfBottomDivider, mRight, bottomOfBottomDivider);
+ mSelectionDivider.draw(canvas);
+ }
}
/**
@@ -1139,26 +1193,46 @@ public class NumberPicker extends LinearLayout {
setVerticalFadingEdgeEnabled(drawSelectorWheel);
}
+ private void initializeScrollWheel() {
+ if (mInitialScrollOffset != Integer.MIN_VALUE) {
+ return;
+
+ }
+ int[] selectorIndices = getSelectorIndices();
+ int totalTextHeight = selectorIndices.length * mTextSize;
+ int totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
+ int textGapCount = selectorIndices.length - 1;
+ int selectorTextGapHeight = totalTextGapHeight / textGapCount;
+ // compensate for integer division loss of the components used to
+ // calculate the text gap
+ int integerDivisionLoss = (mTextSize + mBottom - mTop) % textGapCount;
+ mInitialScrollOffset = mCurrentScrollOffset = mTextSize - integerDivisionLoss / 2;
+ mSelectorElementHeight = mTextSize + selectorTextGapHeight;
+ updateInputTextView();
+ }
+
/**
* Callback invoked upon completion of a given <code>scroller</code>.
*/
private void onScrollerFinished(Scroller scroller) {
if (scroller == mFlingScroller) {
postAdjustScrollerCommand(0);
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
} else {
updateInputTextView();
- showInputControls();
+ showInputControls(mShowInputControlsAnimimationDuration);
}
}
/**
- * Notifies the scroll listener for the given <code>scrollState</code>
- * if the scroll state differs from the current scroll state.
+ * Handles transition to a given <code>scrollState</code>
*/
- private void tryNotifyScrollListener(int scrollState) {
- if (mOnScrollListener != null && mScrollState != scrollState) {
- mScrollState = scrollState;
+ private void onScrollStateChange(int scrollState) {
+ if (mScrollState == scrollState) {
+ return;
+ }
+ mScrollState = scrollState;
+ if (mOnScrollListener != null) {
mOnScrollListener.onScrollStateChange(this, scrollState);
}
}
@@ -1204,10 +1278,13 @@ public class NumberPicker extends LinearLayout {
/**
* Show the input controls by making them visible and animating the alpha
* property up/down arrows.
+ *
+ * @param animationDuration The duration of the animation.
*/
- private void showInputControls() {
+ private void showInputControls(long animationDuration) {
updateIncrementAndDecrementButtonsVisibilityState();
mInputText.setVisibility(VISIBLE);
+ mShowInputControlsAnimator.setDuration(animationDuration);
mShowInputControlsAnimator.start();
}
@@ -1332,9 +1409,9 @@ public class NumberPicker extends LinearLayout {
/**
* Updates the view of this NumberPicker. If displayValues were specified in
- * {@link #setRange}, the string corresponding to the index specified by the
- * current value will be returned. Otherwise, the formatter specified in
- * {@link #setFormatter} will be used to format the number.
+ * the string corresponding to the index specified by the current value will
+ * be returned. Otherwise, the formatter specified in {@link #setFormatter}
+ * will be used to format the number.
*/
private void updateInputTextView() {
/*
@@ -1355,8 +1432,8 @@ public class NumberPicker extends LinearLayout {
* NumberPicker.
*/
private void notifyChange(int previous, int current) {
- if (mOnValueChangedListener != null) {
- mOnValueChangedListener.onValueChange(this, previous, mValue);
+ if (mOnValueChangeListener != null) {
+ mOnValueChangeListener.onValueChange(this, previous, mValue);
}
}
@@ -1538,7 +1615,7 @@ public class NumberPicker extends LinearLayout {
mPreviousScrollerY = 0;
if (mInitialScrollOffset == mCurrentScrollOffset) {
updateInputTextView();
- showInputControls();
+ showInputControls(mShowInputControlsAnimimationDuration);
return;
}
// adjust to the closest value
@@ -1546,9 +1623,7 @@ public class NumberPicker extends LinearLayout {
if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
}
- float delayCoef = (float) Math.abs(deltaY) / (float) mTextSize;
- int duration = (int) (delayCoef * SELECTOR_ADJUSTMENT_DURATION_MILLIS);
- mAdjustScroller.startScroll(0, 0, 0, deltaY, duration);
+ mAdjustScroller.startScroll(0, 0, 0, deltaY, SELECTOR_ADJUSTMENT_DURATION_MILLIS);
invalidate();
}
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 79d6a81d2461..439e0cabe19f 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -28,7 +28,6 @@ import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.os.IBinder;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -1087,7 +1086,14 @@ public class PopupWindow {
p.width = Math.min(p.width, displayFrameWidth);
}
- p.y = Math.max(p.y, displayFrame.top);
+ if (onTop) {
+ int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
+ if (popupTop < 0) {
+ p.y += popupTop;
+ }
+ } else {
+ p.y = Math.max(p.y, displayFrame.top);
+ }
}
p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index c336ccbbd988..482ce56f83ae 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1277,18 +1277,6 @@ public class RemoteViews implements Parcelable, Filter {
/**
* Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
*
- * @param viewId The id of the view whose text should change
- * @param intent The intent of the service which will be
- * providing data to the RemoteViewsAdapter
- */
- public void setRemoteAdapter(int viewId, Intent intent) {
- // Do nothing. This method will be removed after all widgets have been updated to the
- // new API.
- }
-
- /**
- * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
- *
* @param appWidgetId The id of the app widget which contains the specified view
* @param viewId The id of the view whose text should change
* @param intent The intent of the service which will be
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index 16126aad1c94..e5a3de28ca62 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -42,7 +42,7 @@ public abstract class RemoteViewsService extends Service {
/**
* An interface for an adapter between a remote collection view (ListView, GridView, etc) and
* the underlying data for that view. The implementor is responsible for making a RemoteView
- * for each item in the data set.
+ * for each item in the data set. This interface is a thin wrapper around {@link Adapter}.
*
* @see android.widget.Adapter
* @see android.appwidget.AppWidgetManager
@@ -53,24 +53,72 @@ public abstract class RemoteViewsService extends Service {
* multiple RemoteViewAdapters depending on the intent passed.
*/
public void onCreate();
+
/**
* Called when notifyDataSetChanged() is triggered on the remote adapter. This allows a
* RemoteViewsFactory to respond to data changes by updating any internal references.
*
+ * Note: expensive tasks can be safely performed synchronously within this method. In the
+ * interim, the old data will be displayed within the widget.
+ *
* @see android.appwidget.AppWidgetManager#notifyAppWidgetViewDataChanged(int[], int)
*/
public void onDataSetChanged();
+
/**
* Called when the last RemoteViewsAdapter that is associated with this factory is
* unbound.
*/
public void onDestroy();
+ /**
+ * See {@link Adapter#getCount()}
+ *
+ * @return Count of items.
+ */
public int getCount();
+
+ /**
+ * See {@link Adapter#getView(int, android.view.View, android.view.ViewGroup)}.
+ *
+ * Note: expensive tasks can be safely performed synchronously within this method, and a
+ * loading view will be displayed in the interim. See {@link #getLoadingView()}.
+ *
+ * @param position The position of the item within the Factory's data set of the item whose
+ * view we want.
+ * @return A RemoteViews object corresponding to the data at the specified position.
+ */
public RemoteViews getViewAt(int position);
+
+ /**
+ * This allows for the use of a custom loading view which appears between the time that
+ * {@link #getViewAt(int)} is called and returns. If null is returned, a default loading
+ * view will be used.
+ *
+ * @return The RemoteViews representing the desired loading view.
+ */
public RemoteViews getLoadingView();
+
+ /**
+ * See {@link Adapter#getViewTypeCount()}.
+ *
+ * @return The number of types of Views that will be returned by this factory.
+ */
public int getViewTypeCount();
+
+ /**
+ * See {@link Adapter#getItemId(int)}.
+ *
+ * @param position The position of the item within the data set whose row id we want.
+ * @return The id of the item at the specified position.
+ */
public long getItemId(int position);
+
+ /**
+ * See {@link Adapter#hasStableIds()}.
+ *
+ * @return True if the same id always refers to the same object.
+ */
public boolean hasStableIds();
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 8558c70e40de..ce6da72a2c98 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -521,8 +521,10 @@ public class ScrollView extends FrameLayout {
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
- final float y = ev.getY();
- mIsBeingDragged = true;
+ mIsBeingDragged = getChildCount() != 0;
+ if (!mIsBeingDragged) {
+ return false;
+ }
/*
* If being flinged and user touches, stop the fling. isFinished
@@ -537,7 +539,7 @@ public class ScrollView extends FrameLayout {
}
// Remember where the motion event started
- mLastMotionY = y;
+ mLastMotionY = ev.getY();
mActivePointerId = ev.getPointerId(0);
break;
}
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 2c100773951c..22edf6d5f68f 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -347,6 +347,9 @@ public class StackView extends AdapterViewAnimator {
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
@android.view.RemotableViewMethod
public void showNext() {
@@ -362,6 +365,9 @@ public class StackView extends AdapterViewAnimator {
super.showNext();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
@android.view.RemotableViewMethod
public void showPrevious() {
@@ -474,6 +480,9 @@ public class StackView extends AdapterViewAnimator {
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
@@ -561,6 +570,9 @@ public class StackView extends AdapterViewAnimator {
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
@@ -939,6 +951,9 @@ public class StackView extends AdapterViewAnimator {
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void onRemoteAdapterConnected() {
super.onRemoteAdapterConnected();
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index 1ebe62294f79..2cfc0169a46e 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -78,15 +78,15 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
// URL color
private ColorStateList mUrlColor;
- // Cached column indexes, updated when the cursor changes.
- private int mText1Col;
- private int mText2Col;
- private int mText2UrlCol;
- private int mIconName1Col;
- private int mIconName2Col;
- private int mFlagsCol;
+ static final int INVALID_INDEX = -1;
- static final int NONE = -1;
+ // Cached column indexes, updated when the cursor changes.
+ private int mText1Col = INVALID_INDEX;
+ private int mText2Col = INVALID_INDEX;
+ private int mText2UrlCol = INVALID_INDEX;
+ private int mIconName1Col = INVALID_INDEX;
+ private int mIconName2Col = INVALID_INDEX;
+ private int mFlagsCol = INVALID_INDEX;
private final Runnable mStartSpinnerRunnable;
private final Runnable mStopSpinnerRunnable;
@@ -308,7 +308,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
ChildViewCache views = (ChildViewCache) view.getTag();
int flags = 0;
- if (mFlagsCol != -1) {
+ if (mFlagsCol != INVALID_INDEX) {
flags = cursor.getInt(mFlagsCol);
}
if (views.mText1 != null) {
@@ -391,7 +391,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
}
private Drawable getIcon1(Cursor cursor) {
- if (mIconName1Col < 0) {
+ if (mIconName1Col == INVALID_INDEX) {
return null;
}
String value = cursor.getString(mIconName1Col);
@@ -403,7 +403,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
}
private Drawable getIcon2(Cursor cursor) {
- if (mIconName2Col < 0) {
+ if (mIconName2Col == INVALID_INDEX) {
return null;
}
String value = cursor.getString(mIconName2Col);
@@ -687,7 +687,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
}
private static String getStringOrNull(Cursor cursor, int col) {
- if (col == NONE) {
+ if (col == INVALID_INDEX) {
return null;
}
try {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1895d793de13..d09e52f7ba8b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3426,8 +3426,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
setError(null, null);
} else {
Drawable dr = getContext().getResources().
- getDrawable(com.android.internal.R.drawable.
- indicator_input_error);
+ getDrawable(com.android.internal.R.drawable.indicator_input_error);
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
setError(error, dr);
@@ -3450,8 +3449,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mErrorWasChanged = true;
final Drawables dr = mDrawables;
if (dr != null) {
- setCompoundDrawables(dr.mDrawableLeft, dr.mDrawableTop,
- icon, dr.mDrawableBottom);
+ setCompoundDrawables(dr.mDrawableLeft, dr.mDrawableTop, icon, dr.mDrawableBottom);
} else {
setCompoundDrawables(null, null, icon, null);
}
@@ -3479,8 +3477,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mPopup == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
- final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
- null);
+ final TextView err = (TextView) inflater.inflate(
+ com.android.internal.R.layout.textview_hint, null);
final float scale = getResources().getDisplayMetrics().density;
mPopup = new ErrorPopup(err, (int) (200 * scale + 0.5f),
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 8f3442e4d6f5..2688b952a72a 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -20,61 +20,67 @@ import com.android.internal.R;
import android.annotation.Widget;
import android.content.Context;
+import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
-import android.widget.NumberPicker.OnValueChangedListener;
+import android.widget.NumberPicker.OnValueChangeListener;
import java.text.DateFormatSymbols;
import java.util.Calendar;
/**
- * A view for selecting the time of day, in either 24 hour or AM/PM mode.
- *
- * The hour, each minute digit, and AM/PM (if applicable) can be conrolled by
- * vertical spinners.
- *
- * The hour can be entered by keyboard input. Entering in two digit hours
- * can be accomplished by hitting two digits within a timeout of about a
- * second (e.g. '1' then '2' to select 12).
- *
- * The minutes can be entered by entering single digits.
- *
- * Under AM/PM mode, the user can hit 'a', 'A", 'p' or 'P' to pick.
- *
- * For a dialog using this view, see {@link android.app.TimePickerDialog}.
- *
- * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Time Picker
- * tutorial</a>.</p>
+ * A view for selecting the time of day, in either 24 hour or AM/PM mode. The
+ * hour, each minute digit, and AM/PM (if applicable) can be conrolled by
+ * vertical spinners. The hour can be entered by keyboard input. Entering in two
+ * digit hours can be accomplished by hitting two digits within a timeout of
+ * about a second (e.g. '1' then '2' to select 12). The minutes can be entered
+ * by entering single digits. Under AM/PM mode, the user can hit 'a', 'A", 'p'
+ * or 'P' to pick. For a dialog using this view, see
+ * {@link android.app.TimePickerDialog}.
+ *<p>
+ * See the <a href="{@docRoot}
+ * resources/tutorials/views/hello-timepicker.html">Time Picker tutorial</a>.
+ * </p>
*/
@Widget
public class TimePicker extends FrameLayout {
private static final boolean DEFAULT_ENABLED_STATE = true;
+ private static final int HOURS_IN_HALF_DAY = 12;
+
/**
- * A no-op callback used in the constructor to avoid null checks
- * later in the code.
+ * A no-op callback used in the constructor to avoid null checks later in
+ * the code.
*/
private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() {
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
}
};
-
+
// state
- private int mCurrentHour = 0; // 0-23
- private int mCurrentMinute = 0; // 0-59
- private Boolean mIs24HourView = false;
+ private boolean mIs24HourView;
+
private boolean mIsAm;
// ui components
private final NumberPicker mHourSpinner;
+
private final NumberPicker mMinuteSpinner;
+
private final NumberPicker mAmPmSpinner;
+
private final TextView mDivider;
+ // Note that the legacy implementation of the TimePicker is
+ // using a button for toggling between AM/PM while the new
+ // version uses a NumberPicker spinner. Therefore the code
+ // accommodates these two cases to be backwards compatible.
+ private final Button mAmPmButton;
+
private final String[] mAmPmStrings;
private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
@@ -98,74 +104,77 @@ public class TimePicker extends FrameLayout {
public TimePicker(Context context) {
this(context, null);
}
-
+
public TimePicker(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, R.attr.timePickerStyle);
}
public TimePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- LayoutInflater inflater =
- (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.time_picker,
- this, // we are the parent
- true);
+ // process style attributes
+ TypedArray attributesArray = context.obtainStyledAttributes(
+ attrs, R.styleable.TimePicker, defStyle, 0);
+ int layoutResourceId = attributesArray.getResourceId(
+ R.styleable.TimePicker_layout, R.layout.time_picker);
+ attributesArray.recycle();
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(layoutResourceId, this, true);
// hour
mHourSpinner = (NumberPicker) findViewById(R.id.hour);
- mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangedListener() {
+ mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
- mCurrentHour = newVal;
- if (!mIs24HourView) {
- // adjust from [1-12] to [0-11] internally, with the times
- // written "12:xx" being the start of the half-day
- if (mCurrentHour == 12) {
- mCurrentHour = 0;
- }
- if (!mIsAm) {
- // PM means 12 hours later than nominal
- mCurrentHour += 12;
+ if (!is24HourView()) {
+ int minValue = mHourSpinner.getMinValue();
+ int maxValue = mHourSpinner.getMaxValue();
+ // toggle AM/PM if the spinner has wrapped and not in 24
+ // format
+ if ((oldVal == maxValue && newVal == minValue)
+ || (oldVal == minValue && newVal == maxValue)) {
+ mIsAm = !mIsAm;
+ updateAmPmControl();
}
}
onTimeChanged();
}
});
- // divider
+ // divider (only for the new widget style)
mDivider = (TextView) findViewById(R.id.divider);
- mDivider.setText(R.string.time_picker_separator);
+ if (mDivider != null) {
+ mDivider.setText(R.string.time_picker_separator);
+ }
- // digits of minute
+ // minute
mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(59);
mMinuteSpinner.setOnLongPressUpdateInterval(100);
mMinuteSpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangedListener() {
+ mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
- mCurrentMinute = newVal;
- onTimeChanged();
- }
- });
-
- // am/pm
- mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm);
- mAmPmSpinner.setOnValueChangedListener(new OnValueChangedListener() {
- public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
- picker.requestFocus();
- if (mIsAm) {
- // Currently AM switching to PM
- if (mCurrentHour < 12) {
- mCurrentHour += 12;
+ int minValue = mMinuteSpinner.getMinValue();
+ int maxValue = mMinuteSpinner.getMaxValue();
+ if (oldVal == maxValue && newVal == minValue) {
+ int currentHour = mHourSpinner.getValue();
+ // toggle AM/PM if the spinner is about to wrap
+ if (!is24HourView() && currentHour == mHourSpinner.getMaxValue()) {
+ mIsAm = !mIsAm;
+ updateAmPmControl();
}
- } else {
- // Currently PM switching to AM
- if (mCurrentHour >= 12) {
- mCurrentHour -= 12;
+ mHourSpinner.setValue(currentHour + 1);
+ } else if (oldVal == minValue && newVal == maxValue) {
+ int currentHour = mHourSpinner.getValue();
+ // toggle AM/PM if the spinner is about to wrap
+ if (!is24HourView() && currentHour == mHourSpinner.getMinValue()) {
+ mIsAm = !mIsAm;
+ updateAmPmControl();
}
+ mHourSpinner.setValue(currentHour - 1);
}
- mIsAm = !mIsAm;
onTimeChanged();
}
});
@@ -173,17 +182,44 @@ public class TimePicker extends FrameLayout {
/* Get the localized am/pm strings and use them in the spinner */
mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
- // now that the hour/minute picker objects have been initialized, set
- // the hour range properly based on the 12/24 hour display mode.
- configurePickerRanges();
+ // am/pm
+ View amPmView = findViewById(R.id.amPm);
+ if (amPmView instanceof Button) {
+ mAmPmSpinner = null;
+ mAmPmButton = (Button) amPmView;
+ mAmPmButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View button) {
+ button.requestFocus();
+ mIsAm = !mIsAm;
+ updateAmPmControl();
+ }
+ });
+ } else {
+ mAmPmButton = null;
+ mAmPmSpinner = (NumberPicker) amPmView;
+ mAmPmSpinner.setMinValue(0);
+ mAmPmSpinner.setMaxValue(1);
+ mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+ mAmPmSpinner.setOnValueChangedListener(new OnValueChangeListener() {
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ picker.requestFocus();
+ mIsAm = !mIsAm;
+ updateAmPmControl();
+ }
+ });
+ }
+
+ // update controls to initial state
+ updateHourControl();
+ updateAmPmControl();
// initialize to current time
- Calendar cal = Calendar.getInstance();
+ Calendar calendar = Calendar.getInstance();
setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
- // by default we're not in 24 hour mode
- setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));
- setCurrentMinute(cal.get(Calendar.MINUTE));
+ // set to current time
+ setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
+ setCurrentMinute(calendar.get(Calendar.MINUTE));
if (!isEnabled()) {
setEnabled(false);
@@ -197,9 +233,15 @@ public class TimePicker extends FrameLayout {
}
super.setEnabled(enabled);
mMinuteSpinner.setEnabled(enabled);
- mDivider.setEnabled(enabled);
+ if (mDivider != null) {
+ mDivider.setEnabled(enabled);
+ }
mHourSpinner.setEnabled(enabled);
- mAmPmSpinner.setEnabled(enabled);
+ if (mAmPmSpinner != null) {
+ mAmPmSpinner.setEnabled(enabled);
+ } else {
+ mAmPmButton.setEnabled(enabled);
+ }
mIsEnabled = enabled;
}
@@ -214,6 +256,7 @@ public class TimePicker extends FrameLayout {
private static class SavedState extends BaseSavedState {
private final int mHour;
+
private final int mMinute;
private SavedState(Parcelable superState, int hour, int minute) {
@@ -221,7 +264,7 @@ public class TimePicker extends FrameLayout {
mHour = hour;
mMinute = minute;
}
-
+
private SavedState(Parcel in) {
super(in);
mHour = in.readInt();
@@ -244,8 +287,7 @@ public class TimePicker extends FrameLayout {
}
@SuppressWarnings("unused")
- public static final Parcelable.Creator<SavedState> CREATOR
- = new Creator<SavedState>() {
+ public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@@ -259,7 +301,7 @@ public class TimePicker extends FrameLayout {
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
- return new SavedState(superState, mCurrentHour, mCurrentMinute);
+ return new SavedState(superState, getCurrentHour(), getCurrentMinute());
}
@Override
@@ -272,6 +314,7 @@ public class TimePicker extends FrameLayout {
/**
* Set the callback that indicates the time has been adjusted by the user.
+ *
* @param onTimeChangedListener the callback, should not be null.
*/
public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
@@ -279,30 +322,58 @@ public class TimePicker extends FrameLayout {
}
/**
- * @return The current hour (0-23).
+ * @return The current hour in the range (0-23).
*/
public Integer getCurrentHour() {
- return mCurrentHour;
+ int currentHour = mHourSpinner.getValue();
+ if (is24HourView() || mIsAm) {
+ return currentHour;
+ } else {
+ return (currentHour == HOURS_IN_HALF_DAY) ? 0 : currentHour + HOURS_IN_HALF_DAY;
+ }
}
/**
* Set the current hour.
*/
public void setCurrentHour(Integer currentHour) {
- this.mCurrentHour = currentHour;
- updateHourDisplay();
+ // why was Integer used in the first place?
+ if (currentHour == null || currentHour == getCurrentHour()) {
+ return;
+ }
+ if (!is24HourView()) {
+ // convert [0,23] ordinal to wall clock display
+ if (currentHour > HOURS_IN_HALF_DAY) {
+ currentHour -= HOURS_IN_HALF_DAY;
+ mIsAm = false;
+ } else {
+ if (currentHour == 0) {
+ currentHour = HOURS_IN_HALF_DAY;
+ }
+ mIsAm = true;
+ }
+ updateAmPmControl();
+ }
+ mHourSpinner.setValue(currentHour);
+ onTimeChanged();
}
/**
* Set whether in 24 hour or AM/PM mode.
+ *
* @param is24HourView True = 24 hour mode. False = AM/PM.
*/
public void setIs24HourView(Boolean is24HourView) {
- if (mIs24HourView != is24HourView) {
- mIs24HourView = is24HourView;
- configurePickerRanges();
- updateHourDisplay();
+ if (mIs24HourView == is24HourView) {
+ return;
}
+ mIs24HourView = is24HourView;
+ // cache the current hour since spinner range changes
+ int currentHour = getCurrentHour();
+ updateHourControl();
+ // set value after spinner range is updated
+ setCurrentHour(currentHour);
+ updateAmPmControl();
}
/**
@@ -311,20 +382,23 @@ public class TimePicker extends FrameLayout {
public boolean is24HourView() {
return mIs24HourView;
}
-
+
/**
* @return The current minute.
*/
public Integer getCurrentMinute() {
- return mCurrentMinute;
+ return mMinuteSpinner.getValue();
}
/**
* Set the current minute (0-59).
*/
public void setCurrentMinute(Integer currentMinute) {
- this.mCurrentMinute = currentMinute;
- updateMinuteDisplay();
+ if (currentMinute == getCurrentMinute()) {
+ return;
+ }
+ mMinuteSpinner.setValue(currentMinute);
+ onTimeChanged();
}
@Override
@@ -332,39 +406,34 @@ public class TimePicker extends FrameLayout {
return mHourSpinner.getBaseline();
}
- /**
- * Set the state of the spinners appropriate to the current hour.
- */
- private void updateHourDisplay() {
- int currentHour = mCurrentHour;
- if (!mIs24HourView) {
- // convert [0,23] ordinal to wall clock display
- if (currentHour > 12) {
- currentHour -= 12;
- } else if (currentHour == 0) {
- currentHour = 12;
- }
- }
- mHourSpinner.setValue(currentHour);
- mIsAm = mCurrentHour < 12;
- mAmPmSpinner.setValue(mIsAm ? Calendar.AM : Calendar.PM);
- onTimeChanged();
- }
-
- private void configurePickerRanges() {
- if (mIs24HourView) {
+ private void updateHourControl() {
+ if (is24HourView()) {
mHourSpinner.setMinValue(0);
mHourSpinner.setMaxValue(23);
mHourSpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- mAmPmSpinner.setVisibility(View.GONE);
} else {
mHourSpinner.setMinValue(1);
mHourSpinner.setMaxValue(12);
mHourSpinner.setFormatter(null);
- mAmPmSpinner.setVisibility(View.VISIBLE);
- mAmPmSpinner.setMinValue(0);
- mAmPmSpinner.setMaxValue(1);
- mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+ }
+ }
+
+ private void updateAmPmControl() {
+ if (is24HourView()) {
+ if (mAmPmSpinner != null) {
+ mAmPmSpinner.setVisibility(View.GONE);
+ } else {
+ mAmPmButton.setVisibility(View.GONE);
+ }
+ } else {
+ int index = mIsAm ? Calendar.AM : Calendar.PM;
+ if (mAmPmSpinner != null) {
+ mAmPmSpinner.setValue(index);
+ mAmPmSpinner.setVisibility(View.VISIBLE);
+ } else {
+ mAmPmButton.setText(mAmPmStrings[index]);
+ mAmPmButton.setVisibility(View.VISIBLE);
+ }
}
}
@@ -373,12 +442,4 @@ public class TimePicker extends FrameLayout {
mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute());
}
}
-
- /**
- * Set the state of the spinners appropriate to the current minute.
- */
- private void updateMinuteDisplay() {
- mMinuteSpinner.setValue(mCurrentMinute);
- onTimeChanged();
- }
}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index a8f9f62222c2..6a7db1f0b83c 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -33,8 +33,6 @@ import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
-import java.lang.ref.WeakReference;
-
/**
* A toast is a view containing a quick little message for the user. The toast class
* helps you create and show those.
@@ -72,11 +70,6 @@ public class Toast {
final Context mContext;
final TN mTN;
int mDuration;
- int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
- int mX, mY;
- float mHorizontalMargin;
- float mVerticalMargin;
- View mView;
View mNextView;
/**
@@ -88,8 +81,8 @@ public class Toast {
*/
public Toast(Context context) {
mContext = context;
- mTN = new TN(this);
- mY = context.getResources().getDimensionPixelSize(
+ mTN = new TN();
+ mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
}
@@ -103,9 +96,11 @@ public class Toast {
INotificationManager service = getService();
String pkg = mContext.getPackageName();
+ TN tn = mTN;
+ tn.mNextView = mNextView;
try {
- service.enqueueToast(pkg, mTN, mDuration);
+ service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// Empty
}
@@ -165,22 +160,22 @@ public class Toast {
* notification
*/
public void setMargin(float horizontalMargin, float verticalMargin) {
- mHorizontalMargin = horizontalMargin;
- mVerticalMargin = verticalMargin;
+ mTN.mHorizontalMargin = horizontalMargin;
+ mTN.mVerticalMargin = verticalMargin;
}
/**
* Return the horizontal margin.
*/
public float getHorizontalMargin() {
- return mHorizontalMargin;
+ return mTN.mHorizontalMargin;
}
/**
* Return the vertical margin.
*/
public float getVerticalMargin() {
- return mVerticalMargin;
+ return mTN.mVerticalMargin;
}
/**
@@ -189,9 +184,9 @@ public class Toast {
* @see #getGravity
*/
public void setGravity(int gravity, int xOffset, int yOffset) {
- mGravity = gravity;
- mX = xOffset;
- mY = yOffset;
+ mTN.mGravity = gravity;
+ mTN.mX = xOffset;
+ mTN.mY = yOffset;
}
/**
@@ -200,21 +195,21 @@ public class Toast {
* @see #getGravity
*/
public int getGravity() {
- return mGravity;
+ return mTN.mGravity;
}
/**
* Return the X offset in pixels to apply to the gravity's location.
*/
public int getXOffset() {
- return mX;
+ return mTN.mX;
}
/**
* Return the Y offset in pixels to apply to the gravity's location.
*/
public int getYOffset() {
- return mY;
+ return mTN.mY;
}
/**
@@ -281,21 +276,6 @@ public class Toast {
tv.setText(s);
}
- private void trySendAccessibilityEvent() {
- AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
- if (!accessibilityManager.isEnabled()) {
- return;
- }
- // treat toasts as notifications since they are used to
- // announce a transient piece of information to the user
- AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
- event.setClassName(getClass().getName());
- event.setPackageName(mContext.getPackageName());
- mView.dispatchPopulateAccessibilityEvent(event);
- accessibilityManager.sendAccessibilityEvent(event);
- }
-
// =======================================================================================
// All the gunk below is the interaction with the Notification Service, which handles
// the proper ordering of these system-wide.
@@ -312,8 +292,6 @@ public class Toast {
}
private static class TN extends ITransientNotification.Stub {
- final Handler mHandler = new Handler();
-
final Runnable mShow = new Runnable() {
public void run() {
handleShow();
@@ -327,12 +305,20 @@ public class Toast {
};
private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
- private final WeakReference<Toast> mToast;
+ final Handler mHandler = new Handler();
+
+ int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+ int mX, mY;
+ float mHorizontalMargin;
+ float mVerticalMargin;
+
+
+ View mView;
+ View mNextView;
WindowManagerImpl mWM;
- TN(Toast toast) {
- mToast = new WeakReference<Toast>(toast);
+ TN() {
// XXX This should be changed to use a Dialog, with a Theme.Toast
// defined that sets up the layout params appropriately.
final WindowManager.LayoutParams params = mParams;
@@ -364,53 +350,64 @@ public class Toast {
}
public void handleShow() {
- final Toast toast = mToast.get();
- if (toast != null) {
- if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + toast.mView
- + " mNextView=" + toast.mNextView);
- if (toast.mView != toast.mNextView) {
- // remove the old view if necessary
- handleHide();
- toast.mView = toast.mNextView;
- mWM = WindowManagerImpl.getDefault();
- final int gravity = toast.mGravity;
- mParams.gravity = gravity;
- if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
- mParams.horizontalWeight = 1.0f;
- }
- if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
- mParams.verticalWeight = 1.0f;
- }
- mParams.x = toast.mX;
- mParams.y = toast.mY;
- mParams.verticalMargin = toast.mVerticalMargin;
- mParams.horizontalMargin = toast.mHorizontalMargin;
- if (toast.mView.getParent() != null) {
- if (localLOGV) Log.v(TAG, "REMOVE! " + toast.mView + " in " + this);
- mWM.removeView(toast.mView);
- }
- if (localLOGV) Log.v(TAG, "ADD! " + toast.mView + " in " + this);
- mWM.addView(toast.mView, mParams);
- toast.trySendAccessibilityEvent();
+ if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
+ + " mNextView=" + mNextView);
+ if (mView != mNextView) {
+ // remove the old view if necessary
+ handleHide();
+ mView = mNextView;
+ mWM = WindowManagerImpl.getDefault();
+ final int gravity = mGravity;
+ mParams.gravity = gravity;
+ if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
+ mParams.horizontalWeight = 1.0f;
+ }
+ if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
+ mParams.verticalWeight = 1.0f;
+ }
+ mParams.x = mX;
+ mParams.y = mY;
+ mParams.verticalMargin = mVerticalMargin;
+ mParams.horizontalMargin = mHorizontalMargin;
+ if (mView.getParent() != null) {
+ if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
+ mWM.removeView(mView);
}
+ if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
+ mWM.addView(mView, mParams);
+ trySendAccessibilityEvent();
}
}
+ private void trySendAccessibilityEvent() {
+ AccessibilityManager accessibilityManager =
+ AccessibilityManager.getInstance(mView.getContext());
+ if (!accessibilityManager.isEnabled()) {
+ return;
+ }
+ // treat toasts as notifications since they are used to
+ // announce a transient piece of information to the user
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+ event.setClassName(getClass().getName());
+ event.setPackageName(mView.getContext().getPackageName());
+ mView.dispatchPopulateAccessibilityEvent(event);
+ accessibilityManager.sendAccessibilityEvent(event);
+ }
+
public void handleHide() {
- final Toast toast = mToast.get();
- if (toast != null) {
- if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + toast.mView);
- if (toast.mView != null) {
- // note: checking parent() just to make sure the view has
- // been added... i have seen cases where we get here when
- // the view isn't yet added, so let's try not to crash.
- if (toast.mView.getParent() != null) {
- if (localLOGV) Log.v(TAG, "REMOVE! " + toast.mView + " in " + this);
- mWM.removeView(toast.mView);
- }
-
- toast.mView = null;
+ if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
+ if (mView != null) {
+ // note: checking parent() just to make sure the view has
+ // been added... i have seen cases where we get here when
+ // the view isn't yet added, so let's try not to crash.
+ if (mView.getParent() != null) {
+ if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
+ mWM.removeView(mView);
}
+
+ mView = null;
+ mNextView = null;
}
}
}
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 6a1beb422f36..e992e7c40ab1 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -142,10 +142,6 @@ public class EditableInputConnection extends BaseInputConnection {
boolean success = super.commitText(text, newCursorPosition);
CharSequence errorAfter = mTextView.getError();
- if (errorAfter != null && errorBefore == errorAfter) {
- mTextView.setError(null, null);
- }
-
return success;
}
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f023e9469578..342b8840ed51 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -568,6 +568,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
+ char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
char extraOptsBuf[PROPERTY_VALUE_MAX];
char* stackTraceFile = NULL;
bool checkJni = false;
@@ -659,6 +660,13 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
opt.optionString = heapsizeOptsBuf;
mOptions.add(opt);
+ strcpy(heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
+ property_get("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf+20, "");
+ if (heapgrowthlimitOptsBuf[20] != '\0') {
+ opt.optionString = heapgrowthlimitOptsBuf;
+ mOptions.add(opt);
+ }
+
/*
* Enable or disable dexopt features, such as bytecode verification and
* calculation of register maps for precise GC.
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index c43b5ce14eb1..24452292ab62 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -154,6 +154,16 @@ static void Region_scale(JNIEnv* env, jobject region, jfloat scale, jobject dst)
scale_rgn(rgn, *rgn, scale);
}
+static jstring Region_toString(JNIEnv* env, jobject clazz, SkRegion* region) {
+ char* str = region->toString();
+ if (str == NULL) {
+ return NULL;
+ }
+ jstring result = env->NewStringUTF(str);
+ free(str);
+ return result;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////
static SkRegion* Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
@@ -262,6 +272,7 @@ static JNINativeMethod gRegionMethods[] = {
{ "quickReject", "(Landroid/graphics/Region;)Z", (void*)Region_quickRejectRgn },
{ "scale", "(FLandroid/graphics/Region;)V", (void*)Region_scale },
{ "translate", "(IILandroid/graphics/Region;)V", (void*)Region_translate },
+ { "nativeToString", "(I)Ljava/lang/String;", (void*)Region_toString },
// parceling methods
{ "nativeCreateFromParcel", "(Landroid/os/Parcel;)I", (void*)Region_createFromParcel },
{ "nativeWriteToParcel", "(ILandroid/os/Parcel;)Z", (void*)Region_writeToParcel },
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
index 9222e1a7b61c..3364703d49e9 100644
--- a/core/jni/android_bluetooth_common.h
+++ b/core/jni/android_bluetooth_common.h
@@ -38,6 +38,7 @@ namespace android {
#ifdef HAVE_BLUETOOTH
#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
#define BLUEZ_DBUS_BASE_IFC "org.bluez"
+#define BLUEZ_ERROR_IFC "org.bluez.Error"
// It would be nicer to retrieve this from bluez using GetDefaultAdapter,
// but this is only possible when the adapter is up (and hcid is running).
@@ -171,6 +172,30 @@ void get_bdaddr_as_string(const bdaddr_t *ba, char *str);
bool debug_no_encrypt();
+
+// Result codes from Bluez DBus calls
+#define BOND_RESULT_ERROR -1
+#define BOND_RESULT_SUCCESS 0
+#define BOND_RESULT_AUTH_FAILED 1
+#define BOND_RESULT_AUTH_REJECTED 2
+#define BOND_RESULT_AUTH_CANCELED 3
+#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
+#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
+#define BOND_RESULT_AUTH_TIMEOUT 6
+#define BOND_RESULT_REPEATED_ATTEMPTS 7
+
+#define PAN_DISCONNECT_FAILED_NOT_CONNECTED 1000
+#define PAN_CONNECT_FAILED_ALREADY_CONNECTED 1001
+#define PAN_CONNECT_FAILED_ATTEMPT_FAILED 1002
+#define PAN_OPERATION_GENERIC_FAILURE 1003
+#define PAN_OPERATION_SUCCESS 1004
+
+#define INPUT_DISCONNECT_FAILED_NOT_CONNECTED 5000
+#define INPUT_CONNECT_FAILED_ALREADY_CONNECTED 5001
+#define INPUT_CONNECT_FAILED_ATTEMPT_FAILED 5002
+#define INPUT_OPERATION_GENERIC_FAILURE 5003
+#define INPUT_OPERATION_SUCCESS 5004
+
#endif
} /* namespace android */
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index b0ba6955c3b6..fd12c2d736f8 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -134,11 +134,11 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
- "(Ljava/lang/String;Z)V");
+ "(Ljava/lang/String;I)V");
method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
- "(Ljava/lang/String;Z)V");
+ "(Ljava/lang/String;I)V");
method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
"(Ljava/lang/String;I)V");
@@ -1227,16 +1227,6 @@ success:
#ifdef HAVE_BLUETOOTH
-//TODO: Unify result codes in a header
-#define BOND_RESULT_ERROR -1000
-#define BOND_RESULT_SUCCESS 0
-#define BOND_RESULT_AUTH_FAILED 1
-#define BOND_RESULT_AUTH_REJECTED 2
-#define BOND_RESULT_AUTH_CANCELED 3
-#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
-#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
-#define BOND_RESULT_AUTH_TIMEOUT 6
-#define BOND_RESULT_REPEATED_ATTEMPTS 7
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
LOGV(__FUNCTION__);
@@ -1406,11 +1396,25 @@ void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
JNIEnv *env;
nat->vm->GetEnv((void**)&env, nat->envVer);
- bool result = JNI_TRUE;
+ jint result = INPUT_OPERATION_SUCCESS;
if (dbus_set_error_from_message(&err, msg)) {
+ if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+ result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
+ result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+ // TODO():This is flaky, need to change Bluez to add new error codes
+ if (!strcmp(err.message, "Transport endpoint is not connected")) {
+ result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
+ } else {
+ result = INPUT_OPERATION_GENERIC_FAILURE;
+ }
+ } else {
+ result = INPUT_OPERATION_GENERIC_FAILURE;
+ }
LOG_AND_FREE_DBUS_ERROR(&err);
- result = JNI_FALSE;
}
+
LOGV("... Device Path = %s, result = %d", path, result);
jstring jPath = env->NewStringUTF(path);
env->CallVoidMethod(nat->me,
@@ -1431,11 +1435,25 @@ void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
JNIEnv *env;
nat->vm->GetEnv((void**)&env, nat->envVer);
- bool result = JNI_TRUE;
+ jint result = PAN_OPERATION_SUCCESS;
if (dbus_set_error_from_message(&err, msg)) {
+ if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+ result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+ // TODO():This is flaky, need to change Bluez to add new error codes
+ if (!strcmp(err.message, "Device already connected")) {
+ result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
+ } else if (!strcmp(err.message, "Device not connected")) {
+ result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
+ } else {
+ result = PAN_OPERATION_GENERIC_FAILURE;
+ }
+ } else {
+ result = PAN_OPERATION_GENERIC_FAILURE;
+ }
LOG_AND_FREE_DBUS_ERROR(&err);
- result = JNI_FALSE;
}
+
LOGV("... Pan Device Path = %s, result = %d", path, result);
jstring jPath = env->NewStringUTF(path);
env->CallVoidMethod(nat->me,
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index ac491ea25a5e..bfd2b58e8b86 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -299,6 +299,17 @@ static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
renderer->drawRect(left, top, right, bottom, paint);
}
+static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
+ jfloat rx, jfloat ry, SkPaint* paint) {
+ renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
+}
+
+static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jfloat x, jfloat y, jfloat radius, SkPaint* paint) {
+ renderer->drawCircle(x, y, radius, paint);
+}
+
static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
SkRegion::Iterator it(*region);
@@ -570,6 +581,8 @@ static JNINativeMethod gMethods[] = {
{ "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
{ "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
{ "nDrawRects", "(III)V", (void*) android_view_GLES20Canvas_drawRects },
+ { "nDrawRoundRect", "(IFFFFFFI)V", (void*) android_view_GLES20Canvas_drawRoundRect },
+ { "nDrawCircle", "(IFFFI)V", (void*) android_view_GLES20Canvas_drawCircle },
{ "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
{ "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
diff --git a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
new file mode 100644
index 000000000000..7719df8a4e83
--- /dev/null
+++ b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-hdpi/vpn_connected.png
index 65fc6db787bf..65fc6db787bf 100644
--- a/packages/VpnServices/res/drawable/vpn_connected.png
+++ b/core/res/res/drawable-hdpi/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-hdpi/vpn_disconnected.png
index 2440c6909ef5..2440c6909ef5 100644
--- a/packages/VpnServices/res/drawable/vpn_disconnected.png
+++ b/core/res/res/drawable-hdpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/vpn_connected.png b/core/res/res/drawable-ldpi/vpn_connected.png
new file mode 100644
index 000000000000..65fc6db787bf
--- /dev/null
+++ b/core/res/res/drawable-ldpi/vpn_connected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/vpn_disconnected.png b/core/res/res/drawable-ldpi/vpn_disconnected.png
new file mode 100644
index 000000000000..2440c6909ef5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
new file mode 100644
index 000000000000..a933d9a6c939
--- /dev/null
+++ b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
new file mode 100644
index 000000000000..137923b4a224
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
new file mode 100644
index 000000000000..62b1debdccec
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
new file mode 100644
index 000000000000..ab30a7728bea
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
new file mode 100644
index 000000000000..9274bc720c2f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
new file mode 100644
index 000000000000..e46155e07064
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/vpn_connected.png b/core/res/res/drawable-mdpi/vpn_connected.png
new file mode 100644
index 000000000000..65fc6db787bf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/vpn_connected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/vpn_disconnected.png b/core/res/res/drawable-mdpi/vpn_disconnected.png
new file mode 100644
index 000000000000..2440c6909ef5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png
new file mode 100644
index 000000000000..0fbdbfa061fb
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
new file mode 100644
index 000000000000..ae9745374304
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
new file mode 100644
index 000000000000..4127d1ee7274
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
new file mode 100644
index 000000000000..525ab8a40f19
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
new file mode 100644
index 000000000000..eb05820ded0a
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
new file mode 100644
index 000000000000..416b2c7295b0
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable/lockscreen_password_field_dark.xml b/core/res/res/drawable/lockscreen_password_field_dark.xml
new file mode 100644
index 000000000000..92ceb79fc7f0
--- /dev/null
+++ b/core/res/res/drawable/lockscreen_password_field_dark.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
+ <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_bg_activated_holo_dark" />
+ <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_bg_focused_holo_dark" />
+ <item android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
+ <item android:state_focused="true" android:drawable="@drawable/textfield_bg_disabled_focused_holo_dark" />
+ <item android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
+</selector>
+
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
index 4bc729248c3f..5ea43dc4ad87 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
@@ -20,76 +20,88 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="horizontal"
- >
+ android:orientation="vertical">
- <!-- left side: status -->
- <RelativeLayout
- android:layout_height="match_parent"
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
android:layout_weight="1"
- android:layout_width="0dip">
+ />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <!-- left side: status -->
<include layout="@layout/keyguard_screen_status_land"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="102dip"
- android:layout_marginTop="320dip"
- android:layout_alignParentTop="true"
+ android:paddingTop="50dip"
+ android:layout_centerVertical="true"
android:layout_alignParentLeft="true"/>
- </RelativeLayout>
+ <!-- right side: password -->
+ <LinearLayout
+ android:layout_width="330dip"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:layout_marginRight="155dip">
- <!-- right side: password -->
- <LinearLayout
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_weight="1"
- android:gravity="center">
+ <!-- Password entry field -->
+ <EditText android:id="@+id/passwordEntry"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:singleLine="true"
+ android:textStyle="normal"
+ android:inputType="textPassword"
+ android:gravity="center"
+ android:textSize="24sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:background="@drawable/lockscreen_password_field_dark"
+ android:textColor="#ffffffff"
+ />
- <!-- Password entry field -->
- <EditText android:id="@+id/passwordEntry"
- android:layout_height="wrap_content"
- android:layout_width="330dip"
- android:singleLine="true"
- android:textStyle="normal"
- android:inputType="textPassword"
- android:gravity="center"
- android:layout_gravity="center"
- android:textSize="24sp"
- android:layout_marginTop="120dip"
- android:layout_marginBottom="5dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:background="@drawable/password_field_default"
- android:textColor="#ffffffff"
+ <!-- Numeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+ android:layout_width="330dip"
+ android:layout_height="330dip"
+ android:background="#00000000"
+ android:layout_marginTop="5dip"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ android:visibility="gone"
/>
+ </LinearLayout>
- <!-- Numeric keyboard -->
- <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
- android:layout_width="330dip"
- android:layout_height="260dip"
- android:background="#00000000"
- android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
- />
- <!-- Alphanumeric keyboard -->
- <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
- android:layout_width="450dip"
- android:layout_height="230dip"
- android:background="#00000000"
- android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
- />
+ </RelativeLayout>
- <!-- emergency call button -->
- <Button
- android:id="@+id/emergencyCall"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableLeft="@drawable/ic_emergency"
- android:drawablePadding="8dip"
- android:text="@string/lockscreen_emergency_call"
- android:visibility="gone"
- style="@style/Widget.Button.Transparent"
- />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ />
+
+ <!-- Alphanumeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#00000000"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ android:visibility="gone"
+ />
+
+ <!-- emergency call button NOT CURRENTLY USED -->
+ <Button
+ android:id="@+id/emergencyCall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:text="@string/lockscreen_emergency_call"
+ android:visibility="gone"
+ style="@style/Widget.Button.Transparent"
+ />
- </LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
index e63fb9bffd3a..8a059f5c1ba0 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
@@ -56,7 +56,7 @@
android:layout_marginTop="120dip"
android:layout_marginBottom="5dip"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:background="@drawable/password_field_default"
+ android:background="@drawable/lockscreen_password_field_dark"
android:textColor="#ffffffff"
/>
@@ -69,7 +69,7 @@
/>
<!-- Alphanumeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
- android:layout_width="450dip"
+ android:layout_width="match_parent"
android:layout_height="230dip"
android:background="#00000000"
android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index e9663b18080d..1649466261c6 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -40,10 +40,10 @@
<!-- Month -->
<NumberPicker
android:id="@+id/month"
- android:layout_width="48dip"
+ android:layout_width="80dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="1dip"
+ android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -51,10 +51,10 @@
<!-- Day -->
<NumberPicker
android:id="@+id/day"
- android:layout_width="48dip"
+ android:layout_width="80dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="1dip"
+ android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -62,10 +62,10 @@
<!-- Year -->
<NumberPicker
android:id="@+id/year"
- android:layout_width="48dip"
+ android:layout_width="95dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="1dip"
+ android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -81,6 +81,7 @@
android:layout_weight="1"
android:focusable="true"
android:focusableInTouchMode="true"
+ android:visibility="gone"
/>
</LinearLayout>
diff --git a/core/res/res/layout/date_picker_holo.xml b/core/res/res/layout/date_picker_holo.xml
new file mode 100644
index 000000000000..026cbfb8bca1
--- /dev/null
+++ b/core/res/res/layout/date_picker_holo.xml
@@ -0,0 +1,86 @@
+<?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.
+*/
+-->
+
+<!-- Layout of date picker-->
+
+<!-- Warning: everything within the "pickers" layout is removed and re-ordered
+ depending on the date format selected by the user.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center">
+
+ <LinearLayout android:id="@+id/pickers"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="22dip"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:gravity="center">
+
+ <!-- Month -->
+ <NumberPicker
+ android:id="@+id/month"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- Day -->
+ <NumberPicker
+ android:id="@+id/day"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- Year -->
+ <NumberPicker
+ android:id="@+id/year"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ </LinearLayout>
+
+ <!-- calendar view -->
+ <CalendarView
+ android:id="@+id/calendar_view"
+ android:layout_width="245dip"
+ android:layout_height="280dip"
+ android:layout_marginLeft="22dip"
+ android:layout_weight="1"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index 382b2f670c0d..df46db47041c 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -28,42 +28,33 @@
<!-- hour -->
<NumberPicker
android:id="@+id/hour"
- android:layout_width="48dip"
+ android:layout_width="70dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="20dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
- <!-- divider -->
- <TextView
- android:id="@+id/divider"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- />
-
<!-- minute -->
<NumberPicker
android:id="@+id/minute"
- android:layout_width="48dip"
+ android:layout_width="70dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="5dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
<!-- AM / PM -->
- <NumberPicker
+ <Button
android:id="@+id/amPm"
- android:layout_width="48dip"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
- android:focusable="true"
- android:focusableInTouchMode="true"
+ android:layout_marginTop="43dip"
+ android:layout_marginLeft="5dip"
+ android:paddingLeft="20dip"
+ android:paddingRight="20dip"
+ style="?android:attr/textAppearanceLargeInverse"
+ android:textColor="@android:color/primary_text_light_nodisable"
/>
</LinearLayout>
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
new file mode 100644
index 000000000000..ca6fe2d66f4d
--- /dev/null
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -0,0 +1,69 @@
+<?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.
+*/
+-->
+
+<!-- Layout of time picker -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_gravity="center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <!-- hour -->
+ <NumberPicker
+ android:id="@+id/hour"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="20dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- divider -->
+ <TextView
+ android:id="@+id/divider"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ />
+
+ <!-- minute -->
+ <NumberPicker
+ android:id="@+id/minute"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- AM / PM -->
+ <NumberPicker
+ android:id="@+id/amPm"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/values-xlarge-land/dimens.xml b/core/res/res/values-xlarge-land/dimens.xml
index 6a2b93fd0e88..0b43a42e7ef4 100644
--- a/core/res/res/values-xlarge-land/dimens.xml
+++ b/core/res/res/values-xlarge-land/dimens.xml
@@ -17,6 +17,9 @@
*/
-->
<resources>
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">100dip</dimen>
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
<!-- Minimum width of the search view text entry area. -->
<dimen name="search_view_text_min_width">256dip</dimen>
</resources>
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index 5b0ea305f69d..63d3619a0284 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -24,15 +24,17 @@
<dimen name="status_bar_icon_size">32dip</dimen>
<!-- Size of the giant number (unread count) in the notifications -->
<dimen name="status_bar_content_number_size">48sp</dimen>
-
+
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
<!-- Margin for permanent screen decorations at the bottom. -->
<dimen name="screen_margin_bottom">48dip</dimen>
-
+
<!-- Default height of a key in the password keyboard for alpha -->
- <dimen name="password_keyboard_key_height_alpha">0.35in</dimen>
+ <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
<!-- Default height of a key in the password keyboard for numeric -->
- <dimen name="password_keyboard_key_height_numeric">0.47in</dimen>
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+ <dimen name="password_keyboard_height">48.0mm</dimen>
<!-- The width that is used when creating thumbnails of applications. -->
<dimen name="thumbnail_width">230dp</dimen>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index de233c8a31e6..b9caeb38d12d 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -534,6 +534,12 @@
<!-- The CalndarView style. -->
<attr name="calendarViewStyle" format="reference" />
+ <!-- The TimePicker style. -->
+ <attr name="timePickerStyle" format="reference" />
+
+ <!-- The DatePicker style. -->
+ <attr name="datePickerStyle" format="reference" />
+
<!-- Fast scroller styles -->
<eat-comment />
@@ -2869,6 +2875,7 @@
<!-- Gravity setting for positioning the currently selected item. -->
<attr name="gravity" />
</declare-styleable>
+
<declare-styleable name="DatePicker">
<!-- The first year (inclusive), for example "1940". -->
<attr name="startYear" format="integer" />
@@ -2882,6 +2889,8 @@
<attr name="minDate" format="string" />
<!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
<attr name="maxDate" format="string" />
+ <!-- @hide The layout of the time picker. -->
+ <attr name="layout" />
</declare-styleable>
<declare-styleable name="TwoLineListItem">
@@ -3080,9 +3089,24 @@
</declare-styleable>
<declare-styleable name="NumberPicker">
- <attr name="orientation" />
- <!-- Color for the solid color background if such for optimized rendering. -->
+ <!-- @hide Color for the solid color background if such for optimized rendering. -->
<attr name="solidColor" format="color|reference" />
+ <!-- @hide Whether the number picker supports fligning. -->
+ <attr name="flingable" format="boolean" />
+ <!-- @hide The divider for making the selection area. -->
+ <attr name="selectionDivider" format="reference" />
+ <!-- @hide The height of the selection divider. -->
+ <attr name="selectionDividerHeight" format="dimension" />
+ </declare-styleable>
+
+ <declare-styleable name="TimePicker">
+ <!-- @hide The layout of the time picker. -->
+ <attr name="layout" />
+ </declare-styleable>
+
+ <declare-styleable name="DatePicker">
+ <!-- @hide The layout of the time picker. -->
+ <attr name="layout" />
</declare-styleable>
<!-- ========================= -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1b47b5483f6e..a30e31689ac9 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1426,6 +1426,8 @@
<public type="attr" name="fastScrollTextColor" />
<public type="attr" name="largeHeap" />
<public type="attr" name="windowCloseOnTouchOutside" />
+ <public type="attr" name="datePickerStyle" />
+ <public type="attr" name="calendarViewStyle" />
<!-- A simple fade-in animation. -->
<public type="animator" name="fade_in" id="0x010b0000" />
@@ -1627,21 +1629,15 @@
<public type="style" name="Holo.Light.ButtonBar.AlertDialog" />
<public type="style" name="Holo.SegmentedButton" />
<public type="style" name="Holo.Light.SegmentedButton" />
- <public type="style" name="Widget.ImageButton.NumberPickerUpButton" />
- <public type="style" name="Widget.EditText.NumberPickerInputText" />
- <public type="style" name="Widget.ImageButton.NumberPickerDownButton" />
- <public type="style" name="Widget.Holo.ImageButton.NumberPickerUpButton" />
- <public type="style" name="Widget.Holo.EditText.NumberPickerInputText" />
- <public type="style" name="Widget.Holo.ImageButton.NumberPickerDownButton" />
- <public type="style" name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" />
- <public type="style" name="Widget.Holo.Light.EditText.NumberPickerInputText" />
- <public type="style" name="Widget.Holo.Light.ImageButton.NumberPickerDownButton" />
<public type="style" name="Widget.CalendarView" />
<public type="style" name="Widget.Holo.CalendarView" />
<public type="style" name="Widget.Holo.Light.CalendarView" />
+ <public type="style" name="Widget.DatePicker" />
+ <public type="style" name="Widget.Holo.DatePicker" />
<public type="string" name="selectTextMode" />
<!-- Default icon for applications that don't specify an icon. -->
<public type="mipmap" name="sym_def_app_icon" id="0x010d0000" />
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9a1b42d9b705..46e45dbf6dc0 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2677,4 +2677,11 @@
<string name="sync_undo_deletes">Undo the deletes.</string>
<!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to do nothing for now -->
<string name="sync_do_nothing">Do nothing for now.</string>
+
+ <!-- Title of the VPN service notification: VPN connected [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_title_connected"><xliff:g id="profilename" example="Home PPTP">%s</xliff:g> VPN connected</string>
+ <!-- Title of the VPN service notification: VPN disconnected [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_title_disconnected"><xliff:g id="profilename" example="Home PPTP">%s</xliff:g> VPN disconnected</string>
+ <!-- Message of the VPN service notification: Hint to reconnect VPN [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_hint_disconnected">Touch to reconnect to a VPN.</string>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 16c80d0e72fd..939e9ef10063 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -489,7 +489,16 @@
<item name="android:orientation">vertical</item>
<item name="android:fadingEdge">vertical</item>
<item name="android:fadingEdgeLength">50dip</item>
- <item name="android:solidColor">@android:color/transparent</item>
+ <item name="android:flingable">false</item>
+ </style>
+
+ <style name="Widget.TimePicker">
+ <item name="android:layout">@android:layout/time_picker</item>
+ </style>
+
+ <style name="Widget.DatePicker">
+ <item name="android:layout">@android:layout/date_picker</item>
+ <item name="android:calendarViewShown">false</item>
</style>
<style name="Widget.ImageButton.NumberPickerUpButton">
@@ -1502,6 +1511,22 @@
<item name="android:background">@android:drawable/btn_default_holo_dark</item>
</style>
+ <style name="Widget.Holo.NumberPicker" parent="Widget.NumberPicker">
+ <item name="android:solidColor">@android:color/transparent</item>
+ <item name="android:flingable">true</item>
+ <item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
+ <item name="android:selectionDividerHeight">2dip</item>
+ </style>
+
+ <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
+ <item name="android:layout">@android:layout/time_picker_holo</item>
+ </style>
+
+ <style name="Widget.Holo.DatePicker" parent="Widget.DatePicker">
+ <item name="android:layout">@android:layout/date_picker_holo</item>
+ <item name="android:calendarViewShown">true</item>
+ </style>
+
<style name="Widget.Holo.ImageButton.NumberPickerUpButton">
<item name="android:background">@null</item>
<item name="android:src">@android:drawable/numberpicker_up_btn_holo_dark</item>
@@ -1870,6 +1895,15 @@
<item name="android:weekDayTextAppearance">@android:style/TextAppearance.Holo.Light.CalendarViewWeekDayView</item>
</style>
+ <style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker">
+ </style>
+
+ <style name="Widget.Holo.Light.TimePicker" parent="Widget.Holo.TimePicker">
+ </style>
+
+ <style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker">
+ </style>
+
<style name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
<item name="android:src">@android:drawable/numberpicker_up_btn_holo_light</item>
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b257a7327d75..2f8cffcb3505 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -290,6 +290,12 @@
<!-- CalendarView style-->
<item name="calendarViewStyle">@style/Widget.CalendarView</item>
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.DatePicker</item>
+
<item name="fastScrollThumbDrawable">@android:drawable/scrollbar_handle_accelerated_anim2</item>
<item name="fastScrollTrackDrawable">@null</item>
<item name="fastScrollPreviewBackgroundRight">@android:drawable/menu_submenu_background</item>
@@ -978,10 +984,17 @@
<item name="numberPickerUpButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerUpButton</item>
<item name="numberPickerDownButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerDownButton</item>
<item name="numberPickerInputTextStyle">@style/Widget.Holo.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.Holo.NumberPicker</item>
<!-- CalendarView style-->
<item name="calendarViewStyle">@style/Widget.Holo.CalendarView</item>
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.Holo.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.Holo.DatePicker</item>
+
<item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
<item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_dark</item>
<item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_dark</item>
@@ -1003,6 +1016,7 @@
<item name="disabledAlpha">0.5</item>
<item name="backgroundDimAmount">0.6</item>
+
<!-- Text styles -->
<item name="textAppearance">@android:style/TextAppearance.Holo.Light</item>
<item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item>
@@ -1236,10 +1250,17 @@
<item name="numberPickerUpButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerUpButton</item>
<item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
<item name="numberPickerInputTextStyle">@style/Widget.Holo.Light.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.Holo.Light.NumberPicker</item>
<!-- CalendarView style-->
<item name="calendarViewStyle">@style/Widget.Holo.Light.CalendarView</item>
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.Holo.Light.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.Holo.Light.DatePicker</item>
+
<item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
<item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_light</item>
<item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_light</item>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty.xml b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
index 0a35040aa845..fd1d5f19a270 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** 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.
@@ -19,26 +19,15 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
- android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- >
-
- <Row android:rowEdgeFlags="top">
- <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="2"/>
- <Key android:keyLabel="3"/>
- <Key android:keyLabel="4"/>
- <Key android:keyLabel="5"/>
- <Key android:keyLabel="6"/>
- <Key android:keyLabel="7"/>
- <Key android:keyLabel="8"/>
- <Key android:keyLabel="9"/>
- <Key android:keyLabel="0" android:keyEdgeFlags="right"/>
- </Row>
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
- <Row>
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
<Key android:keyLabel="q" android:keyEdgeFlags="left"/>
<Key android:keyLabel="w"/>
<Key android:keyLabel="e"/>
@@ -48,12 +37,21 @@
<Key android:keyLabel="u"/>
<Key android:keyLabel="i"/>
<Key android:keyLabel="o"/>
- <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+ <Key android:keyLabel="p"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:keyLabel="a" android:horizontalGap="5%p"
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="11.167%p"
android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="a"/>
<Key android:keyLabel="s"/>
<Key android:keyLabel="d"/>
<Key android:keyLabel="f"/>
@@ -61,14 +59,22 @@
<Key android:keyLabel="h"/>
<Key android:keyLabel="j"/>
<Key android:keyLabel="k"/>
- <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+ <Key android:keyLabel="l"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
- android:keyWidth="15%p" android:isModifier="true"
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
android:iconPreview="@drawable/sym_keyboard_feedback_shift"
- android:isSticky="true" android:keyEdgeFlags="left"/>
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
<Key android:keyLabel="z"/>
<Key android:keyLabel="x"/>
<Key android:keyLabel="c"/>
@@ -76,26 +82,26 @@
<Key android:keyLabel="b"/>
<Key android:keyLabel="n"/>
<Key android:keyLabel="m"/>
- <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
- android:keyWidth="15%p" android:keyEdgeFlags="right"
- android:iconPreview="@drawable/sym_keyboard_feedback_delete"
- android:isRepeatable="true"/>
+ <Key android:keyLabel="," />
+ <Key android:keyLabel="." />
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
- <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
- android:keyWidth="20%p" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="," />
- <Key android:keyLabel="-" />
- <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+ <Row android:keyWidth="8.042%p"
+ android:keyboardMode="@+id/mode_normal">
+ <Key android:keyLabel="/" android:horizontalGap="24.126%p"/>
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
- android:keyWidth="20%p"/>
- <Key android:keyLabel="=" />
- <Key android:keyLabel="."
- android:keyWidth="10%p"/>
- <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
- android:iconPreview="@drawable/sym_keyboard_feedback_ok"
- android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel="'" />
+ <Key android:keyLabel="-" />
</Row>
</Keyboard>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
index 9e9db818ba45..671d87f45a41 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** 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.
@@ -19,82 +19,89 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
- android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- >
-
- <Row android:rowEdgeFlags="top">
- <Key android:keyLabel="\@" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="\#"/>
- <Key android:keyLabel="$"/>
- <Key android:keyLabel="%"/>
- <Key android:keyLabel="&amp;"/>
- <Key android:keyLabel="*"/>
- <Key android:keyLabel="-"/>
- <Key android:keyLabel="+"/>
- <Key android:keyLabel="("/>
- <Key android:keyLabel=")" android:keyEdgeFlags="right"/>
- </Row>
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
- <Row>
- <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="w"/>
- <Key android:keyLabel="e"/>
- <Key android:keyLabel="r"/>
- <Key android:keyLabel="t"/>
- <Key android:keyLabel="y"/>
- <Key android:keyLabel="u"/>
- <Key android:keyLabel="i"/>
- <Key android:keyLabel="o"/>
- <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
+ <Key android:keyLabel="Q" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="W"/>
+ <Key android:keyLabel="E"/>
+ <Key android:keyLabel="R"/>
+ <Key android:keyLabel="T"/>
+ <Key android:keyLabel="Y"/>
+ <Key android:keyLabel="U"/>
+ <Key android:keyLabel="I"/>
+ <Key android:keyLabel="O"/>
+ <Key android:keyLabel="P"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:keyLabel="a" android:horizontalGap="5%p"
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="11.167%p"
android:keyEdgeFlags="left"/>
- <Key android:keyLabel="s"/>
- <Key android:keyLabel="d"/>
- <Key android:keyLabel="f"/>
- <Key android:keyLabel="g"/>
- <Key android:keyLabel="h"/>
- <Key android:keyLabel="j"/>
- <Key android:keyLabel="k"/>
- <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+ <Key android:keyLabel="A"/>
+ <Key android:keyLabel="S"/>
+ <Key android:keyLabel="D"/>
+ <Key android:keyLabel="F"/>
+ <Key android:keyLabel="G"/>
+ <Key android:keyLabel="H"/>
+ <Key android:keyLabel="J"/>
+ <Key android:keyLabel="K"/>
+ <Key android:keyLabel="L"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
- android:keyWidth="15%p" android:isModifier="true"
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
android:iconPreview="@drawable/sym_keyboard_feedback_shift"
- android:isSticky="true" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="z"/>
- <Key android:keyLabel="x"/>
- <Key android:keyLabel="c"/>
- <Key android:keyLabel="v"/>
- <Key android:keyLabel="b"/>
- <Key android:keyLabel="n"/>
- <Key android:keyLabel="m"/>
- <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
- android:keyWidth="15%p" android:keyEdgeFlags="right"
- android:iconPreview="@drawable/sym_keyboard_feedback_delete"
- android:isRepeatable="true"/>
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="Z"/>
+ <Key android:keyLabel="X"/>
+ <Key android:keyLabel="C"/>
+ <Key android:keyLabel="V"/>
+ <Key android:keyLabel="B"/>
+ <Key android:keyLabel="N"/>
+ <Key android:keyLabel="M"/>
+ <Key android:keyLabel="!" />
+ <Key android:keyLabel="\?" />
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
- <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
- android:keyWidth="20%p" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="," />
- <Key android:keyLabel="_" />
- <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+ <Row android:keyWidth="8.042%p"
+ android:keyboardMode="@+id/mode_normal">
+ <Key android:keyLabel="\@" android:horizontalGap="24.126%p"/>
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
- android:keyWidth="20%p"/>
- <Key android:keyLabel="+" />
- <Key android:keyLabel="."/>
- <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
- android:iconPreview="@drawable/sym_keyboard_feedback_ok"
- android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel="&quot;" />
+ <Key android:keyLabel="_" />
</Row>
</Keyboard>
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols.xml b/core/res/res/xml-xlarge/password_kbd_symbols.xml
new file mode 100755
index 000000000000..5ae5577ae186
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_symbols.xml
@@ -0,0 +1,106 @@
+<?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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
+
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
+ <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="2"/>
+ <Key android:keyLabel="3"/>
+ <Key android:keyLabel="4"/>
+ <Key android:keyLabel="5"/>
+ <Key android:keyLabel="6"/>
+ <Key android:keyLabel="7"/>
+ <Key android:keyLabel="8"/>
+ <Key android:keyLabel="9"/>
+ <Key android:keyLabel="0"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_alpha_key"
+ android:keyWidth="11.167%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="\#"/>
+ <Key android:keyLabel="$"/>
+ <Key android:keyLabel="%"/>
+ <Key android:keyLabel="&amp;"/>
+ <Key android:keyLabel="*"/>
+ <Key android:keyLabel="-"/>
+ <Key android:keyLabel="+"/>
+ <Key android:keyLabel="("/>
+ <Key android:keyLabel=")"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="&lt;"/>
+ <Key android:keyLabel="&gt;"/>
+ <Key android:keyLabel="="/>
+ <Key android:keyLabel=":"/>
+ <Key android:keyLabel=";"/>
+ <Key android:keyLabel=","/>
+ <Key android:keyLabel="."/>
+ <Key android:keyLabel="!" />
+ <Key android:keyLabel="\?" />
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:keyLabel="\@" android:horizontalGap="16.084%p"/>
+ <Key android:keyLabel="/" />
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel="\'" />
+ <Key android:keyLabel="-" />
+ </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
new file mode 100755
index 000000000000..26ade76275a9
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
@@ -0,0 +1,100 @@
+<?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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha">
+
+ <Row android:keyWidth="8.272%p"
+ android:rowEdgeFlags="top">
+ <Key android:keyLabel="Tab" android:codes="9"/>
+ <Key android:keyLabel="~" />
+ <Key android:keyLabel="`" />
+ <Key android:keyLabel="|" />
+ <Key android:keyLabel="•" />
+ <Key android:keyLabel="√" />
+ <Key android:keyLabel="π" />
+ <Key android:keyLabel="÷" />
+ <Key android:keyLabel="×" />
+ <Key android:keyLabel="§" />
+ <Key android:keyLabel="Δ" />
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_alpha_key"
+ android:keyWidth="11.167%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="£" />
+ <Key android:keyLabel="¢" />
+ <Key android:keyLabel="€" />
+ <Key android:keyLabel="¥" />
+ <Key android:keyLabel="^"/>
+ <Key android:keyLabel="°" />
+ <Key android:keyLabel="±" />
+ <Key android:keyLabel="{" />
+ <Key android:keyLabel="}" />
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="\\" />
+ <Key android:keyLabel="©" />
+ <Key android:keyLabel="®" />
+ <Key android:keyLabel="™" />
+ <Key android:keyLabel="℅" />
+ <Key android:keyLabel="[" />
+ <Key android:keyLabel="]" />
+ <Key android:keyLabel="¡" />
+ <Key android:keyLabel="¿" />
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <!-- This row is intentionally not marked as a bottom row -->
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="32" android:horizontalGap="32.168%p"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ </Row>
+</Keyboard>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 67f1fec35e44..270d153e4f87 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -213,6 +213,9 @@
<li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
<span class="en">3D with OpenGL</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
+ <span class="en">Animation</span>
+ </a><span class="new">new!</span></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 05f40238925d..6594568ff883 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -17,8 +17,6 @@ parent.link=index.html
<li><a href="#shape-drawable">Shape Drawable</a></li>
<!-- <li><a href="#state-list">StateListDrawable</a></li> -->
<li><a href="#nine-patch">Nine-patch</a></li>
- <li><a href="#tween-animation">Tween Animation</a></li>
- <li><a href="#frame-animation">Frame Animation</a></li>
</ol>
</div>
</div>
@@ -328,172 +326,4 @@ Notice how the width and height of the button varies with the text, and the back
stretches to accommodate it.
</p>
-<img src="{@docRoot}images/ninepatch_examples.png" alt=""/>
-
-
-<h2 id="tween-animation">Tween Animation</h2>
-
-<p>A tween animation can perform a series of simple transformations (position, size, rotation, and transparency) on
-the contents of a View object. So, if you have a TextView object, you can move, rotate, grow, or shrink the text.
-If it has a background image, the background image will be transformed along with the text.
-The {@link android.view.animation animation package} provides all the classes used in a tween animation.</p>
-
-<p>A sequence of animation instructions defines the tween animation, defined by either XML or Android code.
-Like defining a layout, an XML file is recommended because it's more readable, reusable, and swappable
-than hard-coding the animation. In the example below, we use XML. (To learn more about defining an animation
-in your application code, instead of XML, refer to the
-{@link android.view.animation.AnimationSet} class and other {@link android.view.animation.Animation} subclasses.)</p>
-
-<p>The animation instructions define the transformations that you want to occur, when they will occur,
-and how long they should take to apply. Transformations can be sequential or simultaneous &mdash;
-for example, you can have the contents of a TextView move from left to right, and then
-rotate 180 degrees, or you can have the text move and rotate simultaneously. Each transformation
-takes a set of parameters specific for that transformation (starting size and ending size
-for size change, starting angle and ending angle for rotation, and so on), and
-also a set of common parameters (for instance, start time and duration). To make
-several transformations happen simultaneously, give them the same start time;
-to make them sequential, calculate the start time plus the duration of the preceding transformation.
-</p>
-
-<p>The animation XML file belongs in the <code>res/anim/</code> directory of your Android project.
-The file must have a single root element: this will be either a single <code>&lt;alpha&gt;</code>,
-<code>&lt;scale&gt;</code>, <code>&lt;translate&gt;</code>, <code>&lt;rotate&gt;</code>, interpolator element,
-or <code>&lt;set&gt;</code> element that holds groups of these elements (which may include another
-<code>&lt;set&gt;</code>). By default, all animation instructions are applied simultaneously.
-To make them occur sequentially, you must specify the <code>startOffset</code> attribute, as shown in the example below.
-</p>
-
-<p>The following XML from one of the ApiDemos is used to stretch,
-then simultaneously spin and rotate a View object.
-</p>
-<pre>
-&lt;set android:shareInterpolator="false"&gt;
- &lt;scale
- android:interpolator="&#64;android:anim/accelerate_decelerate_interpolator"
- android:fromXScale="1.0"
- android:toXScale="1.4"
- android:fromYScale="1.0"
- android:toYScale="0.6"
- android:pivotX="50%"
- android:pivotY="50%"
- android:fillAfter="false"
- android:duration="700" /&gt;
- &lt;set android:interpolator="&#64;android:anim/decelerate_interpolator"&gt;
- &lt;scale
- android:fromXScale="1.4"
- android:toXScale="0.0"
- android:fromYScale="0.6"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400"
- android:fillBefore="false" /&gt;
- &lt;rotate
- android:fromDegrees="0"
- android:toDegrees="-45"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400" /&gt;
- &lt;/set&gt;
-&lt;/set&gt;
-</pre>
-<p>Screen coordinates (not used in this example) are (0,0) at the upper left hand corner,
-and increase as you go down and to the right.</p>
-
-<p>Some values, such as pivotX, can be specified relative to the object itself or relative to the parent.
-Be sure to use the proper format for what you want ("50" for 50% relative to the parent, or "50%" for 50%
-relative to itself).</p>
-
-<p>You can determine how a transformation is applied over time by assigning an
-{@link android.view.animation.Interpolator}. Android includes
-several Interpolator subclasses that specify various speed curves: for instance,
-{@link android.view.animation.AccelerateInterpolator} tells
-a transformation to start slow and speed up. Each one has an attribute value that can be applied in the XML.</p>
-
-<p>With this XML saved as <code>hyperspace_jump.xml</code> in the <code>res/anim/</code> directory of the
-project, the following Java code will reference it and apply it to an {@link android.widget.ImageView} object
-from the layout.
-</p>
-<pre>
-ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
-Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
-spaceshipImage.startAnimation(hyperspaceJumpAnimation);
-</pre>
-
-<p>As an alternative to <code>startAnimation()</code>, you can define a starting time for the animation with
-<code>{@link android.view.animation.Animation#setStartTime(long) Animation.setStartTime()}</code>,
-then assign the animation to the View with
-<code>{@link android.view.View#setAnimation(android.view.animation.Animation) View.setAnimation()}</code>.
-</p>
-
-<p>For more information on the XML syntax, available tags and attributes, see <a
-href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-
-<p class="note"><strong>Note:</strong> Regardless of how your animation may move or resize, the bounds of the
-View that holds your animation will not automatically adjust to accommodate it. Even so, the animation will still
-be drawn beyond the bounds of its View and will not be clipped. However, clipping <em>will occur</em>
-if the animation exceeds the bounds of the parent View.</p>
-
-
-<h2 id="frame-animation">Frame Animation</h2>
-
-<p>This is a traditional animation in the sense that it is created with a sequence of different
-images, played in order, like a roll of film. The {@link android.graphics.drawable.AnimationDrawable}
-class is the basis for frame animations.</p>
-
-<p>While you can define the frames of an animation in your code, using the
-{@link android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished with a single XML
-file that lists the frames that compose the animation. Like the tween animation above, the XML file for this kind
-of animation belongs in the <code>res/drawable/</code> directory of your Android project. In this case,
-the instructions are the order and duration for each frame of the animation.</p>
-
-<p>The XML file consists of an <code>&lt;animation-list></code> element as the root node and a series
-of child <code>&lt;item></code> nodes that each define a frame: a drawable resource for the frame and the frame duration.
-Here's an example XML file for a frame-by-frame animation:</p>
-<pre>
-&lt;animation-list xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="true">
- &lt;item android:drawable="&#64;drawable/rocket_thrust1" android:duration="200" />
- &lt;item android:drawable="&#64;drawable/rocket_thrust2" android:duration="200" />
- &lt;item android:drawable="&#64;drawable/rocket_thrust3" android:duration="200" />
-&lt;/animation-list>
-</pre>
-
-<p>This animation runs for just three frames. By setting the <code>android:oneshot</code> attribute of the
-list to <var>true</var>, it will cycle just once then stop and hold on the last frame. If it is set <var>false</var> then
-the animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the <code>res/drawable/</code> directory
-of the project, it can be added as the background image to a View and then called to play. Here's an example Activity,
-in which the animation is added to an {@link android.widget.ImageView} and then animated when the screen is touched:</p>
-<pre>
-AnimationDrawable rocketAnimation;
-
-public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
- rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
- rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
-}
-
-public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- rocketAnimation.start();
- return true;
- }
- return super.onTouchEvent(event);
-}
-</pre>
-<p>It's important to note that the <code>start()</code> method called on the AnimationDrawable cannot be
-called during the <code>onCreate()</code> method of your Activity, because the AnimationDrawable is not yet fully attached
-to the window. If you want to play the animation immediately, without
-requiring interaction, then you might want to call it from the
-<code>{@link android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code> method in
-your Activity, which will get called when Android brings your window into focus.</p>
-
-<p>For more information on the XML syntax, available tags and attributes, see <a
-href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-
+<img src="{@docRoot}images/ninepatch_examples.png" alt=""/> \ No newline at end of file
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
new file mode 100644
index 000000000000..c977d51c14da
--- /dev/null
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -0,0 +1,839 @@
+page.title=Animation
+@jd:body
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li>
+ <a href="#property-animation">Property Animation</a>
+
+ <ol>
+ <li><a href="#value-animator">Animating with ValueAnimator</a></li>
+
+ <li><a href="#object-animator">Animating with ObjectAnimator</a></li>
+
+ <li><a href="#type-evaluator">Using the TypeEvaluator</a></li>
+
+ <li><a href="#interpolators">Using interpolators</a></li>
+
+ <li><a href="#keyframes">Specifying keyframes</a></li>
+
+ <li><a href="#choreography">Choreographing multiple animations with AnimatorSet</a></li>
+
+ <li><a href="#declaring-xml">Declaring animations in XML</a></li>
+ </ol>
+ </li>
+
+ <li>
+ <a href="#view-animation">View Animation</a>
+
+ <ol>
+ <li><a href="#tween-animation">Tween animation</a></li>
+
+ <li><a href="#frame-animation">Frame animation</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Key classes</h2>
+
+ <ol>
+ <li><code><a href=
+ "/reference/android/animation/ValueAnimator.html">ValueAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/ObjectAnimator.html">ObjectAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/TypeEvaluator.html">TypeEvaluator</a></code></li>
+ </ol>
+
+ <h2>Related samples</h2>
+
+ <ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API Demos</a></li>
+ </ol>
+
+ </div>
+ </div>
+
+ <p>The Android system provides a flexible animation system that allows you to animate
+ almost anything, either programmatically or declaratively with XML. There are two
+ animation systems that you can choose from: <a href="property-animation">property
+ animation</a> and <a href="#view-animation">view animation</a>. You can use whichever
+ system that matches your needs, but use only one system for each object that you
+ are animating.</p>
+
+ <h2 id="property-animation">Property Animation</h2>
+
+ <p>Introduced in Android 3.0, the property animation system allows you to animate
+ object properties of any type. <code>int</code>, <code>float</code>,
+ and hexadecimal color values are supported by default. You can animate any other type by telling the
+ system how to calculate the values for that given type.</p>
+
+ <p>The property animation system allows you to define many aspects of an animation,
+ such as:</p>
+
+ <ul>
+ <li>Duration</li>
+
+ <li>Repeat amount and behavior</li>
+
+ <li>Type of time interpolation</li>
+
+ <li>Animator sets to play animations together, sequentially, or after specified
+ delays</li>
+
+ <li>Frame refresh delay</li>
+
+ </ul>
+
+ <p>Most of the property animation system's features can be found in
+ {@link android.animation android.animation}. Because the
+ <a href="#view-animation>view animation</a> system already
+ defines many interpolators in {@link android.view.animation android.view.animation},
+ you will use those to define your animation's interpolation in the property animation
+ system as well.
+ </p>
+
+ <p>The following items are the main components of the property animation system:</p>
+
+ <dl>
+ <dt><strong>Animators</strong></dt>
+
+ <dd>
+ The {@link android.animation.Animator} class provides the basic structure for
+ creating animations. You normally do not use this class directly as it only provides
+ minimal functionality that must be extended to fully support animating values.
+ The following subclasses extend {@link android.animation.Animator}, which you might find more useful:
+
+ <ul>
+ <li>{@link android.animation.ValueAnimator} is the main timing engine for
+ property animation and computes the values for the property to be animated.
+ {@link android.animation.ValueAnimator} only computes the animation values and is
+ not aware of the specific object and property that is being animated or what the
+ values might be used for. You must listen for updates to values calculated by the
+ {@link android.animation.ValueAnimator} and process the data with your own logic.
+ See the section about <a href="#value-animator">Animating with ValueAnimator</a>
+ for more information.</li>
+
+ <li>{@link android.animation.ObjectAnimator} is a subclass of {@link
+ android.animation.ValueAnimator} and allows you to set a target object and object
+ property to animate. This class is aware of the object and property to be
+ animated, and updates the property accordingly when it computes a new value for
+ the animation. See the section about <a href="#object-animator">
+ Animating with ObjectAnimator</a> for more information.</li>
+
+ <li>{@link android.animation.AnimatorSet} provides a mechanism to group
+ animations together so that they are rendered in relation to one another. You can
+ set animations to play together, sequentially, or after a specified delay.
+ See the section about <a href="#choreography">
+ Choreographing multiple animations with Animator Sets</a> for more information.</li>
+ </ul>
+ </dd>
+
+ <dt><strong>Evaluators</strong></dt>
+
+ <dd>
+ <p>If you are animating an object property that is <em>not</em> an <code>int</code>,
+ <code>float</code>, or color, implement the {@link android.animation.TypeEvaluator}
+ interface to specify how to compute the object property's animated values. You give
+ a {@link android.animation.TypeEvaluator} the timing data that is provided by an
+ {@link android.animation.Animator} class, the animation's start and end value, and
+ provide logic that computes the animated values of the property based on this data.</p>
+
+ <p>You can also specify a custom {@link android.animation.TypeEvaluator} for
+ <code>int</code>, <code>float</code>, and color values as well, if you want to
+ process those types differently than the default behavior.</p>
+
+ <p>See <a href="#type-evaluator">Using a TypeEvaluator</a> for more information on
+ how to write a custom evaluator.</p>
+ </dd>
+
+ <dt><strong>Interpolators</strong></dt>
+
+ <dd>
+ <p>A time interpolator defines how specific values in an animation are calculated
+ as a function of time. For example, you can specify animations to happen linearly
+ across the whole animation, meaning the animation moves evenly the entire time, or
+ you can specify animations to use non-linear time, for example, using acceleration
+ or deceleration at the beginning or end of the animation.</p>
+
+ <p>The Android system provides a set of common interpolators in
+ {@link android.view.animation android.view.animation}. If none of these suits your needs, you
+ can implement the {@link android.animation.TimeInterpolator} interface and create
+ your own. See <a href="#interpolators">Interpolators</a> for more information on
+ how to write a custom interpolator.</p>
+ </dd>
+ </dl>
+
+
+ <p>The <code>com.example.android.apis.animation</code> package in the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">
+ API Demos</a> sample project also provides a good overview and many examples on how to
+ use the property animation system.</p>
+
+
+ <h3>How the property animation system calculates animated values</h3>
+
+ <p>When you call {@link android.animation.ValueAnimator#start start()} to begin an animation,
+ the {@link android.animation.ValueAnimator} calculates
+ an <em>elapsed fraction</em> between 0 and 1, based on the duration of the animation
+ and how much time has elapsed. The elapsed fraction represents the percentage of time
+ that the animation has completed, 0 meaning 0% and 1 meaning 100%. The Animator then
+ calls the {@link android.animation.TimeInterpolator} that is currently set,
+ to calculate an <em>eased fraction</em>,
+ which is a modified value of the elapsed fraction that takes into account the interpolator that
+ is set (time interpolation is often referred to as <em>easing</em>). The eased fraction
+ is the final value that is used to animate the property.</p>
+
+ <p>Once the eased fraction is calculated, {@link android.animation.ValueAnimator} calls
+ the appropriate {@link android.animation.TypeEvaluator} to calculate the final value of
+ the property that you are animating, based on the eased fraction, the starting value,
+ and ending value of the animation.</p>
+
+ <h3 id="value-animator">Animating with ValueAnimator</h3>
+
+ <p>The {@link android.animation.ValueAnimator} class lets you animate values of some
+ type for the duration of an animation by specifying a set of <code>int</code>,
+ <code>float</code>, or color values to animate over and the duration of the animation.
+ You obtain a {@link android.animation.ValueAnimator} by calling one of its factory
+ methods: {@link android.animation.ValueAnimator#ofInt ofInt()},
+ {@link android.animation.ValueAnimator#ofFloat ofFloat()},
+ or {@link android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
+
+ <pre>ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts
+ calculating the values of the animation, between 0 and 1, for
+ a duration of 1000 ms, when the <code>start()</code> method runs.</p>
+
+ <p>You can also specify a custom type to animate by doing the following:</p>
+
+ <pre>ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts
+ calculating the values of the animation, between <code>startPropertyValue</code> and
+ <code>endPropertyValue</code> using the logic supplied by <code>MyTypeEvaluator</code>
+ for a duration of 1000 ms, when the {@link android.animation.ValueAnimator#start start()}
+ method runs.</p>
+
+ <p>The previous code snippets, however, do not affect an object, because the {@link
+ android.animation.ValueAnimator} does not operate on objects or properties directly. To
+ use the results of a {@link android.animation.ValueAnimator}, you must define listeners
+ in the {@link android.animation.ValueAnimator} to appropriately handle important events
+ during the animation's lifespan, such as frame updates. You can implement the following
+ interfaces to create listeners for {@link android.animation.ValueAnimator}:</p>
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener}
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart
+ onAnimationStart()} - Called when the animation starts</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd
+ onAnimationEnd()} - Called when the animation ends.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat
+ onAnimationRepeat()} - Called when the animation repeats itself.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel
+ onAnimationCancel()} - Called when the animation is canceled.</li>
+ </ul>
+ </li>
+
+ <li>{@link android.animation.ValueAnimator.AnimatorUpdateListener}
+
+ <ul>
+ <li>
+ <p>{@link
+ android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
+ onAnimationUpdate()} - called on every frame of the animation.
+ Listen to this event to use the calculated values generated by
+ {@link android.animation.ValueAnimator} during an animation. To use the value,
+ query the {@link android.animation.ValueAnimator} object passed into the event
+ to get the current animated value with the
+ {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method.</p>
+
+ <p>If you are animating your own custom object (not View objects), this
+ callback must also call the {@link android.view.View#invalidate invalidate()}
+ method to force a redraw of the screen. If you are animating View objects,
+ {@link android.view.View#invalidate invalidate()} is automatically called when
+ a property of the View is changed.</p>
+ </li>
+ </ul>
+
+ <p>You can extend the {@link android.animation.AnimatorListenerAdapter} class
+ instead of implementing the {@link android.animation.Animator.AnimatorListener}
+ interface, if you do not want to implement all of the methods of the {@link
+ android.animation.Animator.AnimatorListener} interface. The {@link
+ android.animation.AnimatorListenerAdapter} class provides empty implementations of the
+ methods that you can choose to override.</p>
+ </li>
+ </ul>
+
+ <p>For example, the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample in the API demos creates an {@link
+ android.animation.AnimatorListenerAdapter} for just the {@link
+ android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
+ callback:</p>
+ <pre>ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+fadeAnim.addListener(new AnimatorListenerAdapter() {
+public void onAnimationEnd(Animator animation) {
+ balls.remove(((ObjectAnimator)animation).getTarget());
+}
+
+</pre>
+
+ <h3 id="object-animator">Animating with ObjectAnimator</h3>
+
+ <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
+ android.animation.ValueAnimator} (discussed in the previous section)
+ and combines the timing engine and value computation
+ of {@link android.animation.ValueAnimator} with the ability to animate a named property
+ of a target object. This makes animating any object much easier, as you no longer need
+ to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener}, because
+ the animated property updates automatically.</p>
+
+ <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
+ android.animation.ValueAnimator}, but you also specify the object and that object's
+ property (as a String) that you want to animate:</p>
+ <pre>
+ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
+anim.setDuration(1000);
+anim.start();
+</pre>
+
+ <p>To have the {@link android.animation.ObjectAnimator} update properties correctly,
+ you must do the following:</p>
+
+ <ul>
+ <li>The object property that you are animating must have a setter function in the
+ form of <code>set&lt;propertyName&gt;()</code>. Because the {@link
+ android.animation.ObjectAnimator} automatically updates the property during
+ animation, it must be able to access the property with this setter method. For
+ example, if the property name is <code>foo</code>, you need to have a
+ <code>setFoo()</code> method. If this setter method does not exist, you have three
+ options:
+
+ <ul>
+ <li>Add the setter method to the class if you have the rights to do so.</li>
+
+ <li>Use a wrapper class that you have rights to change and have that wrapper
+ receive the value with a valid setter method and forward it to the original
+ object.</li>
+
+ <li>Use {@link android.animation.ValueAnimator} instead.</li>
+ </ul>
+ </li>
+
+ <li>If you specify only one value for the <code>values...</code> parameter,
+ in one of the {@link android.animation.ObjectAnimator} factory methods, it is assumed to be
+ the ending value of the animation. Therefore, the object property that you are
+ animating must have a getter function that is used to obtain the starting value of
+ the animation. The getter function must be in the form of
+ <code>get&lt;propertyName&gt;()</code>. For example, if the property name is
+ <code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
+
+ <li>The getter (if needed) and setter methods of the property that you are animating must
+ return the same type as the starting and ending values that you specify to {@link
+ android.animation.ObjectAnimator}. For example, you must have
+ <code>targetObject.setPropName(float)</code> and
+ <code>targetObject.getPropName(float)</code> if you construct the following {@link
+ android.animation.ObjectAnimator}:
+ <pre>ObjectAnimator.ofFloat(targetObject, "propName", 1f)</pre>
+ </li>
+ </ul>
+
+ <h3 id="type-evaluator">Using the TypeEvaluator</h3>
+
+ <p>If you want to animate a type that is unknown to the Android system,
+ you can create your own evaluator by implementing the {@link
+ android.animation.TypeEvaluator} interface. The types that are known by the Android
+ system are <code>int</code>, <code>float</code>, or a color, which are supported by the
+ {@link android.animation.IntEvaluator}, {@link android.animation.FloatEvaluator}, and
+ {@link android.animation.ArgbEvaluator} type evaluators.</p>
+
+ <p>There is only one method to implement in the {@link android.animation.TypeEvaluator}
+ interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method.
+ This allows the animator that you are using to return an
+ appropriate value for your animated property at the current point of the animation. The
+ {@link android.animation.FloatEvaluator} class demonstrates how to do this:</p>
+ <pre>
+public class FloatEvaluator implements TypeEvaluator {
+
+ public Object evaluate(float fraction, Object startValue, Object endValue) {
+ float startFloat = ((Number) startValue).floatValue();
+ return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
+ }
+}
+</pre>
+
+ <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or
+ {@link android.animation.ObjectAnimator}) runs, it calculates a current elapsed
+ fraction of the animation (a value between 0 and 1) and then calculates an eased
+ version of that depending on what interpolator that you are using. The eased fraction
+ is what your {@link android.animation.TypeEvaluator} receives through the <code>fraction</code>
+ parameter, so you do not have to take into account the interpolator
+ when calculating animated values.</p>
+
+ <h3 id="interpolators">Using Interpolators</h3>
+
+ <p>An interpolator define how specific values in an animation are
+ calculated as a function of time. For example, you can specify animations to happen
+ linearly across the whole animation, meaning the animation moves evenly the entire
+ time, or you can specify animations to use non-linear time, for example, using
+ acceleration or deceleration at the beginning or end of the animation.</p>
+
+ <p>Interpolators in the animation system receive a fraction from Animators that represent the elapsed time
+ of the animation. Interpolators modify this fraction to coincide with the type of
+ animation that it aims to provide. The Android system provides a set of common
+ interpolators in the {@link android.view.animation android.view.animation package}. If
+ none of these suit your needs, you can implement the {@link
+ android.animation.TimeInterpolator} interface and create your own.</p>
+
+ <p>As an example, how the default interpolator {@link
+ android.view.animation.AccelerateDecelerateInterpolator} and the {@link
+ android.view.animation.LinearInterpolator} calculate eased fractions are compared below. The {@link
+ android.view.animation.LinearInterpolator} has no effect on the elapsed fraction,
+ because a linear interpolation is calculated the same way as the elapsed fraction. The
+ {@link android.view.animation.AccelerateDecelerateInterpolator} accelerates into the
+ animation and decelerates out of it. The following methods define the logic for these
+ interpolators:</p>
+
+ <p><strong>AccelerateDecelerateInterpolator</strong></p>
+ <pre>public float getInterpolation(float input) {
+ return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
+ }</pre>
+
+ <p><strong>LinearInterpolator</strong></p>
+ <pre>public float getInterpolation(float input) {
+ return input;
+ }</pre>
+
+ <p>The following table represents the approximate values that are calculated by these
+ interpolators for an animation that lasts 1000ms:</p>
+
+ <table>
+ <tr>
+ <th>ms elapsed</th>
+
+ <th>Elapsed fraction/Eased fraction (Linear)</th>
+
+ <th>Eased fraction (Accelerate/Decelerate)</th>
+ </tr>
+
+ <tr>
+ <td>0</td>
+
+ <td>0</td>
+
+ <td>0</td>
+ </tr>
+
+ <tr>
+ <td>200</td>
+
+ <td>.2</td>
+
+ <td>.1</td>
+ </tr>
+
+ <tr>
+ <td>400</td>
+
+ <td>.4</td>
+
+ <td>.345</td>
+ </tr>
+
+ <tr>
+ <td>600</td>
+
+ <td>.6</td>
+
+ <td>.8</td>
+ </tr>
+
+ <tr>
+ <td>800</td>
+
+ <td>.8</td>
+
+ <td>.9</td>
+ </tr>
+
+ <tr>
+ <td>1000</td>
+
+ <td>1</td>
+
+ <td>1</td>
+ </tr>
+ </table>
+
+ <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes
+ the values at the same speed, .2 for every 200ms that passes. The {@link
+ android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than
+ {@link android.view.animation.LinearInterpolator} between 200ms and 600ms and slower
+ between 600ms and 1000ms.</p>
+
+ <h3 id="keyframes">Specifying Keyframes</h3>
+
+ <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets
+ you define a specific state at a specific time of an animation. Each keyframe can also
+ have its own interpolator to control the behavior of the animation in the interval
+ between the previous keyframe's time and the time of this keyframe.</p>
+
+ <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the
+ factory methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
+ android.animation.Keyframe#ofFloat ofFloat()}, or {@link
+ android.animation.Keyframe#ofObject ofObject()} to obtain the appropriate type of
+ {@link android.animation.Keyframe}. You then call the {@link
+ android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
+ obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the
+ object, you can obtain an animator by passing in the {@link
+ android.animation.PropertyValuesHolder} object and the object to animate. The following
+ code snippet demonstrates how to do this:</p>
+ <pre>
+ Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+ Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
+ Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+ PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
+ ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
+ rotationAnim.setDuration(5000ms);
+
+</pre>For a more complete example on how to use keyframes, see the <a href=
+"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
+ MultiPropertyAnimation</a> sample in APIDemos.
+
+ <h3 id="choreography">Choreographing multiple animations with Animator Sets</h3>
+
+ <p>In many cases, you want to play an animation that depends on when another animation
+ starts or finishes. The Android system lets you bundle animations together into an
+ {@link android.animation.AnimatorSet}, so that you can specify whether to start animations
+ simultaneously, sequentially, or after a specified delay. You can also nest {@link
+ android.animation.AnimatorSet} objects within each other.</p>
+
+ <p>The following sample code taken from the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample (modified for simplicity) plays the following
+ {@link android.animation.Animator} objects in the following manner:</p>
+
+ <ol>
+ <li>Plays <code>bounceAnim</code>.</li>
+
+ <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>,
+ <code>stretchAnim1</code>, and <code>stretchAnim2</code> at the same time.</li>
+
+ <li>Plays <code>bounceBackAnim</code>.</li>
+
+ <li>Plays <code>fadeAnim</code>.</li>
+ </ol>
+ <pre>AnimatorSet bouncer = new AnimatorSet();
+bouncer.play(bounceAnim).before(squashAnim1);
+bouncer.play(squashAnim1).with(squashAnim2);
+bouncer.play(squashAnim1).with(stretchAnim1);
+bouncer.play(squashAnim1).with(stretchAnim2);
+bouncer.play(bounceBackAnim).after(stretchAnim2);
+ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+AnimatorSet animatorSet = new AnimatorSet();
+animatorSet.play(bouncer).before(fadeAnim);
+animatorSet.start();
+</pre>
+
+ <p>For a more complete example on how to use animator sets, see the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample in APIDemos.</p>
+
+ <h3 id="declaring-xml">Declaring animations in XML</h3>
+
+ <p>As with <a href="view-animation">view animation</a>, you can declare property animations with
+ XML instead of doing it programmatically. The following Android classes also have XML
+ declaration support with the following XML tags:</p>
+
+ <ul>
+ <li>{@link android.animation.ValueAnimator} - <code>&lt;animator&gt;</code></li>
+
+ <li>{@link android.animation.ObjectAnimator} - <code>&lt;objectAnimator&gt;</code></li>
+
+ <li>{@link android.animation.AnimatorSet} - <code>&lt;AnimatorSet&gt;</code></li>
+ </ul>
+
+ <p>Both <code>&lt;animator&gt;</code> ({@link android.animation.ValueAnimator}) and
+ <code>&lt;objectAnimator&gt;</code> ({@link android.animation.ObjectAnimator}) have the
+ following attributes:</p>
+
+ <dl>
+ <dt><code>android:duration</code></dt>
+ <dd>The number of milliseconds that the animation runs.</dd>
+
+ <dt><code>android:valueFrom</code> and <code>android:valueTo</code></dt>
+ <dd>The values being animated
+ between. These are restricted to numbers (<code>float</code> or <code>int</code>) in
+ XML. They can be <code>float</code>, <code>int</code>, or any kind of
+ <code>Object</code> when creating animations programmatically.</dd>
+
+ <dt><code>android:valueType</code></dt>
+ <dd>Set to either <code>"floatType"</code> or <code>"intType"</code>.</dd>
+
+ <dt><code>android:startDelay</code></dt>
+ <dd>The delay, in milliseconds, before the animation begins
+ playing (after calling {@link android.animation.ValueAnimator#start start()}).</dd>
+
+ <dt><code>android:repeatCount</code></dt>
+ <dd>How many times to repeat an animation. Set to
+ <code>"-1"</code> for infinite repeating or to a positive integer. For example, a value of
+ <code>"1"</code> means that the animation is repeated once after the initial run of the
+ animation, so the animation plays a total of two times. The default value is
+ <code>"0"</code>.</dd>
+
+ <dt><code>android:repeatMode</code></dt>
+ <dd>How an animation behaves when it reaches the end of the
+ animation. <code>android:repeatCount</code> must be set to a positive integer or
+ <code>"-1"</code> for this attribute to have an effect. Set to <code>"reverse"</code> to
+ have the animation reverse direction with each iteration or <code>"repeat"</code> to
+ have the animation loop from the beginning each time.</dd>
+ </dl>
+
+ <p>The <code>objectAnimator</code> ({@link android.animation.ObjectAnimator}) element has the
+ additional attribute <code>propertyName</code>, that lets you specify the name of the
+ property being animated. The <code>objectAnimator</code> element does not expose a
+ <code>target</code> attribute, however, so you cannot set the object to animate in the
+ XML declaration. You have to inflate the XML resource by calling
+ {@link android.animation.AnimatorInflater#loadAnimator loadAnimator()} and call
+ {@link android.animation.ObjectAnimator#setTarget setTarget()} to set the target object, before calling
+ {@link android.animation.ObjectAnimator#start start()}.</p>
+
+ <p>The <code>set</code> element ({@link android.animation.AnimatorSet}) exposes a single
+ attribute, <code>ordering</code>. Set this attribute to <code>together</code> (default)
+ to play all the animations in this set at once. Set this attribute to
+ <code>sequentially</code> to play the animations in the order they are declared.</p>
+
+ <p>You can specify nested <code>set</code> tags to further group animations together.
+ The animations that you want to group together should be children of the
+ <code>set</code> tag and can define their own <code>ordering</code> attribute.</p>
+
+ <p>As an example, this XML code creates an {@link android.animation.AnimatorSet} object
+ that animates x and y at the same time (<code>together</code> is the default ordering
+ when nothing is specified), then runs an animation that fades an object out:</p>
+ <pre>&lt;set android:ordering="sequentially"&gt;
+ &lt;set&gt;
+ &lt;objectAnimator
+ android:propertyName="x"
+ android:duration="500"
+ android:valueTo="400"
+ android:valueType="int"/&gt;
+ &lt;objectAnimator
+ android:propertyName="y"
+ android:duration="500"
+ android:valueTo="300"
+ android:valueType="int" &gt;
+ &lt;/set&gt;
+ &lt;objectAnimator
+ android:propertyName="alpha"
+ android:duration="500"
+ android:valueTo="0f"/&gt;
+ &lt;/set&gt;
+</pre>
+
+ <p>In order to run this animation, you must inflate the XML resources in your code to
+ an {@link android.animation.AnimatorSet} object, and then set the target objects for all of
+ the animations before starting the animation set. Calling {@link
+ android.animation.AnimatorSet#setTarget setTarget()} sets a single target object for
+ all children of the {@link android.animation.AnimatorSet}.</p>
+
+ <h2 id="view-animation">View Animation</h2>You can use View Animation in any View
+ object to perform tweened animation and frame by frame animation. Tween animation
+ calculates the animation given information such as the start point, end point, size,
+ rotation, and other common aspects of an animation. Frame by frame animation lets you
+ load a series of Drawable resources one after another to create an animation.
+
+ <h3 id="tween-animation">Tween Animation</h3>
+
+ <p>A tween animation can perform a series of simple transformations (position, size,
+ rotation, and transparency) on the contents of a View object. So, if you have a
+ {@link android.widget.TextView} object, you can move, rotate, grow, or shrink the text. If it has a background
+ image, the background image will be transformed along with the text. The {@link
+ android.view.animation animation package} provides all the classes used in a tween
+ animation.</p>
+
+ <p>A sequence of animation instructions defines the tween animation, defined by either
+ XML or Android code. As with defining a layout, an XML file is recommended because it's
+ more readable, reusable, and swappable than hard-coding the animation. In the example
+ below, we use XML. (To learn more about defining an animation in your application code,
+ instead of XML, refer to the {@link android.view.animation.AnimationSet} class and
+ other {@link android.view.animation.Animation} subclasses.)</p>
+
+ <p>The animation instructions define the transformations that you want to occur, when
+ they will occur, and how long they should take to apply. Transformations can be
+ sequential or simultaneous &mdash; for example, you can have the contents of a TextView
+ move from left to right, and then rotate 180 degrees, or you can have the text move and
+ rotate simultaneously. Each transformation takes a set of parameters specific for that
+ transformation (starting size and ending size for size change, starting angle and
+ ending angle for rotation, and so on), and also a set of common parameters (for
+ instance, start time and duration). To make several transformations happen
+ simultaneously, give them the same start time; to make them sequential, calculate the
+ start time plus the duration of the preceding transformation.</p>
+
+ <p>The animation XML file belongs in the <code>res/anim/</code> directory of your
+ Android project. The file must have a single root element: this will be either a single
+ <code>&lt;alpha&gt;</code>, <code>&lt;scale&gt;</code>, <code>&lt;translate&gt;</code>,
+ <code>&lt;rotate&gt;</code>, interpolator element, or <code>&lt;set&gt;</code> element
+ that holds groups of these elements (which may include another
+ <code>&lt;set&gt;</code>). By default, all animation instructions are applied
+ simultaneously. To make them occur sequentially, you must specify the
+ <code>startOffset</code> attribute, as shown in the example below.</p>
+
+ <p>The following XML from one of the ApiDemos is used to stretch, then simultaneously
+ spin and rotate a View object.</p>
+ <pre>
+&lt;set android:shareInterpolator="false"&gt;
+ &lt;scale
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:fromXScale="1.0"
+ android:toXScale="1.4"
+ android:fromYScale="1.0"
+ android:toYScale="0.6"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillAfter="false"
+ android:duration="700" /&gt;
+ &lt;set android:interpolator="@android:anim/decelerate_interpolator"&gt;
+ &lt;scale
+ android:fromXScale="1.4"
+ android:toXScale="0.0"
+ android:fromYScale="0.6"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400"
+ android:fillBefore="false" /&gt;
+ &lt;rotate
+ android:fromDegrees="0"
+ android:toDegrees="-45"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400" /&gt;
+ &lt;/set&gt;
+&lt;/set&gt;
+</pre>
+
+ <p>Screen coordinates (not used in this example) are (0,0) at the upper left hand
+ corner, and increase as you go down and to the right.</p>
+
+ <p>Some values, such as pivotX, can be specified relative to the object itself or
+ relative to the parent. Be sure to use the proper format for what you want ("50" for
+ 50% relative to the parent, or "50%" for 50% relative to itself).</p>
+
+ <p>You can determine how a transformation is applied over time by assigning an {@link
+ android.view.animation.Interpolator}. Android includes several Interpolator subclasses
+ that specify various speed curves: for instance, {@link
+ android.view.animation.AccelerateInterpolator} tells a transformation to start slow and
+ speed up. Each one has an attribute value that can be applied in the XML.</p>
+
+ <p>With this XML saved as <code>hyperspace_jump.xml</code> in the
+ <code>res/anim/</code> directory of the project, the following code will reference
+ it and apply it to an {@link android.widget.ImageView} object from the layout.</p>
+ <pre>
+ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
+Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
+spaceshipImage.startAnimation(hyperspaceJumpAnimation);
+</pre>
+
+ <p>As an alternative to <code>startAnimation()</code>, you can define a starting time
+ for the animation with <code>{@link android.view.animation.Animation#setStartTime(long)
+ Animation.setStartTime()}</code>, then assign the animation to the View with
+ <code>{@link android.view.View#setAnimation(android.view.animation.Animation)
+ View.setAnimation()}</code>.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+
+ <p class="note"><strong>Note:</strong> Regardless of how your animation may move or
+ resize, the bounds of the View that holds your animation will not automatically adjust
+ to accommodate it. Even so, the animation will still be drawn beyond the bounds of its
+ View and will not be clipped. However, clipping <em>will occur</em> if the animation
+ exceeds the bounds of the parent View.</p>
+
+ <h3 id="frame-animation">Frame Animation</h3>
+
+ <p>This is a traditional animation in the sense that it is created with a sequence of
+ different images, played in order, like a roll of film. The {@link
+ android.graphics.drawable.AnimationDrawable} class is the basis for frame
+ animations.</p>
+
+ <p>While you can define the frames of an animation in your code, using the {@link
+ android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished
+ with a single XML file that lists the frames that compose the animation. Like the tween
+ animation above, the XML file for this kind of animation belongs in the
+ <code>res/drawable/</code> directory of your Android project. In this case, the
+ instructions are the order and duration for each frame of the animation.</p>
+
+ <p>The XML file consists of an <code>&lt;animation-list&gt;</code> element as the root
+ node and a series of child <code>&lt;item&gt;</code> nodes that each define a frame: a
+ drawable resource for the frame and the frame duration. Here's an example XML file for
+ a frame-by-frame animation:</p>
+ <pre>
+&lt;animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="true"&gt;
+ &lt;item android:drawable="@drawable/rocket_thrust1" android:duration="200" /&gt;
+ &lt;item android:drawable="@drawable/rocket_thrust2" android:duration="200" /&gt;
+ &lt;item android:drawable="@drawable/rocket_thrust3" android:duration="200" /&gt;
+&lt;/animation-list&gt;
+</pre>
+
+ <p>This animation runs for just three frames. By setting the
+ <code>android:oneshot</code> attribute of the list to <var>true</var>, it will cycle
+ just once then stop and hold on the last frame. If it is set <var>false</var> then the
+ animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the
+ <code>res/drawable/</code> directory of the project, it can be added as the background
+ image to a View and then called to play. Here's an example Activity, in which the
+ animation is added to an {@link android.widget.ImageView} and then animated when the
+ screen is touched:</p>
+ <pre>
+AnimationDrawable rocketAnimation;
+
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
+ rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
+ rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
+}
+
+public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ rocketAnimation.start();
+ return true;
+ }
+ return super.onTouchEvent(event);
+}
+</pre>
+
+ <p>It's important to note that the <code>start()</code> method called on the
+ AnimationDrawable cannot be called during the <code>onCreate()</code> method of your
+ Activity, because the AnimationDrawable is not yet fully attached to the window. If you
+ want to play the animation immediately, without requiring interaction, then you might
+ want to call it from the <code>{@link
+ android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code>
+ method in your Activity, which will get called when Android brings your window into
+ focus.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p> \ No newline at end of file
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 221406c459f3..11964da3f537 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -343,7 +343,27 @@ var ANDROID_RESOURCES = [
///////////////////
/// SAMPLE CODE ///
///////////////////
-
+
+ {
+ tags: ['sample'],
+ path: 'samples/AccelerometerPlay/index.html',
+ title: {
+ en: 'Accelerometer Play'
+ },
+ description: {
+ en: ''
+ }
+ },
+ {
+ tags: ['sample'],
+ path: 'samples/AccessibilityService/index.html',
+ title: {
+ en: 'Accessibility Service'
+ },
+ description: {
+ en: 'Illustrates an accessibility service that provides custom feedback for the Clock application which comes by default with Android devices'
+ }
+ },
{
tags: ['sample', 'layout', 'ui'],
path: 'samples/ApiDemos/index.html',
@@ -355,7 +375,7 @@ var ANDROID_RESOURCES = [
}
},
{
- tags: ['sample', 'data', 'newfeature', 'accountsync', 'new'],
+ tags: ['sample', 'data', 'newfeature', 'accountsync'],
path: 'samples/BackupRestore/index.html',
title: {
en: 'Backup and Restore'
@@ -395,6 +415,16 @@ var ANDROID_RESOURCES = [
}
},
{
+ tags: ['sample', 'ui'],
+ path: 'samples/CubeLiveWallpaper/index.html',
+ title: {
+ en: 'Cube Live Wallpaper'
+ },
+ description: {
+ en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.'
+ }
+ },
+ {
tags: ['sample'],
path: 'samples/Home/index.html',
title: {
@@ -405,23 +435,23 @@ var ANDROID_RESOURCES = [
}
},
{
- tags: ['sample', 'gamedev', 'media'],
- path: 'samples/JetBoy/index.html',
+ tags: ['sample', 'new'],
+ path: 'samples/Honeycomb-Gallery/index.html',
title: {
- en: 'JetBoy'
+ en: 'Honeycomb Gallery'
},
description: {
- en: 'A game that demonstrates the SONiVOX JET interactive music technology, with <code><a href="/reference/android/media/JetPlayer.html">JetPlayer</a></code>.'
+ en: 'An image gallery application using Honeycomb-specific APIs.'
}
},
{
- tags: ['sample', 'ui', 'newfeature'],
- path: 'samples/CubeLiveWallpaper/index.html',
+ tags: ['sample', 'gamedev', 'media'],
+ path: 'samples/JetBoy/index.html',
title: {
- en: 'Live Wallpaper'
+ en: 'JetBoy'
},
description: {
- en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.'
+ en: 'A game that demonstrates the SONiVOX JET interactive music technology, with <code><a href="/reference/android/media/JetPlayer.html">JetPlayer</a></code>.'
}
},
{
@@ -446,6 +476,16 @@ var ANDROID_RESOURCES = [
},
{
tags: ['sample', 'data'],
+ path: 'samples/NFCDemo/index.html',
+ title: {
+ en: 'NFC Demo'
+ },
+ description: {
+ en: 'An application for reading NFC Forum Type 2 Tags using the NFC APIs'
+ }
+ },
+ {
+ tags: ['sample', 'data'],
path: 'samples/NotePad/index.html',
title: {
en: 'Note Pad'
@@ -475,6 +515,16 @@ var ANDROID_RESOURCES = [
}
},
{
+ tags: ['sample'],
+ path: 'samples/SipDemo/index.html',
+ title: {
+ en: 'SIP Demo'
+ },
+ description: {
+ en: 'A demo application highlighting how to make internet-based calls with the SIP API.'
+ }
+ },
+ {
tags: ['sample', 'layout', 'ui'],
path: 'samples/Snake/index.html',
title: {
@@ -485,6 +535,16 @@ var ANDROID_RESOURCES = [
}
},
{
+ tags: ['sample', 'input'],
+ path: 'samples/SoftKeyboard/index.html',
+ title: {
+ en: 'Soft Keyboard'
+ },
+ description: {
+ en: 'An example of writing an input method for a software keyboard.'
+ }
+ },
+ {
tags: ['sample', 'testing'],
path: 'samples/Spinner/index.html',
title: {
@@ -525,16 +585,6 @@ var ANDROID_RESOURCES = [
}
},
{
- tags: ['sample', 'input'],
- path: 'samples/SoftKeyboard/index.html',
- title: {
- en: 'Soft Keyboard'
- },
- description: {
- en: 'An example of writing an input method for a software keyboard.'
- }
- },
- {
tags: ['sample', 'ui'],
path: 'samples/Wiktionary/index.html',
title: {
@@ -555,7 +605,7 @@ var ANDROID_RESOURCES = [
}
},
{
- tags: ['sample', 'layout', 'new'],
+ tags: ['sample', 'layout'],
path: 'samples/XmlAdapters/index.html',
title: {
en: 'XML Adapters'
diff --git a/docs/html/resources/samples/images/NfcDemo.png b/docs/html/resources/samples/images/NfcDemo.png
new file mode 100644
index 000000000000..c175d12b5d7e
--- /dev/null
+++ b/docs/html/resources/samples/images/NfcDemo.png
Binary files differ
diff --git a/docs/html/resources/samples/images/hcgallery.png b/docs/html/resources/samples/images/hcgallery.png
new file mode 100644
index 000000000000..9a80fd77ad9b
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery.png
Binary files differ
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 75edac6b6f59..ddbd220795e1 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -382,7 +382,7 @@ status_t BpDrmManagerService::setPlaybackStatus(
}
data.writeInt32(playbackStatus);
- data.writeInt32(position);
+ data.writeInt64(position);
remote()->transact(SET_PLAYBACK_STATUS, data, &reply);
return reply.readInt32();
@@ -1111,7 +1111,7 @@ status_t BnDrmManagerService::onTransact(
}
const status_t status
- = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt32());
+ = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt64());
reply->writeInt32(status);
delete handle.decryptInfo; handle.decryptInfo = NULL;
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index e5408068e64f..27ea0f03d97a 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -287,6 +287,10 @@ public class Region implements Parcelable {
region2.mNativeRegion, op.nativeInt);
}
+ public String toString() {
+ return nativeToString(mNativeRegion);
+ }
+
//////////////////////////////////////////////////////////////////////////
public static final Parcelable.Creator<Region> CREATOR
@@ -357,6 +361,8 @@ public class Region implements Parcelable {
return mNativeRegion;
}
+ private static native boolean nativeEquals(int native_r1, int native_r2);
+
private static native int nativeConstructor();
private static native void nativeDestructor(int native_region);
@@ -381,5 +387,5 @@ public class Region implements Parcelable {
private static native boolean nativeWriteToParcel(int native_region,
Parcel p);
- private static native boolean nativeEquals(int native_r1, int native_r2);
+ private static native String nativeToString(int native_region);
}
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 1789891d73e5..74cdf80a9294 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -268,22 +268,105 @@ public class Allocation extends BaseObj {
}
}
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(int[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(short[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(byte[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(float[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 32 bit integer type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(int[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 16 bit integer type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(short[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 8 bit integer type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(byte[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 32 bit float type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(float[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from a bitmap. The height, width, and
+ * format of the bitmap must match the existing allocation.
+ *
+ * @param b the source bitmap
+ */
public void copyFrom(Bitmap b) {
mRS.validate();
validateBitmapSize(b);
@@ -369,39 +452,114 @@ public class Allocation extends BaseObj {
mRS.nAllocationGenerateMipmaps(getID());
}
- void copy1DRangeFromUnchecked(int off, int count, int[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- void copy1DRangeFromUnchecked(int off, int count, short[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 2, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- void copy1DRangeFromUnchecked(int off, int count, float[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 32 bit integer type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, int[] d) {
validateIsInt32();
copy1DRangeFromUnchecked(off, count, d);
}
+
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 16 bit integer type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, short[] d) {
validateIsInt16();
copy1DRangeFromUnchecked(off, count, d);
}
+
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 8 bit integer type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, byte[] d) {
validateIsInt8();
copy1DRangeFromUnchecked(off, count, d);
}
+
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 32 bit float type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, float[] d) {
validateIsFloat32();
copy1DRangeFromUnchecked(off, count, d);
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index ff8f09323503..94452834623f 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -56,6 +56,9 @@ public class ScriptC extends Script {
protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
super(0, rs);
int id = internalCreate(rs, resources, resourceID);
+ if (id == 0) {
+ throw new RSRuntimeException("Loading of ScriptC script failed.");
+ }
setID(id);
}
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 9d589cf9988a..eb599b590e2d 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -105,7 +105,7 @@ public:
volatile int32_t head; // server's current front buffer
volatile int32_t available; // number of dequeue-able buffers
volatile int32_t queued; // number of buffers waiting for post
- volatile int32_t inUse; // buffer currently in use by SF
+ volatile int32_t reserved1;
volatile status_t status; // surface's status code
// not part of the conditions
@@ -275,7 +275,6 @@ public:
int32_t identity);
ssize_t retireAndLock();
- status_t unlock(int buffer);
void setStatus(status_t status);
status_t reallocateAll();
status_t reallocateAllExcept(int buffer);
@@ -356,12 +355,6 @@ private:
inline const char* name() const { return "BuffersAvailableCondition"; }
};
- struct UnlockUpdate : public UpdateBase {
- const int lockedBuffer;
- inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
- inline ssize_t operator()();
- };
-
struct RetireUpdate : public UpdateBase {
const int numBuffers;
inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 27f65bce8832..30b45f766bc5 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -38,6 +38,15 @@ enum {
AKEY_EVENT_FLAG_START_TRACKING = 0x40000000
};
+enum {
+ /*
+ * Indicates that an input device has switches.
+ * This input source flag is hidden from the API because switches are only used by the system
+ * and applications have no way to interact with them.
+ */
+ AINPUT_SOURCE_SWITCH = 0x80000000,
+};
+
/*
* Maximum number of pointers supported per motion event.
* Smallest number of pointers is 1.
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index ef1957928117..c6501417713e 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -29,12 +29,8 @@ import java.security.KeyPair;
public class Credentials {
private static final String LOGTAG = "Credentials";
- public static final String UNLOCK_ACTION = "android.credentials.UNLOCK";
-
public static final String INSTALL_ACTION = "android.credentials.INSTALL";
- public static final String SYSTEM_INSTALL_ACTION = "android.credentials.SYSTEM_INSTALL";
-
/** Key prefix for CA certificates. */
public static final String CA_CERTIFICATE = "CACERT_";
@@ -73,7 +69,7 @@ public class Credentials {
public void unlock(Context context) {
try {
- Intent intent = new Intent(UNLOCK_ACTION);
+ Intent intent = new Intent("com.android.credentials.UNLOCK");
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w(LOGTAG, e.toString());
@@ -107,12 +103,4 @@ public class Credentials {
Log.w(LOGTAG, e.toString());
}
}
-
- public void installFromSdCard(Context context) {
- try {
- context.startActivity(createInstallIntent());
- } catch (ActivityNotFoundException e) {
- Log.w(LOGTAG, e.toString());
- }
- }
}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index c49be9373135..38e0848d5b54 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -23,6 +23,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
Program.cpp \
ProgramCache.cpp \
ResourceCache.cpp \
+ ShapeCache.cpp \
SkiaColorFilter.cpp \
SkiaShader.cpp \
TextureCache.cpp \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index fde4f966c7b1..bffab958378f 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -73,6 +73,10 @@ void Caches::dumpMemoryUsage() {
LOGD(" LayerCache %8d / %8d", layerCache.getSize(), layerCache.getMaxSize());
LOGD(" GradientCache %8d / %8d", gradientCache.getSize(), gradientCache.getMaxSize());
LOGD(" PathCache %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
+ LOGD(" CircleShapeCache %8d / %8d",
+ circleShapeCache.getSize(), circleShapeCache.getMaxSize());
+ LOGD(" RoundRectShapeCache %8d / %8d",
+ roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
LOGD(" TextDropShadowCache %8d / %8d", dropShadowCache.getSize(),
dropShadowCache.getMaxSize());
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index a11b6bc1ec08..aa0ceb707451 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -31,6 +31,7 @@
#include "GradientCache.h"
#include "PatchCache.h"
#include "ProgramCache.h"
+#include "ShapeCache.h"
#include "PathCache.h"
#include "TextDropShadowCache.h"
#include "FboCache.h"
@@ -159,6 +160,8 @@ public:
GradientCache gradientCache;
ProgramCache programCache;
PathCache pathCache;
+ RoundRectShapeCache roundRectShapeCache;
+ CircleShapeCache circleShapeCache;
PatchCache patchCache;
TextDropShadowCache dropShadowCache;
FboCache fboCache;
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 71ec7609f0d0..62366845e7a1 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -42,8 +42,8 @@
// This flag requires DEBUG_PATCHES to be turned on
#define DEBUG_PATCHES_EMPTY_VERTICES 0
-// Turn on to display debug info about paths
-#define DEBUG_PATHS 0
+// Turn on to display debug info about shapes
+#define DEBUG_SHAPES 0
// Turn on to display debug info about textures
#define DEBUG_TEXTURES 0
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ade85e5b4852..a74a95fc28b8 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -103,6 +103,8 @@ const char* DisplayList::OP_NAMES[] = {
"DrawPatch",
"DrawColor",
"DrawRect",
+ "DrawRoundRect",
+ "DrawCircle",
"DrawPath",
"DrawLines",
"DrawText",
@@ -332,6 +334,15 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
}
break;
+ case DrawRoundRect: {
+ renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
+ getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case DrawCircle: {
+ renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
+ }
+ break;
case DrawPath: {
renderer.drawPath(getPath(), getPaint());
}
@@ -601,6 +612,21 @@ void DisplayListRenderer::drawRect(float left, float top, float right, float bot
addPaint(paint);
}
+void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint) {
+ addOp(DisplayList::DrawRoundRect);
+ addBounds(left, top, right, bottom);
+ addPoint(rx, ry);
+ addPaint(paint);
+}
+
+void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ addOp(DisplayList::DrawCircle);
+ addPoint(x, y);
+ addFloat(radius);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
addOp(DisplayList::DrawPath);
addPath(path);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 05864ec8ad6f..4b727f68fdf1 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -110,6 +110,8 @@ public:
DrawPatch,
DrawColor,
DrawRect,
+ DrawRoundRect,
+ DrawCircle,
DrawPath,
DrawLines,
DrawText,
@@ -270,6 +272,9 @@ public:
float left, float top, float right, float bottom, SkPaint* paint);
void drawColor(int color, SkXfermode::Mode mode);
void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ void drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint);
+ void drawCircle(float x, float y, float radius, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
void drawLines(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index c080501df338..c43e40dfcedd 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -298,8 +298,10 @@ Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize,
// FontRenderer
///////////////////////////////////////////////////////////////////////////////
+static bool sLogFontRendererCreate = true;
+
FontRenderer::FontRenderer() {
- LOGD("Creating FontRenderer");
+ if (sLogFontRendererCreate) LOGD("Creating FontRenderer");
mGammaTable = NULL;
mInitialized = false;
@@ -317,18 +319,24 @@ FontRenderer::FontRenderer() {
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
- LOGD(" Setting text cache width to %s pixels", property);
+ if (sLogFontRendererCreate) LOGD(" Setting text cache width to %s pixels", property);
mCacheWidth = atoi(property);
} else {
- LOGD(" Using default text cache width of %i pixels", mCacheWidth);
+ if (sLogFontRendererCreate) {
+ LOGD(" Using default text cache width of %i pixels", mCacheWidth);
+ }
}
if (property_get(PROPERTY_TEXT_CACHE_HEIGHT, property, NULL) > 0) {
- LOGD(" Setting text cache width to %s pixels", property);
+ if (sLogFontRendererCreate) LOGD(" Setting text cache width to %s pixels", property);
mCacheHeight = atoi(property);
} else {
- LOGD(" Using default text cache height of %i pixels", mCacheHeight);
+ if (sLogFontRendererCreate) {
+ LOGD(" Using default text cache height of %i pixels", mCacheHeight);
+ }
}
+
+ sLogFontRendererCreate = false;
}
FontRenderer::~FontRenderer() {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e6bea786dfdc..a16742982f61 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -29,7 +29,6 @@ namespace uirenderer {
void LayerRenderer::prepare(bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
- glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo);
glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
OpenGLRenderer::prepare(opaque);
@@ -37,11 +36,17 @@ void LayerRenderer::prepare(bool opaque) {
void LayerRenderer::finish() {
OpenGLRenderer::finish();
- glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo);
generateMesh();
LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->mFbo);
+
+ // No need to unbind our FBO, this will be taken care of by the caller
+ // who will invoke OpenGLRenderer::resume()
+}
+
+GLint LayerRenderer::getTargetFbo() {
+ return mLayer->fbo;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index f2fb898b21c7..1e398470a082 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -51,6 +51,7 @@ public:
bool hasLayer();
Region* getRegion();
+ GLint getTargetFbo();
static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
@@ -61,8 +62,6 @@ private:
void generateMesh();
Layer* mLayer;
- GLuint mPreviousFbo;
-
}; // class LayerRenderer
}; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2067acc1803c..9528dbbfdafb 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -200,7 +200,7 @@ void OpenGLRenderer::resume() {
glDisable(GL_DITHER);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
mCaches.blend = true;
@@ -430,18 +430,18 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
} else {
// Copy the framebuffer into the layer
glBindTexture(GL_TEXTURE_2D, layer->texture);
-
- if (layer->empty) {
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
- snapshot->height - bounds.bottom, layer->width, layer->height, 0);
- layer->empty = false;
- } else {
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
- snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+ if (!bounds.isEmpty()) {
+ if (layer->empty) {
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
+ snapshot->height - bounds.bottom, layer->width, layer->height, 0);
+ layer->empty = false;
+ } else {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
+ snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+ }
+ // Enqueue the buffer coordinates to clear the corresponding region later
+ mLayers.push(new Rect(bounds));
}
-
- // Enqueue the buffer coordinates to clear the corresponding region later
- mLayers.push(new Rect(bounds));
}
return true;
@@ -565,8 +565,10 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
resetColorFilter();
}
} else {
- dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
- composeLayerRect(layer, rect, true);
+ if (!rect.isEmpty()) {
+ dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
+ composeLayerRect(layer, rect, true);
+ }
}
if (fboLayer) {
@@ -1303,6 +1305,38 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
+void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ glActiveTexture(gTextureUnits[0]);
+
+ const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
+ right - left, bottom - top, rx, ry, paint);
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+
+ const float x = left + texture->left - texture->offset;
+ const float y = top + texture->top - texture->offset;
+
+ drawPathTexture(texture, x, y, paint);
+}
+
+void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ glActiveTexture(gTextureUnits[0]);
+
+ const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+
+ const float left = (x - radius) + texture->left - texture->offset;
+ const float top = (y - radius) + texture->top - texture->offset;
+
+ drawPathTexture(texture, left, top, paint);
+}
+
void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
if (quickReject(left, top, right, bottom)) {
return;
@@ -1451,8 +1485,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
- GLuint textureUnit = 0;
- glActiveTexture(gTextureUnits[textureUnit]);
+ glActiveTexture(gTextureUnits[0]);
const PathTexture* texture = mCaches.pathCache.get(path, paint);
if (!texture) return;
@@ -1461,31 +1494,7 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
const float x = texture->left - texture->offset;
const float y = texture->top - texture->offset;
- if (quickReject(x, y, x + texture->width, y + texture->height)) {
- return;
- }
-
- int alpha;
- SkXfermode::Mode mode;
- getAlphaAndMode(paint, &alpha, &mode);
-
- setupDraw();
- setupDrawWithTexture(true);
- setupDrawAlpha8Color(paint->getColor(), alpha);
- setupDrawColorFilter();
- setupDrawShader();
- setupDrawBlending(true, mode);
- setupDrawProgram();
- setupDrawModelView(x, y, x + texture->width, y + texture->height);
- setupDrawTexture(texture->id);
- setupDrawPureColorUniforms();
- setupDrawColorFilterUniforms();
- setupDrawShaderUniforms();
- setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
-
- finishDrawTexture();
+ drawPathTexture(texture, x, y, paint);
}
void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
@@ -1581,6 +1590,35 @@ void OpenGLRenderer::setupShadow(float radius, float dx, float dy, int color) {
// Drawing implementation
///////////////////////////////////////////////////////////////////////////////
+void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
+ float x, float y, SkPaint* paint) {
+ if (quickReject(x, y, x + texture->width, y + texture->height)) {
+ return;
+ }
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ setupDraw();
+ setupDrawWithTexture(true);
+ setupDrawAlpha8Color(paint->getColor(), alpha);
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(true, mode);
+ setupDrawProgram();
+ setupDrawModelView(x, y, x + texture->width, y + texture->height);
+ setupDrawTexture(texture->id);
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawShaderUniforms();
+ setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
+ finishDrawTexture();
+}
+
// Same values used by Skia
#define kStdStrikeThru_Offset (-6.0f / 21.0f)
#define kStdUnderline_Offset (1.0f / 9.0f)
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 272c5c249b04..a43660b190bd 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -107,6 +107,9 @@ public:
float left, float top, float right, float bottom, SkPaint* paint);
virtual void drawColor(int color, SkXfermode::Mode mode);
virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint);
+ virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
virtual void drawPath(SkPath* path, SkPaint* paint);
virtual void drawLines(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
@@ -145,14 +148,27 @@ protected:
return mSnapshot;
}
+ /**
+ * Returns the region of the current layer.
+ */
virtual Region* getRegion() {
return mSnapshot->region;
}
+ /**
+ * Indicates whether rendering is currently targeted at a layer.
+ */
virtual bool hasLayer() {
return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
}
+ /**
+ * Returns the name of the FBO this renderer is rendering into.
+ */
+ virtual GLint getTargetFbo() {
+ return 0;
+ }
+
private:
/**
* Saves the current state of the renderer as a new snapshot.
@@ -330,6 +346,8 @@ private:
void drawTextDecorations(const char* text, int bytesCount, float length,
float x, float y, SkPaint* paint);
+ void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
+
/**
* Resets the texture coordinates stored in mMeshVertices. Setting the values
* back to default is achieved by calling:
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 999e4eacaba2..11eb953907ca 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -167,10 +167,6 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
if (stepY > 0.0f) {
- if (i == mYCount - 1 && mYDivs[i] == bitmapHeight) {
- y2 = bottom - top;
- v2 = 1.0f;
- }
generateRow(vertex, y1, y2, v1, v2, stretchX, right - left,
bitmapWidth, quadCount);
}
@@ -222,10 +218,6 @@ void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, fl
float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
if (stepX > 0.0f) {
- if (i == mXCount - 1 && mXDivs[i] == bitmapWidth) {
- x2 = bitmapWidth;
- u2 = 1.0f;
- }
generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount);
}
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 3184598d48c4..28c302e68de8 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -16,11 +16,6 @@
#define LOG_TAG "OpenGLRenderer"
-#include <GLES2/gl2.h>
-
-#include <SkCanvas.h>
-#include <SkRect.h>
-
#include <utils/threads.h>
#include "PathCache.h"
@@ -30,87 +25,11 @@ namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-PathCache::PathCache():
- mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(MB(DEFAULT_PATH_CACHE_SIZE)) {
- char property[PROPERTY_VALUE_MAX];
- if (property_get(PROPERTY_PATH_CACHE_SIZE, property, NULL) > 0) {
- LOGD(" Setting path cache size to %sMB", property);
- setMaxSize(MB(atof(property)));
- } else {
- LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE);
- }
- init();
-}
-
-PathCache::PathCache(uint32_t maxByteSize):
- mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(maxByteSize) {
- init();
-}
-
-PathCache::~PathCache() {
- mCache.clear();
-}
-
-void PathCache::init() {
- mCache.setOnEntryRemovedListener(this);
-
- GLint maxTextureSize;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
- mMaxTextureSize = maxTextureSize;
-
- mDebugEnabled = readDebugLevel() & kDebugCaches;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
+// Path cache
///////////////////////////////////////////////////////////////////////////////
-uint32_t PathCache::getSize() {
- return mSize;
-}
-
-uint32_t PathCache::getMaxSize() {
- return mMaxSize;
-}
-
-void PathCache::setMaxSize(uint32_t maxSize) {
- mMaxSize = maxSize;
- while (mSize > mMaxSize) {
- mCache.removeOldest();
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-void PathCache::operator()(PathCacheEntry& path, PathTexture*& texture) {
- removeTexture(texture);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-void PathCache::removeTexture(PathTexture* texture) {
- if (texture) {
- const uint32_t size = texture->width * texture->height;
- mSize -= size;
-
- PATH_LOGD("PathCache::callback: delete path: name, size, mSize = %d, %d, %d",
- texture->id, size, mSize);
- if (mDebugEnabled) {
- LOGD("Path deleted, size = %d", size);
- }
-
- glDeleteTextures(1, &texture->id);
- delete texture;
- }
+PathCache::PathCache(): ShapeCache<PathCacheEntry>("path",
+ PROPERTY_PATH_CACHE_SIZE, DEFAULT_PATH_CACHE_SIZE) {
}
void PathCache::remove(SkPath* path) {
@@ -159,103 +78,5 @@ PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
return texture;
}
-PathTexture* PathCache::addTexture(const PathCacheEntry& entry,
- const SkPath *path, const SkPaint* paint) {
- const SkRect& bounds = path->getBounds();
-
- const float pathWidth = fmax(bounds.width(), 1.0f);
- const float pathHeight = fmax(bounds.height(), 1.0f);
-
- if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
- LOGW("Path too large to be rendered into a texture");
- return NULL;
- }
-
- const float offset = entry.strokeWidth * 1.5f;
- const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
- const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
-
- const uint32_t size = width * height;
- // Don't even try to cache a bitmap that's bigger than the cache
- if (size < mMaxSize) {
- while (mSize + size > mMaxSize) {
- mCache.removeOldest();
- }
- }
-
- PathTexture* texture = new PathTexture;
- texture->left = bounds.fLeft;
- texture->top = bounds.fTop;
- texture->offset = offset;
- texture->width = width;
- texture->height = height;
- texture->generation = path->getGenerationID();
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kA8_Config, width, height);
- bitmap.allocPixels();
- bitmap.eraseColor(0);
-
- SkPaint pathPaint(*paint);
-
- // Make sure the paint is opaque, color, alpha, filter, etc.
- // will be applied later when compositing the alpha8 texture
- pathPaint.setColor(0xff000000);
- pathPaint.setAlpha(255);
- pathPaint.setColorFilter(NULL);
- pathPaint.setMaskFilter(NULL);
- pathPaint.setShader(NULL);
- SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode);
- pathPaint.setXfermode(mode)->safeUnref();
-
- SkCanvas canvas(bitmap);
- canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset);
- canvas.drawPath(*path, pathPaint);
-
- generateTexture(bitmap, texture);
-
- if (size < mMaxSize) {
- mSize += size;
- PATH_LOGD("PathCache::get: create path: name, size, mSize = %d, %d, %d",
- texture->id, size, mSize);
- if (mDebugEnabled) {
- LOGD("Path created, size = %d", size);
- }
- mCache.put(entry, texture);
- } else {
- texture->cleanup = true;
- }
-
- return texture;
-}
-
-void PathCache::clear() {
- mCache.clear();
-}
-
-void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
- SkAutoLockPixels alp(bitmap);
- if (!bitmap.readyToDraw()) {
- LOGE("Cannot generate texture from bitmap");
- return;
- }
-
- glGenTextures(1, &texture->id);
-
- glBindTexture(GL_TEXTURE_2D, texture->id);
- // Textures are Alpha8
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- texture->blend = true;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
- GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index ae2e55dfbe2a..dc67e160fabf 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -17,123 +17,54 @@
#ifndef ANDROID_HWUI_PATH_CACHE_H
#define ANDROID_HWUI_PATH_CACHE_H
-#include <SkBitmap.h>
-#include <SkPaint.h>
-#include <SkPath.h>
-
#include <utils/Vector.h>
#include "Debug.h"
-#include "Texture.h"
+#include "ShapeCache.h"
+
#include "utils/Compare.h"
-#include "utils/GenerationCache.h"
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_PATHS
- #define PATH_LOGD(...) LOGD(__VA_ARGS__)
-#else
- #define PATH_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
// Classes
///////////////////////////////////////////////////////////////////////////////
-/**
- * Describe a path in the path cache.
- */
-struct PathCacheEntry {
- PathCacheEntry() {
- path = NULL;
- join = SkPaint::kDefault_Join;
- cap = SkPaint::kDefault_Cap;
- style = SkPaint::kFill_Style;
- miter = 4.0f;
- strokeWidth = 1.0f;
+struct PathCacheEntry: public ShapeCacheEntry {
+ PathCacheEntry(SkPath* path, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapePath, paint) {
+ this->path = path;
}
- PathCacheEntry(const PathCacheEntry& entry):
- path(entry.path), join(entry.join), cap(entry.cap),
- style(entry.style), miter(entry.miter),
- strokeWidth(entry.strokeWidth) {
+ PathCacheEntry(): ShapeCacheEntry() {
+ path = NULL;
}
- PathCacheEntry(SkPath* path, SkPaint* paint) {
- this->path = path;
- join = paint->getStrokeJoin();
- cap = paint->getStrokeCap();
- miter = paint->getStrokeMiter();
- strokeWidth = paint->getStrokeWidth();
- style = paint->getStyle();
+ PathCacheEntry(const PathCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ path = entry.path;
}
- SkPath* path;
- SkPaint::Join join;
- SkPaint::Cap cap;
- SkPaint::Style style;
- float miter;
- float strokeWidth;
-
- bool operator<(const PathCacheEntry& rhs) const {
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const PathCacheEntry& rhs = (const PathCacheEntry&) r;
LTE_INT(path) {
- LTE_INT(join) {
- LTE_INT(cap) {
- LTE_INT(style) {
- LTE_FLOAT(miter) {
- LTE_FLOAT(strokeWidth) return false;
- }
- }
- }
- }
+ return false;
}
return false;
}
-}; // struct PathCacheEntry
-
-/**
- * Alpha texture used to represent a path.
- */
-struct PathTexture: public Texture {
- PathTexture(): Texture() {
- }
- /**
- * Left coordinate of the path bounds.
- */
- float left;
- /**
- * Top coordinate of the path bounds.
- */
- float top;
- /**
- * Offset to draw the path at the correct origin.
- */
- float offset;
-}; // struct PathTexture
+ SkPath* path;
+}; // PathCacheEntry
/**
* A simple LRU path cache. The cache has a maximum size expressed in bytes.
* Any texture added to the cache causing the cache to grow beyond the maximum
* allowed size will also cause the oldest texture to be kicked out.
*/
-class PathCache: public OnEntryRemoved<PathCacheEntry, PathTexture*> {
+class PathCache: public ShapeCache<PathCacheEntry> {
public:
PathCache();
- PathCache(uint32_t maxByteSize);
- ~PathCache();
-
- /**
- * Used as a callback when an entry is removed from the cache.
- * Do not invoke directly.
- */
- void operator()(PathCacheEntry& path, PathTexture*& texture);
/**
* Returns the texture associated with the specified path. If the texture
@@ -141,10 +72,6 @@ public:
*/
PathTexture* get(SkPath* path, SkPaint* paint);
/**
- * Clears the cache. This causes all textures to be deleted.
- */
- void clear();
- /**
* Removes an entry.
*/
void remove(SkPath* path);
@@ -158,39 +85,7 @@ public:
*/
void clearGarbage();
- /**
- * Sets the maximum size of the cache in bytes.
- */
- void setMaxSize(uint32_t maxSize);
- /**
- * Returns the maximum size of the cache in bytes.
- */
- uint32_t getMaxSize();
- /**
- * Returns the current size of the cache in bytes.
- */
- uint32_t getSize();
-
private:
- /**
- * Generates the texture from a bitmap into the specified texture structure.
- */
- void generateTexture(SkBitmap& bitmap, Texture* texture);
-
- void removeTexture(PathTexture* texture);
-
- PathTexture* addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint);
-
- void init();
-
- GenerationCache<PathCacheEntry, PathTexture*> mCache;
-
- uint32_t mSize;
- uint32_t mMaxSize;
- GLuint mMaxTextureSize;
-
- bool mDebugEnabled;
-
Vector<SkPath*> mGarbage;
mutable Mutex mLock;
}; // class PathCache
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 6a0d7ea18dfb..2f230b566c82 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -48,6 +48,7 @@ enum DebugLevel {
#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
#define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
+#define PROPERTY_SHAPE_CACHE_SIZE "ro.hwui.shape_cache_size"
#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
@@ -66,6 +67,7 @@ enum DebugLevel {
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
#define DEFAULT_LAYER_CACHE_SIZE 8.0f
#define DEFAULT_PATH_CACHE_SIZE 4.0f
+#define DEFAULT_SHAPE_CACHE_SIZE 1.0f
#define DEFAULT_PATCH_CACHE_SIZE 512
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
diff --git a/libs/hwui/ShapeCache.cpp b/libs/hwui/ShapeCache.cpp
new file mode 100644
index 000000000000..b78eecba5215
--- /dev/null
+++ b/libs/hwui/ShapeCache.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "ShapeCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Rounded rects
+///////////////////////////////////////////////////////////////////////////////
+
+RoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>(
+ "round rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
+}
+
+PathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
+ float rx, float ry, SkPaint* paint) {
+ RoundRectShapeCacheEntry entry(width, height, rx, ry, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ SkRect r;
+ r.set(0.0f, 0.0f, width, height);
+ path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Circles
+///////////////////////////////////////////////////////////////////////////////
+
+CircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>(
+ "circle", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
+}
+
+PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
+ CircleShapeCacheEntry entry(radius, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ path.addCircle(radius, radius, radius, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
new file mode 100644
index 000000000000..c8bcfc246aad
--- /dev/null
+++ b/libs/hwui/ShapeCache.h
@@ -0,0 +1,492 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HWUI_SHAPE_CACHE_H
+#define ANDROID_HWUI_SHAPE_CACHE_H
+
+#include <GLES2/gl2.h>
+
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkPaint.h>
+#include <SkPath.h>
+#include <SkRect.h>
+
+#include "Debug.h"
+#include "Properties.h"
+#include "Texture.h"
+#include "utils/Compare.h"
+#include "utils/GenerationCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+// Debug
+#if DEBUG_SHAPES
+ #define SHAPE_LOGD(...) LOGD(__VA_ARGS__)
+#else
+ #define SHAPE_LOGD(...)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Alpha texture used to represent a path.
+ */
+struct PathTexture: public Texture {
+ PathTexture(): Texture() {
+ }
+
+ /**
+ * Left coordinate of the path bounds.
+ */
+ float left;
+ /**
+ * Top coordinate of the path bounds.
+ */
+ float top;
+ /**
+ * Offset to draw the path at the correct origin.
+ */
+ float offset;
+}; // struct PathTexture
+
+/**
+ * Describe a shape in the shape cache.
+ */
+struct ShapeCacheEntry {
+ enum ShapeType {
+ kShapeNone,
+ kShapeRoundRect,
+ kShapeCircle,
+ kShapeOval,
+ kShapeArc,
+ kShapePath
+ };
+
+ ShapeCacheEntry() {
+ shapeType = kShapeNone;
+ join = SkPaint::kDefault_Join;
+ cap = SkPaint::kDefault_Cap;
+ style = SkPaint::kFill_Style;
+ miter = 4.0f;
+ strokeWidth = 1.0f;
+ }
+
+ ShapeCacheEntry(const ShapeCacheEntry& entry):
+ shapeType(entry.shapeType), join(entry.join), cap(entry.cap),
+ style(entry.style), miter(entry.miter),
+ strokeWidth(entry.strokeWidth) {
+ }
+
+ ShapeCacheEntry(ShapeType type, SkPaint* paint) {
+ shapeType = type;
+ join = paint->getStrokeJoin();
+ cap = paint->getStrokeCap();
+ float v = paint->getStrokeMiter();
+ miter = *(uint32_t*) &v;
+ v = paint->getStrokeWidth();
+ strokeWidth = *(uint32_t*) &v;
+ style = paint->getStyle();
+ }
+
+ virtual ~ShapeCacheEntry() {
+ }
+
+ // shapeType must be checked in subclasses operator<
+ ShapeType shapeType;
+ SkPaint::Join join;
+ SkPaint::Cap cap;
+ SkPaint::Style style;
+ uint32_t miter;
+ uint32_t strokeWidth;
+
+ bool operator<(const ShapeCacheEntry& rhs) const {
+ LTE_INT(shapeType) {
+ LTE_INT(join) {
+ LTE_INT(cap) {
+ LTE_INT(style) {
+ LTE_INT(miter) {
+ LTE_INT(strokeWidth) {
+ return lessThan(rhs);
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+protected:
+ virtual bool lessThan(const ShapeCacheEntry& rhs) const {
+ return false;
+ }
+}; // struct ShapeCacheEntry
+
+
+struct RoundRectShapeCacheEntry: public ShapeCacheEntry {
+ RoundRectShapeCacheEntry(float width, float height, float rx, float ry, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeRoundRect, paint) {
+ mWidth = *(uint32_t*) &width;
+ mHeight = *(uint32_t*) &height;
+ mRx = *(uint32_t*) &rx;
+ mRy = *(uint32_t*) &ry;
+ }
+
+ RoundRectShapeCacheEntry(): ShapeCacheEntry() {
+ mWidth = 0;
+ mHeight = 0;
+ mRx = 0;
+ mRy = 0;
+ }
+
+ RoundRectShapeCacheEntry(const RoundRectShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mWidth = entry.mWidth;
+ mHeight = entry.mHeight;
+ mRx = entry.mRx;
+ mRy = entry.mRy;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const RoundRectShapeCacheEntry& rhs = (const RoundRectShapeCacheEntry&) r;
+ LTE_INT(mWidth) {
+ LTE_INT(mHeight) {
+ LTE_INT(mRx) {
+ LTE_INT(mRy) {
+ return false;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+private:
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mRx;
+ uint32_t mRy;
+}; // RoundRectShapeCacheEntry
+
+struct CircleShapeCacheEntry: public ShapeCacheEntry {
+ CircleShapeCacheEntry(float radius, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeCircle, paint) {
+ mRadius = *(uint32_t*) &radius;
+ }
+
+ CircleShapeCacheEntry(): ShapeCacheEntry() {
+ mRadius = 0;
+ }
+
+ CircleShapeCacheEntry(const CircleShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mRadius = entry.mRadius;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const CircleShapeCacheEntry& rhs = (const CircleShapeCacheEntry&) r;
+ LTE_INT(mRadius) {
+ return false;
+ }
+ return false;
+ }
+
+private:
+ uint32_t mRadius;
+}; // CircleShapeCacheEntry
+
+/**
+ * A simple LRU shape cache. The cache has a maximum size expressed in bytes.
+ * Any texture added to the cache causing the cache to grow beyond the maximum
+ * allowed size will also cause the oldest texture to be kicked out.
+ */
+template<typename Entry>
+class ShapeCache: public OnEntryRemoved<Entry, PathTexture*> {
+public:
+ ShapeCache(const char* name, const char* propertyName, float defaultSize);
+ ~ShapeCache();
+
+ /**
+ * Used as a callback when an entry is removed from the cache.
+ * Do not invoke directly.
+ */
+ void operator()(Entry& path, PathTexture*& texture);
+
+ /**
+ * Clears the cache. This causes all textures to be deleted.
+ */
+ void clear();
+
+ /**
+ * Sets the maximum size of the cache in bytes.
+ */
+ void setMaxSize(uint32_t maxSize);
+ /**
+ * Returns the maximum size of the cache in bytes.
+ */
+ uint32_t getMaxSize();
+ /**
+ * Returns the current size of the cache in bytes.
+ */
+ uint32_t getSize();
+
+protected:
+ PathTexture* addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint);
+
+ PathTexture* get(Entry entry) {
+ return mCache.get(entry);
+ }
+
+ void removeTexture(PathTexture* texture);
+
+ GenerationCache<Entry, PathTexture*> mCache;
+ uint32_t mSize;
+ uint32_t mMaxSize;
+ GLuint mMaxTextureSize;
+
+ char* mName;
+ bool mDebugEnabled;
+
+private:
+ /**
+ * Generates the texture from a bitmap into the specified texture structure.
+ */
+ void generateTexture(SkBitmap& bitmap, Texture* texture);
+
+ void init();
+}; // class ShapeCache
+
+class RoundRectShapeCache: public ShapeCache<RoundRectShapeCacheEntry> {
+public:
+ RoundRectShapeCache();
+
+ PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
+}; // class RoundRectShapeCache
+
+class CircleShapeCache: public ShapeCache<CircleShapeCacheEntry> {
+public:
+ CircleShapeCache();
+
+ PathTexture* getCircle(float radius, SkPaint* paint);
+}; // class RoundRectShapeCache
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructor
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+ShapeCache<Entry>::ShapeCache(const char* name, const char* propertyName, float defaultSize):
+ mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
+ mSize(0), mMaxSize(MB(defaultSize)) {
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get(propertyName, property, NULL) > 0) {
+ LOGD(" Setting %s cache size to %sMB", name, property);
+ setMaxSize(MB(atof(property)));
+ } else {
+ LOGD(" Using default %s cache size of %.2fMB", name, defaultSize);
+ }
+
+ size_t len = strlen(name);
+ mName = new char[len + 1];
+ strcpy(mName, name);
+ mName[len] = '\0';
+
+ init();
+}
+
+template<class Entry>
+ShapeCache<Entry>::~ShapeCache() {
+ mCache.clear();
+ delete[] mName;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::init() {
+ mCache.setOnEntryRemovedListener(this);
+
+ GLint maxTextureSize;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ mMaxTextureSize = maxTextureSize;
+
+ mDebugEnabled = readDebugLevel() & kDebugCaches;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Size management
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+uint32_t ShapeCache<Entry>::getSize() {
+ return mSize;
+}
+
+template<class Entry>
+uint32_t ShapeCache<Entry>::getMaxSize() {
+ return mMaxSize;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::setMaxSize(uint32_t maxSize) {
+ mMaxSize = maxSize;
+ while (mSize > mMaxSize) {
+ mCache.removeOldest();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Callbacks
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+void ShapeCache<Entry>::operator()(Entry& path, PathTexture*& texture) {
+ removeTexture(texture);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Caching
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+void ShapeCache<Entry>::removeTexture(PathTexture* texture) {
+ if (texture) {
+ const uint32_t size = texture->width * texture->height;
+ mSize -= size;
+
+ SHAPE_LOGD("ShapeCache::callback: delete %s: name, size, mSize = %d, %d, %d",
+ mName, texture->id, size, mSize);
+ if (mDebugEnabled) {
+ LOGD("Shape %s deleted, size = %d", mName, size);
+ }
+
+ glDeleteTextures(1, &texture->id);
+ delete texture;
+ }
+}
+
+template<class Entry>
+PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path,
+ const SkPaint* paint) {
+ const SkRect& bounds = path->getBounds();
+
+ const float pathWidth = fmax(bounds.width(), 1.0f);
+ const float pathHeight = fmax(bounds.height(), 1.0f);
+
+ if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
+ LOGW("Shape %s too large to be rendered into a texture", mName);
+ return NULL;
+ }
+
+ const float offset = paint->getStrokeWidth() * 1.5f;
+ const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
+ const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
+
+ const uint32_t size = width * height;
+ // Don't even try to cache a bitmap that's bigger than the cache
+ if (size < mMaxSize) {
+ while (mSize + size > mMaxSize) {
+ mCache.removeOldest();
+ }
+ }
+
+ PathTexture* texture = new PathTexture;
+ texture->left = bounds.fLeft;
+ texture->top = bounds.fTop;
+ texture->offset = offset;
+ texture->width = width;
+ texture->height = height;
+ texture->generation = path->getGenerationID();
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kA8_Config, width, height);
+ bitmap.allocPixels();
+ bitmap.eraseColor(0);
+
+ SkPaint pathPaint(*paint);
+
+ // Make sure the paint is opaque, color, alpha, filter, etc.
+ // will be applied later when compositing the alpha8 texture
+ pathPaint.setColor(0xff000000);
+ pathPaint.setAlpha(255);
+ pathPaint.setColorFilter(NULL);
+ pathPaint.setMaskFilter(NULL);
+ pathPaint.setShader(NULL);
+ SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode);
+ pathPaint.setXfermode(mode)->safeUnref();
+
+ SkCanvas canvas(bitmap);
+ canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset);
+ canvas.drawPath(*path, pathPaint);
+
+ generateTexture(bitmap, texture);
+
+ if (size < mMaxSize) {
+ mSize += size;
+ SHAPE_LOGD("ShapeCache::get: create %s: name, size, mSize = %d, %d, %d",
+ mName, texture->id, size, mSize);
+ if (mDebugEnabled) {
+ LOGD("Shape %s created, size = %d", mName, size);
+ }
+ mCache.put(entry, texture);
+ } else {
+ texture->cleanup = true;
+ }
+
+ return texture;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::clear() {
+ mCache.clear();
+}
+
+template<class Entry>
+void ShapeCache<Entry>::generateTexture(SkBitmap& bitmap, Texture* texture) {
+ SkAutoLockPixels alp(bitmap);
+ if (!bitmap.readyToDraw()) {
+ LOGE("Cannot generate texture from bitmap");
+ return;
+ }
+
+ glGenTextures(1, &texture->id);
+
+ glBindTexture(GL_TEXTURE_2D, texture->id);
+ // Textures are Alpha8
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ texture->blend = true;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_SHAPE_CACHE_H
diff --git a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
index b02f85d74913..b6f2b2a60371 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
@@ -102,8 +102,7 @@ static void test_clamp(uint32_t index) {
start();
// Do ~100 M ops
- int ct;
- for (ct=0; ct < 1000 * 100; ct++) {
+ for (int ct=0; ct < 1000 * 100; ct++) {
for (int i=0; i < (1000); i++) {
data_f1[i] = clamp(data_f1[i], -1.f, 1.f);
}
@@ -114,7 +113,7 @@ static void test_clamp(uint32_t index) {
start();
// Do ~100 M ops
- for (ct=0; ct < 1000 * 100; ct++) {
+ for (int ct=0; ct < 1000 * 100; ct++) {
for (int i=0; i < (1000); i++) {
if (data_f1[i] < -1.f) data_f1[i] = -1.f;
if (data_f1[i] > -1.f) data_f1[i] = 1.f;
@@ -130,8 +129,7 @@ static void test_clamp4(uint32_t index) {
float total = 0;
// Do ~100 M ops
- int ct;
- for (ct=0; ct < 1000 * 100 /4; ct++) {
+ for (int ct=0; ct < 1000 * 100 /4; ct++) {
for (int i=0; i < (1000); i++) {
data_f4[i] = clamp(data_f4[i], -1.f, 1.f);
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/libs/rs/java/tests/src/com/android/rs/test/math.rs
index 5b1ad15c0cb6..02993fe5bb05 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/math.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/math.rs
@@ -7,45 +7,162 @@ volatile float2 f2;
volatile float3 f3;
volatile float4 f4;
-#define TEST_F(fnc, var) \
+volatile int i1;
+volatile int2 i2;
+volatile int3 i3;
+volatile int4 i4;
+
+#define TEST_FN_FUNC_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1); \
+ f2 = fnc(f2); \
+ f3 = fnc(f3); \
+ f4 = fnc(f4);
+
+#define TEST_FN_FUNC_FN_PFN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, (float*) &f1); \
+ f2 = fnc(f2, (float2*) &f2); \
+ f3 = fnc(f3, (float3*) &f3); \
+ f4 = fnc(f4, (float4*) &f4);
+
+#define TEST_FN_FUNC_FN_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1); \
+ f2 = fnc(f2, f2); \
+ f3 = fnc(f3, f3); \
+ f4 = fnc(f4, f4);
+
+#define TEST_FN_FUNC_FN_F(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1); \
+ f2 = fnc(f2, f1); \
+ f3 = fnc(f3, f1); \
+ f4 = fnc(f4, f1);
+
+#define TEST_FN_FUNC_FN_IN(fnc) \
rsDebug("Testing " #fnc, 0); \
- var##1 = fnc(var##1); \
- var##2 = fnc(var##2); \
- var##3 = fnc(var##3); \
- var##4 = fnc(var##4);
+ f1 = fnc(f1, i1); \
+ f2 = fnc(f2, i2); \
+ f3 = fnc(f3, i3); \
+ f4 = fnc(f4, i4);
-#define TEST_FP(fnc, var) \
+#define TEST_FN_FUNC_FN_I(fnc) \
rsDebug("Testing " #fnc, 0); \
- var##1 = fnc(var##1, (float*) &f1); \
- var##2 = fnc(var##2, (float2*) &f2); \
- var##3 = fnc(var##3, (float3*) &f3); \
- var##4 = fnc(var##4, (float4*) &f4);
+ f1 = fnc(f1, i1); \
+ f2 = fnc(f2, i1); \
+ f3 = fnc(f3, i1); \
+ f4 = fnc(f4, i1);
-#define TEST_F2(fnc, var) \
+#define TEST_FN_FUNC_FN_FN_FN(fnc) \
rsDebug("Testing " #fnc, 0); \
- var##1 = fnc(var##1, var##1); \
- var##2 = fnc(var##2, var##2); \
- var##3 = fnc(var##3, var##3); \
- var##4 = fnc(var##4, var##4);
+ f1 = fnc(f1, f1, f1); \
+ f2 = fnc(f2, f2, f2); \
+ f3 = fnc(f3, f3, f3); \
+ f4 = fnc(f4, f4, f4);
-static bool test_math(uint32_t index) {
+#define TEST_FN_FUNC_FN_PIN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, (int*) &i1); \
+ f2 = fnc(f2, (int2*) &i2); \
+ f3 = fnc(f3, (int3*) &i3); \
+ f4 = fnc(f4, (int4*) &i4);
+
+#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1, (int*) &i1); \
+ f2 = fnc(f2, f2, (int2*) &i2); \
+ f3 = fnc(f3, f3, (int3*) &i3); \
+ f4 = fnc(f4, f4, (int4*) &i4);
+
+#define TEST_IN_FUNC_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ i1 = fnc(f1); \
+ i2 = fnc(f2); \
+ i3 = fnc(f3); \
+ i4 = fnc(f4);
+
+
+static bool test_fp_math(uint32_t index) {
bool failed = false;
start();
- TEST_F(cos, f);
- TEST_FP(modf, f);
- TEST_F2(pow, f);
- TEST_F(sin, f);
- TEST_F(sqrt, f);
-
+ TEST_FN_FUNC_FN(acos);
+ TEST_FN_FUNC_FN(acosh);
+ TEST_FN_FUNC_FN(acospi);
+ TEST_FN_FUNC_FN(asin);
+ TEST_FN_FUNC_FN(asinh);
+ TEST_FN_FUNC_FN(asinpi);
+ TEST_FN_FUNC_FN(atan);
+ TEST_FN_FUNC_FN_FN(atan2);
+ TEST_FN_FUNC_FN(atanh);
+ TEST_FN_FUNC_FN(atanpi);
+ TEST_FN_FUNC_FN_FN(atan2pi);
+ TEST_FN_FUNC_FN(cbrt);
+ TEST_FN_FUNC_FN(ceil);
+ TEST_FN_FUNC_FN_FN(copysign);
+ TEST_FN_FUNC_FN(cos);
+ TEST_FN_FUNC_FN(cosh);
+ TEST_FN_FUNC_FN(cospi);
+ TEST_FN_FUNC_FN(erfc);
+ TEST_FN_FUNC_FN(erf);
+ TEST_FN_FUNC_FN(exp);
+ TEST_FN_FUNC_FN(exp2);
+ TEST_FN_FUNC_FN(exp10);
+ TEST_FN_FUNC_FN(expm1);
+ TEST_FN_FUNC_FN(fabs);
+ TEST_FN_FUNC_FN_FN(fdim);
+ TEST_FN_FUNC_FN(floor);
+ TEST_FN_FUNC_FN_FN_FN(fma);
+ TEST_FN_FUNC_FN_FN(fmax);
+ TEST_FN_FUNC_FN_F(fmax);
+ TEST_FN_FUNC_FN_FN(fmin);
+ TEST_FN_FUNC_FN_F(fmin);
+ TEST_FN_FUNC_FN_FN(fmod);
+ TEST_FN_FUNC_FN_PFN(fract);
+ TEST_FN_FUNC_FN_PIN(frexp);
+ TEST_FN_FUNC_FN_FN(hypot);
+ TEST_IN_FUNC_FN(ilogb);
+ TEST_FN_FUNC_FN_IN(ldexp);
+ TEST_FN_FUNC_FN_I(ldexp);
+ TEST_FN_FUNC_FN(lgamma);
+ TEST_FN_FUNC_FN_PIN(lgamma);
+ TEST_FN_FUNC_FN(log);
+ TEST_FN_FUNC_FN(log2);
+ TEST_FN_FUNC_FN(log10);
+ TEST_FN_FUNC_FN(log1p);
+ TEST_FN_FUNC_FN(logb);
+ TEST_FN_FUNC_FN_FN_FN(mad);
+ TEST_FN_FUNC_FN_PFN(modf);
+ // nan
+ TEST_FN_FUNC_FN_FN(nextafter);
+ TEST_FN_FUNC_FN_FN(pow);
+ TEST_FN_FUNC_FN_IN(pown);
+ TEST_FN_FUNC_FN_FN(powr);
+ TEST_FN_FUNC_FN_FN(remainder);
+ TEST_FN_FUNC_FN_FN_PIN(remquo);
+ TEST_FN_FUNC_FN(rint);
+ TEST_FN_FUNC_FN_IN(rootn);
+ TEST_FN_FUNC_FN(round);
+ TEST_FN_FUNC_FN(rsqrt);
+ TEST_FN_FUNC_FN(sin);
+ TEST_FN_FUNC_FN_PFN(sincos);
+ TEST_FN_FUNC_FN(sinh);
+ TEST_FN_FUNC_FN(sinpi);
+ TEST_FN_FUNC_FN(sqrt);
+ TEST_FN_FUNC_FN(tan);
+ TEST_FN_FUNC_FN(tanh);
+ TEST_FN_FUNC_FN(tanpi);
+ TEST_FN_FUNC_FN(tgamma);
+ TEST_FN_FUNC_FN(trunc);
float time = end(index);
if (failed) {
- rsDebug("test_math FAILED", time);
+ rsDebug("test_fp_math FAILED", time);
}
else {
- rsDebug("test_math PASSED", time);
+ rsDebug("test_fp_math PASSED", time);
}
return failed;
@@ -53,7 +170,7 @@ static bool test_math(uint32_t index) {
void math_test(uint32_t index, int test_num) {
bool failed = false;
- failed |= test_math(index);
+ failed |= test_fp_math(index);
if (failed) {
rsSendToClientBlocking(RS_MSG_TEST_FAILED);
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2e0c491c34ef..3acb62460de0 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -253,7 +253,11 @@ void Context::deinitEGL() {
LOGV("%p, deinitEGL", this);
if (mEGL.mContext != EGL_NO_CONTEXT) {
- eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEGL.mContext);
+ eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(mEGL.mDisplay, mEGL.mSurfaceDefault);
+ if (mEGL.mSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+ }
eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
checkEglError("eglDestroyContext");
}
@@ -1035,9 +1039,7 @@ void rsi_ContextDump(Context *rsc, int32_t bits) {
}
void rsi_ContextDestroyWorker(Context *rsc) {
- LOGE("rsi_ContextDestroyWorker 1");
rsc->destroyWorkerThreadResources();;
- LOGE("rsi_ContextDestroyWorker 2");
}
}
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 9f730bffe8d3..1fceb663527f 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -467,7 +467,7 @@ extern const char rs_runtime_lib_bc[];
extern unsigned rs_runtime_lib_bc_size;
#endif
-void ScriptCState::runCompiler(Context *rsc,
+bool ScriptCState::runCompiler(Context *rsc,
ScriptC *s,
const char *resName,
const char *cacheDir) {
@@ -482,7 +482,7 @@ void ScriptCState::runCompiler(Context *rsc,
s->mEnviroment.mScriptText,
s->mEnviroment.mScriptTextLength, 0) != 0) {
LOGE("bcc: FAILS to read bitcode");
- // Handle Fatal Error
+ return false;
}
#if 1
@@ -493,14 +493,14 @@ void ScriptCState::runCompiler(Context *rsc,
/*"1" means skip buffer here, and let libbcc decide*/,
0) != 0) {
LOGE("bcc: FAILS to link bitcode");
- // Handle Fatal Error
+ return false;
}
#endif
char *cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
if (bccPrepareExecutable(s->mBccScript, cachePath, 0) != 0) {
LOGE("bcc: FAILS to prepare executable");
- // Handle Fatal Error
+ return false;
}
free(cachePath);
@@ -547,7 +547,7 @@ void ScriptCState::runCompiler(Context *rsc,
continue;
}
LOGE("Invalid version pragma value: %s\n", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateVertex")) {
@@ -559,7 +559,7 @@ void ScriptCState::runCompiler(Context *rsc,
continue;
}
LOGE("Unrecognized value %s passed to stateVertex", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateRaster")) {
@@ -571,7 +571,7 @@ void ScriptCState::runCompiler(Context *rsc,
continue;
}
LOGE("Unrecognized value %s passed to stateRaster", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateFragment")) {
@@ -583,7 +583,7 @@ void ScriptCState::runCompiler(Context *rsc,
continue;
}
LOGE("Unrecognized value %s passed to stateFragment", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateStore")) {
@@ -595,9 +595,10 @@ void ScriptCState::runCompiler(Context *rsc,
continue;
}
LOGE("Unrecognized value %s passed to stateStore", values[i]);
- // Handle Fatal Error
+ return false;
}
}
+ return true;
}
namespace android {
@@ -630,7 +631,11 @@ RsScript rsi_ScriptCCreate(Context *rsc,
ss->mScript.clear();
s->incUserRef();
- ss->runCompiler(rsc, s.get(), resName, cacheDir);
+ if (!ss->runCompiler(rsc, s.get(), resName, cacheDir)) {
+ // Error during compile, destroy s and return null.
+ s->zeroUserRef();
+ return NULL;
+ }
ss->clear(rsc);
return s.get();
}
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 483481e81b02..612e38a3b5aa 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -81,7 +81,7 @@ public:
void init(Context *rsc);
void clear(Context *rsc);
- void runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
+ bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
struct SymbolTable_t {
const char * mName;
diff --git a/libs/rs/rsScriptC_LibCL.cpp b/libs/rs/rsScriptC_LibCL.cpp
index 28c558d9120e..02d33b768abe 100644
--- a/libs/rs/rsScriptC_LibCL.cpp
+++ b/libs/rs/rsScriptC_LibCL.cpp
@@ -24,26 +24,6 @@ using namespace android;
using namespace android::renderscript;
-static float SC_acospi(float v) {
- return acosf(v)/ M_PI;
-}
-
-static float SC_asinpi(float v) {
- return asinf(v) / M_PI;
-}
-
-static float SC_atanpi(float v) {
- return atanf(v) / M_PI;
-}
-
-static float SC_atan2pi(float y, float x) {
- return atan2f(y, x) / M_PI;
-}
-
-static float SC_cospi(float v) {
- return cosf(v * M_PI);
-}
-
static float SC_exp10(float v) {
return pow(10.f, v);
}
@@ -58,6 +38,10 @@ static float SC_log2(float v) {
return log10(v) / log10(2.f);
}
+static float SC_mad(float v1, float v2, float v3) {
+ return v1 * v2 + v3;
+}
+
static float SC_pown(float v, int p) {
return powf(v, (float)p);
}
@@ -79,14 +63,6 @@ float SC_sincos(float v, float *cosptr) {
return sinf(v);
}
-static float SC_sinpi(float v) {
- return sinf(v * M_PI);
-}
-
-static float SC_tanpi(float v) {
- return tanf(v * M_PI);
-}
-
//////////////////////////////////////////////////////////////////////////////
// Integer
//////////////////////////////////////////////////////////////////////////////
@@ -182,20 +158,16 @@ static ScriptCState::SymbolTable_t gSyms[] = {
// OpenCL math
{ "_Z4acosf", (void *)&acosf, true },
{ "_Z5acoshf", (void *)&acoshf, true },
- { "_Z6acospif", (void *)&SC_acospi, true },
{ "_Z4asinf", (void *)&asinf, true },
{ "_Z5asinhf", (void *)&asinhf, true },
- { "_Z6asinpif", (void *)&SC_asinpi, true },
{ "_Z4atanf", (void *)&atanf, true },
{ "_Z5atan2ff", (void *)&atan2f, true },
- { "_Z6atanpif", (void *)&SC_atanpi, true },
- { "_Z7atan2piff", (void *)&SC_atan2pi, true },
+ { "_Z5atanhf", (void *)&atanhf, true },
{ "_Z4cbrtf", (void *)&cbrtf, true },
{ "_Z4ceilf", (void *)&ceilf, true },
{ "_Z8copysignff", (void *)&copysignf, true },
{ "_Z3cosf", (void *)&cosf, true },
{ "_Z4coshf", (void *)&coshf, true },
- { "_Z5cospif", (void *)&SC_cospi, true },
{ "_Z4erfcf", (void *)&erfcf, true },
{ "_Z3erff", (void *)&erff, true },
{ "_Z3expf", (void *)&expf, true },
@@ -215,33 +187,30 @@ static ScriptCState::SymbolTable_t gSyms[] = {
{ "_Z5ilogbf", (void *)&ilogbf, true },
{ "_Z5ldexpfi", (void *)&ldexpf, true },
{ "_Z6lgammaf", (void *)&lgammaf, true },
+ { "_Z6lgammafPi", (void *)&lgammaf_r, true },
{ "_Z3logf", (void *)&logf, true },
{ "_Z4log2f", (void *)&SC_log2, true },
{ "_Z5log10f", (void *)&log10f, true },
{ "_Z5log1pf", (void *)&log1pf, true },
- //{ "logb", (void *)&, true },
- //{ "mad", (void *)&, true },
+ { "_Z4logbf", (void *)&logbf, true },
+ { "_Z3madfff", (void *)&SC_mad, true },
{ "_Z4modffPf", (void *)&modff, true },
//{ "nan", (void *)&, true },
{ "_Z9nextafterff", (void *)&nextafterf, true },
{ "_Z3powff", (void *)&powf, true },
- { "_Z4pownfi", (void *)&SC_pown, true },
- { "_Z4powrff", (void *)&SC_powr, true },
{ "_Z9remainderff", (void *)&remainderf, true },
- { "remquo", (void *)&remquof, true },
+ { "_Z6remquoffPi", (void *)&remquof, true },
{ "_Z4rintf", (void *)&rintf, true },
{ "_Z5rootnfi", (void *)&SC_rootn, true },
{ "_Z5roundf", (void *)&roundf, true },
{ "_Z5rsqrtf", (void *)&SC_rsqrt, true },
{ "_Z3sinf", (void *)&sinf, true },
- { "sincos", (void *)&SC_sincos, true },
+ { "_Z6sincosfPf", (void *)&SC_sincos, true },
{ "_Z4sinhf", (void *)&sinhf, true },
- { "_Z5sinpif", (void *)&SC_sinpi, true },
{ "_Z4sqrtf", (void *)&sqrtf, true },
{ "_Z3tanf", (void *)&tanf, true },
{ "_Z4tanhf", (void *)&tanhf, true },
- { "_Z5tanpif", (void *)&SC_tanpi, true },
- //{ "tgamma", (void *)&, true },
+ { "_Z6tgammaf", (void *)&lgammaf, true }, // FIXME!!! NEEDS TO USE tgammaf
{ "_Z5truncf", (void *)&truncf, true },
// OpenCL Int
diff --git a/libs/rs/scriptc/rs_cl.rsh b/libs/rs/scriptc/rs_cl.rsh
index ab8270f404a8..3c0496d08e3f 100644
--- a/libs/rs/scriptc/rs_cl.rsh
+++ b/libs/rs/scriptc/rs_cl.rsh
@@ -8,27 +8,31 @@
#endif
// Conversions
-#define CVT_FUNC_2(typeout, typein) \
-_RS_STATIC typeout##2 __attribute__((overloadable)) convert_##typeout##2(typein##2 v) { \
- typeout##2 r = {(typeout)v.x, (typeout)v.y}; \
- return r; \
-} \
-_RS_STATIC typeout##3 __attribute__((overloadable)) convert_##typeout##3(typein##3 v) { \
- typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z}; \
- return r; \
-} \
-_RS_STATIC typeout##4 __attribute__((overloadable)) convert_##typeout##4(typein##4 v) { \
- typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z, (typeout)v.w}; \
- return r; \
-}
-
-#define CVT_FUNC(type) CVT_FUNC_2(type, uchar) \
- CVT_FUNC_2(type, char) \
- CVT_FUNC_2(type, ushort) \
- CVT_FUNC_2(type, short) \
- CVT_FUNC_2(type, uint) \
- CVT_FUNC_2(type, int) \
- CVT_FUNC_2(type, float)
+#define CVT_FUNC_2(typeout, typein) \
+_RS_STATIC typeout##2 __attribute__((overloadable)) \
+ convert_##typeout##2(typein##2 v) { \
+ typeout##2 r = {(typeout)v.x, (typeout)v.y}; \
+ return r; \
+} \
+_RS_STATIC typeout##3 __attribute__((overloadable)) \
+ convert_##typeout##3(typein##3 v) { \
+ typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z}; \
+ return r; \
+} \
+_RS_STATIC typeout##4 __attribute__((overloadable)) \
+ convert_##typeout##4(typein##4 v) { \
+ typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z, \
+ (typeout)v.w}; \
+ return r; \
+}
+
+#define CVT_FUNC(type) CVT_FUNC_2(type, uchar) \
+ CVT_FUNC_2(type, char) \
+ CVT_FUNC_2(type, ushort) \
+ CVT_FUNC_2(type, short) \
+ CVT_FUNC_2(type, uint) \
+ CVT_FUNC_2(type, int) \
+ CVT_FUNC_2(type, float)
CVT_FUNC(char)
CVT_FUNC(uchar)
@@ -38,341 +42,444 @@ CVT_FUNC(int)
CVT_FUNC(uint)
CVT_FUNC(float)
-
-
// Float ops, 6.11.2
-#define DEF_FUNC_1(fnc) \
+#define FN_FUNC_FN(fnc) \
_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v) { \
- float2 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- return r; \
-} \
+ float2 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ return r; \
+} \
_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v) { \
- float3 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- return r; \
-} \
+ float3 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ return r; \
+} \
_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v) { \
- float4 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- r.w = fnc(v.w); \
- return r; \
-}
-
-#define DEF_FUNC_1_RI(fnc) \
-_RS_STATIC int2 __attribute__((overloadable)) fnc(float2 v) { \
- int2 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- return r; \
-} \
-_RS_STATIC int3 __attribute__((overloadable)) fnc(float3 v) { \
- int3 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- return r; \
-} \
-_RS_STATIC int4 __attribute__((overloadable)) fnc(float4 v) { \
- int4 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- r.w = fnc(v.w); \
- return r; \
-}
-
-#define DEF_FUNC_2(fnc) \
+ float4 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ r.w = fnc(v.w); \
+ return r; \
+}
+
+#define IN_FUNC_FN(fnc) \
+_RS_STATIC int2 __attribute__((overloadable)) fnc(float2 v) { \
+ int2 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ return r; \
+} \
+_RS_STATIC int3 __attribute__((overloadable)) fnc(float3 v) { \
+ int3 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ return r; \
+} \
+_RS_STATIC int4 __attribute__((overloadable)) fnc(float4 v) { \
+ int4 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ r.w = fnc(v.w); \
+ return r; \
+}
+
+#define FN_FUNC_FN_FN(fnc) \
_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
- float2 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- return r; \
-} \
+ float2 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ return r; \
+} \
_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
- float3 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- return r; \
-} \
+ float3 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ return r; \
+} \
_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
- float4 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- r.w = fnc(v1.w, v2.w); \
- return r; \
-}
-
-#define DEF_FUNC_2F(fnc) \
-_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
- float2 r; \
- r.x = fnc(v1.x, v2); \
- r.y = fnc(v1.y, v2); \
- return r; \
-} \
-_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
- float3 r; \
- r.x = fnc(v1.x, v2); \
- r.y = fnc(v1.y, v2); \
- r.z = fnc(v1.z, v2); \
- return r; \
-} \
-_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
- float4 r; \
- r.x = fnc(v1.x, v2); \
- r.y = fnc(v1.y, v2); \
- r.z = fnc(v1.z, v2); \
- r.w = fnc(v1.w, v2); \
- return r; \
-}
-
-#define DEF_FUNC_2P(fnc) \
-_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 *v2) { \
- float2 r; \
- float q; \
- r.x = fnc(v1.x, &q); \
- v2->x = q; \
- r.y = fnc(v1.y, &q); \
- v2->y = q; \
- return r; \
-} \
-_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 *v2) { \
- float3 r; \
- float q; \
- r.x = fnc(v1.x, &q); \
- v2->x = q; \
- r.y = fnc(v1.y, &q); \
- v2->y = q; \
- r.z = fnc(v1.z, &q); \
- v2->z = q; \
- return r; \
-} \
-_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 *v2) { \
- float4 r; \
- float q; \
- r.x = fnc(v1.x, &q); \
- v2->x = q; \
- r.y = fnc(v1.y, &q); \
- v2->y = q; \
- r.z = fnc(v1.z, &q); \
- v2->z = q; \
- r.w = fnc(v1.w, &q); \
- v2->w = q; \
- return r; \
+ float4 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ r.w = fnc(v1.w, v2.w); \
+ return r; \
}
+#define FN_FUNC_FN_F(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ r.w = fnc(v1.w, v2); \
+ return r; \
+}
+
+#define FN_FUNC_FN_IN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 v2) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 v2) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 v2) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ r.w = fnc(v1.w, v2.w); \
+ return r; \
+}
+
+#define FN_FUNC_FN_I(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int v2) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int v2) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int v2) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ r.w = fnc(v1.w, v2); \
+ return r; \
+}
+
+#define FN_FUNC_FN_PFN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) \
+ fnc(float2 v1, float2 *v2) { \
+ float2 r; \
+ float t[2]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) \
+ fnc(float3 v1, float3 *v2) { \
+ float3 r; \
+ float t[3]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) \
+ fnc(float4 v1, float4 *v2) { \
+ float4 r; \
+ float t[4]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ r.w = fnc(v1.w, &t[3]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ v2->w = t[3]; \
+ return r; \
+}
+
+#define FN_FUNC_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 *v2) { \
+ float2 r; \
+ int t[2]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 *v2) { \
+ float3 r; \
+ int t[3]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 *v2) { \
+ float4 r; \
+ int t[4]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ r.w = fnc(v1.w, &t[3]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ v2->w = t[3]; \
+ return r; \
+}
+
+#define FN_FUNC_FN_FN_FN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) \
+ fnc(float2 v1, float2 v2, float2 v3) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2.x, v3.x); \
+ r.y = fnc(v1.y, v2.y, v3.y); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) \
+ fnc(float3 v1, float3 v2, float3 v3) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2.x, v3.x); \
+ r.y = fnc(v1.y, v2.y, v3.y); \
+ r.z = fnc(v1.z, v2.z, v3.z); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) \
+ fnc(float4 v1, float4 v2, float4 v3) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2.x, v3.x); \
+ r.y = fnc(v1.y, v2.y, v3.y); \
+ r.z = fnc(v1.z, v2.z, v3.z); \
+ r.w = fnc(v1.w, v2.w, v3.w); \
+ return r; \
+}
+
+#define FN_FUNC_FN_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) \
+ fnc(float2 v1, float2 v2, int2 *v3) { \
+ float2 r; \
+ int t[2]; \
+ r.x = fnc(v1.x, v2.x, &t[0]); \
+ r.y = fnc(v1.y, v2.y, &t[1]); \
+ v3->x = t[0]; \
+ v3->y = t[1]; \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) \
+ fnc(float3 v1, float3 v2, int3 *v3) { \
+ float3 r; \
+ int t[3]; \
+ r.x = fnc(v1.x, v2.x, &t[0]); \
+ r.y = fnc(v1.y, v2.y, &t[1]); \
+ r.z = fnc(v1.z, v2.z, &t[2]); \
+ v3->x = t[0]; \
+ v3->y = t[1]; \
+ v3->z = t[2]; \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) \
+ fnc(float4 v1, float4 v2, int4 *v3) { \
+ float4 r; \
+ int t[4]; \
+ r.x = fnc(v1.x, v2.x, &t[0]); \
+ r.y = fnc(v1.y, v2.y, &t[1]); \
+ r.z = fnc(v1.z, v2.z, &t[2]); \
+ r.w = fnc(v1.w, v2.w, &t[3]); \
+ v3->x = t[0]; \
+ v3->y = t[1]; \
+ v3->z = t[2]; \
+ v3->w = t[3]; \
+ return r; \
+}
+
+
extern float __attribute__((overloadable)) acos(float);
-DEF_FUNC_1(acos)
+FN_FUNC_FN(acos)
extern float __attribute__((overloadable)) acosh(float);
-DEF_FUNC_1(acosh)
+FN_FUNC_FN(acosh)
_RS_STATIC float __attribute__((overloadable)) acospi(float v) {
return acos(v) / M_PI;
}
-DEF_FUNC_1(acospi)
+FN_FUNC_FN(acospi)
extern float __attribute__((overloadable)) asin(float);
-DEF_FUNC_1(asin)
+FN_FUNC_FN(asin)
extern float __attribute__((overloadable)) asinh(float);
-DEF_FUNC_1(asinh)
+FN_FUNC_FN(asinh)
_RS_STATIC float __attribute__((overloadable)) asinpi(float v) {
return asin(v) / M_PI;
}
-DEF_FUNC_1(asinpi)
+FN_FUNC_FN(asinpi)
extern float __attribute__((overloadable)) atan(float);
-DEF_FUNC_1(atan)
+FN_FUNC_FN(atan)
extern float __attribute__((overloadable)) atan2(float, float);
-DEF_FUNC_2(atan2)
+FN_FUNC_FN_FN(atan2)
extern float __attribute__((overloadable)) atanh(float);
-DEF_FUNC_1(atanh)
+FN_FUNC_FN(atanh)
_RS_STATIC float __attribute__((overloadable)) atanpi(float v) {
return atan(v) / M_PI;
}
-DEF_FUNC_1(atanpi)
+FN_FUNC_FN(atanpi)
_RS_STATIC float __attribute__((overloadable)) atan2pi(float y, float x) {
return atan2(y, x) / M_PI;
}
-DEF_FUNC_2(atan2pi)
+FN_FUNC_FN_FN(atan2pi)
extern float __attribute__((overloadable)) cbrt(float);
-DEF_FUNC_1(cbrt)
+FN_FUNC_FN(cbrt)
extern float __attribute__((overloadable)) ceil(float);
-DEF_FUNC_1(ceil)
+FN_FUNC_FN(ceil)
extern float __attribute__((overloadable)) copysign(float, float);
-DEF_FUNC_2(copysign)
+FN_FUNC_FN_FN(copysign)
extern float __attribute__((overloadable)) cos(float);
-DEF_FUNC_1(cos)
+FN_FUNC_FN(cos)
extern float __attribute__((overloadable)) cosh(float);
-DEF_FUNC_1(cosh)
+FN_FUNC_FN(cosh)
_RS_STATIC float __attribute__((overloadable)) cospi(float v) {
return cos(v * M_PI);
}
-DEF_FUNC_1(cospi)
+FN_FUNC_FN(cospi)
extern float __attribute__((overloadable)) erfc(float);
-DEF_FUNC_1(erfc)
+FN_FUNC_FN(erfc)
extern float __attribute__((overloadable)) erf(float);
-DEF_FUNC_1(erf)
+FN_FUNC_FN(erf)
extern float __attribute__((overloadable)) exp(float);
-DEF_FUNC_1(exp)
+FN_FUNC_FN(exp)
extern float __attribute__((overloadable)) exp2(float);
-DEF_FUNC_1(exp2)
+FN_FUNC_FN(exp2)
extern float __attribute__((overloadable)) pow(float, float);
_RS_STATIC float __attribute__((overloadable)) exp10(float v) {
return pow(10.f, v);
}
-DEF_FUNC_1(exp10)
+FN_FUNC_FN(exp10)
extern float __attribute__((overloadable)) expm1(float);
-DEF_FUNC_1(expm1)
+FN_FUNC_FN(expm1)
extern float __attribute__((overloadable)) fabs(float);
-DEF_FUNC_1(fabs)
+FN_FUNC_FN(fabs)
extern float __attribute__((overloadable)) fdim(float, float);
-DEF_FUNC_2(fdim)
+FN_FUNC_FN_FN(fdim)
extern float __attribute__((overloadable)) floor(float);
-DEF_FUNC_1(floor)
+FN_FUNC_FN(floor)
extern float __attribute__((overloadable)) fma(float, float, float);
-extern float2 __attribute__((overloadable)) fma(float2, float2, float2);
-extern float3 __attribute__((overloadable)) fma(float3, float3, float3);
-extern float4 __attribute__((overloadable)) fma(float4, float4, float4);
+FN_FUNC_FN_FN_FN(fma)
extern float __attribute__((overloadable)) fmax(float, float);
-DEF_FUNC_2(fmax);
-DEF_FUNC_2F(fmax);
+FN_FUNC_FN_FN(fmax);
+FN_FUNC_FN_F(fmax);
extern float __attribute__((overloadable)) fmin(float, float);
-DEF_FUNC_2(fmin);
-DEF_FUNC_2F(fmin);
+FN_FUNC_FN_FN(fmin);
+FN_FUNC_FN_F(fmin);
extern float __attribute__((overloadable)) fmod(float, float);
-DEF_FUNC_2(fmod)
+FN_FUNC_FN_FN(fmod)
_RS_STATIC float __attribute__((overloadable)) fract(float v, float *iptr) {
int i = (int)floor(v);
iptr[0] = i;
return fmin(v - i, 0x1.fffffep-1f);
}
-_RS_STATIC float2 __attribute__((overloadable)) fract(float2 v, float2 *iptr) {
- float t[2];
- float2 r;
- r.x = fract(v.x, &t[0]);
- r.y = fract(v.y, &t[1]);
- iptr[0] = t[0];
- iptr[1] = t[1];
- return r;
-}
-_RS_STATIC float3 __attribute__((overloadable)) fract(float3 v, float3 *iptr) {
- float t[3];
- float3 r;
- r.x = fract(v.x, &t[0]);
- r.y = fract(v.y, &t[1]);
- r.z = fract(v.z, &t[2]);
- iptr[0] = t[0];
- iptr[1] = t[1];
- iptr[2] = t[2];
- return r;
-}
-_RS_STATIC float4 __attribute__((overloadable)) fract(float4 v, float4 *iptr) {
- float t[4];
- float4 r;
- r.x = fract(v.x, &t[0]);
- r.y = fract(v.y, &t[1]);
- r.z = fract(v.z, &t[2]);
- r.w = fract(v.w, &t[3]);
- iptr[0] = t[0];
- iptr[1] = t[1];
- iptr[2] = t[2];
- iptr[3] = t[3];
- return r;
-}
+FN_FUNC_FN_PFN(fract)
-extern float __attribute__((overloadable)) frexp(float, float *);
-extern float2 __attribute__((overloadable)) frexp(float2, float2 *);
-extern float3 __attribute__((overloadable)) frexp(float3, float3 *);
-extern float4 __attribute__((overloadable)) frexp(float4, float4 *);
+extern float __attribute__((overloadable)) frexp(float, int *);
+FN_FUNC_FN_PIN(frexp)
extern float __attribute__((overloadable)) hypot(float, float);
-DEF_FUNC_2(hypot)
+FN_FUNC_FN_FN(hypot)
extern int __attribute__((overloadable)) ilogb(float);
-DEF_FUNC_1_RI(ilogb)
+IN_FUNC_FN(ilogb)
extern float __attribute__((overloadable)) ldexp(float, int);
-extern float2 __attribute__((overloadable)) ldexp(float2, int2);
-extern float3 __attribute__((overloadable)) ldexp(float3, int3);
-extern float4 __attribute__((overloadable)) ldexp(float4, int4);
-extern float2 __attribute__((overloadable)) ldexp(float2, int);
-extern float3 __attribute__((overloadable)) ldexp(float3, int);
-extern float4 __attribute__((overloadable)) ldexp(float4, int);
+FN_FUNC_FN_IN(ldexp)
+FN_FUNC_FN_I(ldexp)
extern float __attribute__((overloadable)) lgamma(float);
-DEF_FUNC_1(lgamma)
-extern float __attribute__((overloadable)) lgamma(float, float *);
-extern float2 __attribute__((overloadable)) lgamma(float2, float2 *);
-extern float3 __attribute__((overloadable)) lgamma(float3, float3 *);
-extern float4 __attribute__((overloadable)) lgamma(float4, float4 *);
+FN_FUNC_FN(lgamma)
+extern float __attribute__((overloadable)) lgamma(float, int*);
+FN_FUNC_FN_PIN(lgamma)
extern float __attribute__((overloadable)) log(float);
-DEF_FUNC_1(log)
+FN_FUNC_FN(log)
extern float __attribute__((overloadable)) log10(float);
-DEF_FUNC_1(log10)
+FN_FUNC_FN(log10)
_RS_STATIC float __attribute__((overloadable)) log2(float v) {
return log10(v) / log10(2.f);
}
-DEF_FUNC_1(log2)
+FN_FUNC_FN(log2)
extern float __attribute__((overloadable)) log1p(float);
-DEF_FUNC_1(log1p)
+FN_FUNC_FN(log1p)
extern float __attribute__((overloadable)) logb(float);
-DEF_FUNC_1(logb)
+FN_FUNC_FN(logb)
extern float __attribute__((overloadable)) mad(float, float, float);
-extern float2 __attribute__((overloadable)) mad(float2, float2, float2);
-extern float3 __attribute__((overloadable)) mad(float3, float3, float3);
-extern float4 __attribute__((overloadable)) mad(float4, float4, float4);
+FN_FUNC_FN_FN_FN(mad)
extern float __attribute__((overloadable)) modf(float, float *);
-DEF_FUNC_2P(modf);
+FN_FUNC_FN_PFN(modf);
//extern float __attribute__((overloadable)) nan(uint);
extern float __attribute__((overloadable)) nextafter(float, float);
-DEF_FUNC_2(nextafter)
+FN_FUNC_FN_FN(nextafter)
-DEF_FUNC_2(pow)
+FN_FUNC_FN_FN(pow)
_RS_STATIC float __attribute__((overloadable)) pown(float v, int p) {
return pow(v, (float)p);
@@ -401,15 +508,13 @@ _RS_STATIC float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
}
extern float __attribute__((overloadable)) remainder(float, float);
-DEF_FUNC_2(remainder)
+FN_FUNC_FN_FN(remainder)
extern float __attribute__((overloadable)) remquo(float, float, int *);
-extern float2 __attribute__((overloadable)) remquo(float2, float2, int2 *);
-extern float3 __attribute__((overloadable)) remquo(float3, float3, int3 *);
-extern float4 __attribute__((overloadable)) remquo(float4, float4, int4 *);
+FN_FUNC_FN_FN_PIN(remquo)
extern float __attribute__((overloadable)) rint(float);
-DEF_FUNC_1(rint)
+FN_FUNC_FN(rint)
_RS_STATIC float __attribute__((overloadable)) rootn(float v, int r) {
return pow(v, 1.f / r);
@@ -428,16 +533,16 @@ _RS_STATIC float4 __attribute__((overloadable)) rootn(float4 v, int4 r) {
}
extern float __attribute__((overloadable)) round(float);
-DEF_FUNC_1(round)
+FN_FUNC_FN(round)
extern float __attribute__((overloadable)) sqrt(float);
_RS_STATIC float __attribute__((overloadable)) rsqrt(float v) {
return 1.f / sqrt(v);
}
-DEF_FUNC_1(rsqrt)
+FN_FUNC_FN(rsqrt)
extern float __attribute__((overloadable)) sin(float);
-DEF_FUNC_1(sin)
+FN_FUNC_FN(sin)
_RS_STATIC float __attribute__((overloadable)) sincos(float v, float *cosptr) {
*cosptr = cos(v);
@@ -457,114 +562,118 @@ _RS_STATIC float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr)
}
extern float __attribute__((overloadable)) sinh(float);
-DEF_FUNC_1(sinh)
+FN_FUNC_FN(sinh)
_RS_STATIC float __attribute__((overloadable)) sinpi(float v) {
return sin(v * M_PI);
}
-DEF_FUNC_1(sinpi)
+FN_FUNC_FN(sinpi)
-DEF_FUNC_1(sqrt)
+FN_FUNC_FN(sqrt)
extern float __attribute__((overloadable)) tan(float);
-DEF_FUNC_1(tan)
+FN_FUNC_FN(tan)
extern float __attribute__((overloadable)) tanh(float);
-DEF_FUNC_1(tanh)
+FN_FUNC_FN(tanh)
_RS_STATIC float __attribute__((overloadable)) tanpi(float v) {
return tan(v * M_PI);
}
-DEF_FUNC_1(tanpi)
+FN_FUNC_FN(tanpi)
extern float __attribute__((overloadable)) tgamma(float);
-DEF_FUNC_1(tgamma)
+FN_FUNC_FN(tgamma)
extern float __attribute__((overloadable)) trunc(float);
-DEF_FUNC_1(trunc)
+FN_FUNC_FN(trunc)
// Int ops (partial), 6.11.3
-#define DEF_RIFUNC_1(typeout, typein, fnc) \
-extern typeout __attribute__((overloadable)) fnc(typein); \
+#define XN_FUNC_YN(typeout, fnc, typein) \
+extern typeout __attribute__((overloadable)) fnc(typein); \
_RS_STATIC typeout##2 __attribute__((overloadable)) fnc(typein##2 v) { \
- typeout##2 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- return r; \
-} \
+ typeout##2 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ return r; \
+} \
_RS_STATIC typeout##3 __attribute__((overloadable)) fnc(typein##3 v) { \
- typeout##3 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- return r; \
-} \
+ typeout##3 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ return r; \
+} \
_RS_STATIC typeout##4 __attribute__((overloadable)) fnc(typein##4 v) { \
- typeout##4 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- r.w = fnc(v.w); \
- return r; \
-}
-
-#define DEF_UIFUNC_1(fnc) \
-DEF_RIFUNC_1(uchar, char, fnc) \
-DEF_RIFUNC_1(ushort, short, fnc) \
-DEF_RIFUNC_1(uint, int, fnc)
-
-#define DEF_IFUNC_1(fnc) \
-DEF_RIFUNC_1(uchar, uchar, fnc) \
-DEF_RIFUNC_1(char, char, fnc) \
-DEF_RIFUNC_1(ushort, ushort, fnc) \
-DEF_RIFUNC_1(short, short, fnc) \
-DEF_RIFUNC_1(uint, uint, fnc) \
-DEF_RIFUNC_1(int, int, fnc)
-
-#define DEF_RIFUNC_2(type, fnc, body) \
-_RS_STATIC type __attribute__((overloadable)) fnc(type v1, type v2) { \
- return body; \
-} \
-_RS_STATIC type##2 __attribute__((overloadable)) fnc(type##2 v1, type##2 v2) { \
- type##2 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- return r; \
-} \
-_RS_STATIC type##3 __attribute__((overloadable)) fnc(type##3 v1, type##3 v2) { \
- type##3 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- return r; \
-} \
-_RS_STATIC type##4 __attribute__((overloadable)) fnc(type##4 v1, type##4 v2) { \
- type##4 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- r.w = fnc(v1.w, v2.w); \
- return r; \
-} \
-
-#define DEF_IFUNC_2(fnc, body) \
-DEF_RIFUNC_2(uchar, fnc, body) \
-DEF_RIFUNC_2(char, fnc, body) \
-DEF_RIFUNC_2(ushort, fnc, body) \
-DEF_RIFUNC_2(short, fnc, body) \
-DEF_RIFUNC_2(uint, fnc, body) \
-DEF_RIFUNC_2(int, fnc, body) \
-DEF_RIFUNC_2(float, fnc, body)
-
-DEF_UIFUNC_1(abs)
-DEF_IFUNC_1(clz)
-
-DEF_IFUNC_2(min, (v1 < v2 ? v1 : v2))
-DEF_FUNC_2F(min)
-
-DEF_IFUNC_2(max, (v1 > v2 ? v1 : v2))
-DEF_FUNC_2F(max)
+ typeout##4 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ r.w = fnc(v.w); \
+ return r; \
+}
+
+#define UIN_FUNC_IN(fnc) \
+XN_FUNC_YN(uchar, fnc, char) \
+XN_FUNC_YN(ushort, fnc, short) \
+XN_FUNC_YN(uint, fnc, int)
+
+#define IN_FUNC_IN(fnc) \
+XN_FUNC_YN(uchar, fnc, uchar) \
+XN_FUNC_YN(char, fnc, char) \
+XN_FUNC_YN(ushort, fnc, ushort) \
+XN_FUNC_YN(short, fnc, short) \
+XN_FUNC_YN(uint, fnc, uint) \
+XN_FUNC_YN(int, fnc, int)
+
+#define XN_FUNC_XN_XN_BODY(type, fnc, body) \
+_RS_STATIC type __attribute__((overloadable)) \
+ fnc(type v1, type v2) { \
+ return body; \
+} \
+_RS_STATIC type##2 __attribute__((overloadable)) \
+ fnc(type##2 v1, type##2 v2) { \
+ type##2 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ return r; \
+} \
+_RS_STATIC type##3 __attribute__((overloadable)) \
+ fnc(type##3 v1, type##3 v2) { \
+ type##3 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ return r; \
+} \
+_RS_STATIC type##4 __attribute__((overloadable)) \
+ fnc(type##4 v1, type##4 v2) { \
+ type##4 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ r.w = fnc(v1.w, v2.w); \
+ return r; \
+}
+
+#define IN_FUNC_IN_IN_BODY(fnc, body) \
+XN_FUNC_XN_XN_BODY(uchar, fnc, body) \
+XN_FUNC_XN_XN_BODY(char, fnc, body) \
+XN_FUNC_XN_XN_BODY(ushort, fnc, body) \
+XN_FUNC_XN_XN_BODY(short, fnc, body) \
+XN_FUNC_XN_XN_BODY(uint, fnc, body) \
+XN_FUNC_XN_XN_BODY(int, fnc, body) \
+XN_FUNC_XN_XN_BODY(float, fnc, body)
+
+UIN_FUNC_IN(abs)
+IN_FUNC_IN(clz)
+
+IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2))
+FN_FUNC_FN_F(min)
+
+IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
+FN_FUNC_FN_F(max)
// 6.11.4
@@ -617,7 +726,7 @@ _RS_STATIC float4 __attribute__((overloadable)) clamp(float4 amount, float low,
_RS_STATIC float __attribute__((overloadable)) degrees(float radians) {
return radians * (180.f / M_PI);
}
-DEF_FUNC_1(degrees)
+FN_FUNC_FN(degrees)
_RS_STATIC float __attribute__((overloadable)) mix(float start, float stop, float amount) {
return start + (stop - start) * amount;
@@ -644,7 +753,7 @@ _RS_STATIC float4 __attribute__((overloadable)) mix(float4 start, float4 stop, f
_RS_STATIC float __attribute__((overloadable)) radians(float degrees) {
return degrees * (M_PI / 180.f);
}
-DEF_FUNC_1(radians)
+FN_FUNC_FN(radians)
_RS_STATIC float __attribute__((overloadable)) step(float edge, float v) {
return (v < edge) ? 0.f : 1.f;
@@ -705,7 +814,7 @@ _RS_STATIC float __attribute__((overloadable)) sign(float v) {
if (v < 0) return -1.f;
return v;
}
-DEF_FUNC_1(sign)
+FN_FUNC_FN(sign)
// 6.11.5
_RS_STATIC float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
@@ -779,15 +888,21 @@ _RS_STATIC float4 __attribute__((overloadable)) normalize(float4 v) {
#undef CVT_FUNC
#undef CVT_FUNC_2
-#undef DEF_FUNC_1
-#undef DEF_FUNC_1_RI
-#undef DEF_FUNC_2
-#undef DEF_FUNC_2F
-#undef DEF_RIFUNC_1
-#undef DEF_UIFUNC_1
-#undef DEF_IFUNC_1
-#undef DEF_RIFUNC_2
-#undef DEF_IFUNC_2
+#undef FN_FUNC_FN
+#undef IN_FUNC_FN
+#undef FN_FUNC_FN_FN
+#undef FN_FUNC_FN_F
+#undef FN_FUNC_FN_IN
+#undef FN_FUNC_FN_I
+#undef FN_FUNC_FN_PFN
+#undef FN_FUNC_FN_PIN
+#undef FN_FUNC_FN_FN_FN
+#undef FN_FUNC_FN_FN_PIN
+#undef XN_FUNC_YN
+#undef UIN_FUNC_IN
+#undef IN_FUNC_IN
+#undef XN_FUNC_XN_XN_BODY
+#undef IN_FUNC_IN_IN_BODY
#undef _RS_STATIC
#endif
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index 0f8717fa6c03..a010096507b1 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -3,12 +3,7 @@
#define M_PI 3.14159265358979323846264338327950288f /* pi */
-//#include "external/clang/lib/Headers/stdbool.h"
-#define bool _Bool
-#define true 1
-#define false 0
-#define __bool_true_false_are_defined 1
-
+#include "stdbool.h"
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index af11f97a0ca1..7505d530e0c5 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -58,7 +58,6 @@ SharedBufferStack::SharedBufferStack()
void SharedBufferStack::init(int32_t i)
{
- inUse = -2;
status = NO_ERROR;
identity = i;
}
@@ -199,9 +198,9 @@ String8 SharedBufferBase::dump(char const* prefix) const
SharedBufferStack& stack( *mSharedStack );
snprintf(buffer, SIZE,
"%s[ head=%2d, available=%2d, queued=%2d ] "
- "reallocMask=%08x, inUse=%2d, identity=%d, status=%d",
+ "reallocMask=%08x, identity=%d, status=%d",
prefix, stack.head, stack.available, stack.queued,
- stack.reallocMask, stack.inUse, stack.identity, stack.status);
+ stack.reallocMask, stack.identity, stack.status);
result.append(buffer);
result.append("\n");
return result;
@@ -302,22 +301,6 @@ ssize_t SharedBufferClient::CancelUpdate::operator()() {
return NO_ERROR;
}
-SharedBufferServer::UnlockUpdate::UnlockUpdate(
- SharedBufferBase* sbb, int lockedBuffer)
- : UpdateBase(sbb), lockedBuffer(lockedBuffer) {
-}
-ssize_t SharedBufferServer::UnlockUpdate::operator()() {
- if (stack.inUse != lockedBuffer) {
- LOGE("unlocking %d, but currently locked buffer is %d "
- "(identity=%d, token=%d)",
- lockedBuffer, stack.inUse,
- stack.identity, stack.token);
- return BAD_VALUE;
- }
- android_atomic_write(-1, &stack.inUse);
- return NO_ERROR;
-}
-
SharedBufferServer::RetireUpdate::RetireUpdate(
SharedBufferBase* sbb, int numBuffers)
: UpdateBase(sbb), numBuffers(numBuffers) {
@@ -327,9 +310,6 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() {
if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
return BAD_VALUE;
- // Preventively lock the current buffer before updating queued.
- android_atomic_write(stack.headBuf, &stack.inUse);
-
// Decrement the number of queued buffers
int32_t queued;
do {
@@ -345,7 +325,6 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() {
head = (head + 1) % numBuffers;
const int8_t headBuf = stack.index[head];
stack.headBuf = headBuf;
- android_atomic_write(headBuf, &stack.inUse);
// head is only modified here, so we don't need to use cmpxchg
android_atomic_write(head, &stack.head);
@@ -546,13 +525,6 @@ ssize_t SharedBufferServer::retireAndLock()
return buf;
}
-status_t SharedBufferServer::unlock(int buf)
-{
- UnlockUpdate update(this, buf);
- status_t err = updateCondition( update );
- return err;
-}
-
void SharedBufferServer::setStatus(status_t status)
{
if (status < NO_ERROR) {
@@ -694,12 +666,6 @@ status_t SharedBufferServer::shrink(int newNumBuffers)
stack.head = 0;
stack.headBuf = 0;
- // If one of the buffers is in use it must be the head buffer, which we are
- // renaming to buffer 0.
- if (stack.inUse > 0) {
- stack.inUse = 0;
- }
-
// Free the buffers from the end of the list that are no longer needed.
for (int i = newNumBuffers; i < mNumBuffers; i++) {
mBufferList.remove(i);
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 1663313f2e3f..f24a71d88d9d 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -66,12 +66,6 @@ status_t EGLUtils::selectConfigForPixelFormat(
if (outConfig == NULL)
return BAD_VALUE;
- int err;
- PixelFormatInfo fbFormatInfo;
- if ((err = getPixelFormatInfo(PixelFormat(format), &fbFormatInfo)) < 0) {
- return err;
- }
-
// Get all the "potential match" configs...
if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
@@ -81,23 +75,14 @@ status_t EGLUtils::selectConfigForPixelFormat(
free(configs);
return BAD_VALUE;
}
-
- const int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA);
- const int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED);
- const int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN);
- const int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE);
int i;
EGLConfig config = NULL;
for (i=0 ; i<n ; i++) {
- EGLint r,g,b,a;
- EGLConfig curr = configs[i];
- eglGetConfigAttrib(dpy, curr, EGL_RED_SIZE, &r);
- eglGetConfigAttrib(dpy, curr, EGL_GREEN_SIZE, &g);
- eglGetConfigAttrib(dpy, curr, EGL_BLUE_SIZE, &b);
- eglGetConfigAttrib(dpy, curr, EGL_ALPHA_SIZE, &a);
- if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) {
- config = curr;
+ EGLint nativeVisualId = 0;
+ eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+ if (nativeVisualId>0 && format == nativeVisualId) {
+ config = configs[i];
break;
}
}
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index ce84683375ba..33ef1fc8945c 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -61,7 +61,7 @@ void GraphicBufferAllocator::dump(String8& result) const
const size_t c = list.size();
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
list.keyAt(i), rec.size/1024.0f,
rec.w, rec.s, rec.h, rec.format, rec.usage);
result.append(buffer);
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index b03588fdf462..1c028787bed0 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -93,29 +93,28 @@ public class MediaImageItem extends MediaItem {
*
* @throws IOException
*/
- public MediaImageItem(VideoEditor editor, String mediaItemId,
- String filename, long durationMs,
- int renderingMode) throws IOException {
+ public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
+ int renderingMode) throws IOException {
super(editor, mediaItemId, filename, renderingMode);
mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
mVideoEditor = ((VideoEditorImpl)editor);
try {
- final Properties properties =
- mMANativeHelper.getMediaProperties(filename);
+ final Properties properties = mMANativeHelper.getMediaProperties(filename);
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_JPEG:
+ case MediaProperties.FILE_PNG: {
break;
- case MediaProperties.FILE_PNG:
- break;
+ }
- default:
- throw new IllegalArgumentException("Unsupported Input File Type");
+ default: {
+ throw new IllegalArgumentException("Unsupported Input File Type");
+ }
}
} catch (Exception e) {
- throw new IllegalArgumentException("Unsupported file or file not found");
+ throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
}
/**
@@ -130,13 +129,13 @@ public class MediaImageItem extends MediaItem {
mDurationMs = durationMs;
mDecodedFilename = String.format(mMANativeHelper.getProjectPath() +
"/" + "decoded" + getId()+ ".rgb");
- final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
- final DataOutputStream dos = new DataOutputStream(fl);
+
try {
mAspectRatio = mMANativeHelper.getAspectRatio(mWidth, mHeight);
} catch(IllegalArgumentException e) {
throw new IllegalArgumentException ("Null width and height");
}
+
mGeneratedClipHeight = 0;
mGeneratedClipWidth = 0;
@@ -146,9 +145,12 @@ public class MediaImageItem extends MediaItem {
*/
final Pair<Integer, Integer>[] resolutions =
MediaProperties.getSupportedResolutions(mAspectRatio);
+
/**
* Get the highest resolution
*/
+ final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
+ final DataOutputStream dos = new DataOutputStream(fl);
final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
if (mHeight > maxResolution.second) {
/**
@@ -171,16 +173,16 @@ public class MediaImageItem extends MediaItem {
int mNewHeight = 0;
if ((mScaledWidth % 2 ) != 0) {
mNewWidth = mScaledWidth - 1;
- }
- else {
+ } else {
mNewWidth = mScaledWidth;
}
+
if ((mScaledHeight % 2 ) != 0) {
mNewHeight = mScaledHeight - 1;
- }
- else {
+ } else {
mNewHeight = mScaledHeight;
}
+
final int [] framingBuffer = new int[mNewWidth];
final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
IntBuffer intBuffer;
@@ -195,6 +197,7 @@ public class MediaImageItem extends MediaItem {
dos.write(array);
tmp += 1;
}
+
mScaledWidth = mNewWidth;
mScaledHeight = mNewHeight;
scaledImage.recycle();
@@ -204,10 +207,11 @@ public class MediaImageItem extends MediaItem {
+ "/" + "scaled" + getId()+ ".JPG");
if (!((new File(mScaledFilename)).exists())) {
super.mRegenerateClip = true;
- FileOutputStream f1 = new FileOutputStream(mScaledFilename);
+ final FileOutputStream f1 = new FileOutputStream(mScaledFilename);
scaledImage.compress(Bitmap.CompressFormat.JPEG, 50,f1);
f1.close();
}
+
mScaledWidth = scaledImage.getWidth();
mScaledHeight = scaledImage.getHeight();
@@ -215,17 +219,17 @@ public class MediaImageItem extends MediaItem {
int mNewheight = 0;
if ((mScaledWidth % 2 ) != 0) {
mNewWidth = mScaledWidth - 1;
- }
- else {
+ } else {
mNewWidth = mScaledWidth;
}
+
if ((mScaledHeight % 2 ) != 0) {
mNewheight = mScaledHeight - 1;
- }
- else {
+ } else {
mNewheight = mScaledHeight;
}
- Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
+
+ final Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
final int [] framingBuffer = new int[mNewWidth];
ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
IntBuffer intBuffer;
@@ -240,10 +244,12 @@ public class MediaImageItem extends MediaItem {
dos.write(array);
tmp += 1;
}
+
mScaledWidth = mNewWidth;
mScaledHeight = mNewheight;
imageBitmap.recycle();
}
+
fl.close();
System.gc();
}
@@ -286,7 +292,7 @@ public class MediaImageItem extends MediaItem {
/**
* @return The file name of image which is decoded and stored
- * in rgb format
+ * in RGB format
*/
String getDecodedImageFileName() {
return mDecodedFilename;
@@ -447,7 +453,7 @@ public class MediaImageItem extends MediaItem {
* Check if the effect overlaps with the end transition
*/
if (effect.getStartTime() + effect.getDuration() >
- mDurationMs - transitionDurationMs) {
+ mDurationMs - transitionDurationMs) {
mEndTransition.invalidate();
break;
}
@@ -464,7 +470,7 @@ public class MediaImageItem extends MediaItem {
* Check if the overlay overlaps with the end transition
*/
if (overlay.getStartTime() + overlay.getDuration() >
- mDurationMs - transitionDurationMs) {
+ mDurationMs - transitionDurationMs) {
mEndTransition.invalidate();
break;
}
@@ -648,23 +654,24 @@ public class MediaImageItem extends MediaItem {
for (int i = 0; i < thumbnailCount; i++) {
thumbnailArray[i] = thumbnail;
}
- return thumbnailArray;
-
- }
- else {
+ return thumbnailArray;
+ } else {
if (startMs > endMs) {
throw new IllegalArgumentException("Start time is greater than end time");
}
+
if (endMs > mDurationMs) {
throw new IllegalArgumentException("End time is greater than file duration");
}
+
if (startMs == endMs) {
Bitmap[] bitmap = new Bitmap[1];
bitmap[0] = mMANativeHelper.getPixels(getGeneratedImageClip(),
width, height,startMs);
return bitmap;
}
+
return mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
height,startMs,endMs,thumbnailCount);
}
@@ -704,31 +711,51 @@ public class MediaImageItem extends MediaItem {
*/
if (mBeginTransition != null) {
final long transitionDurationMs = mBeginTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs, 0,
+ transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs, 0,
+ transitionDurationMs);
/**
- * If the start time has changed and if the old or the new item
- * overlaps with the begin transition, invalidate the transition.
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (((oldStartTimeMs != newStartTimeMs)
- || (oldDurationMs != newDurationMs) )&&
- (isOverlapping(oldStartTimeMs, oldDurationMs, 0, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs, 0,
- transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mBeginTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs != newStartTimeMs) ||
+ !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+ newStartTimeMs + newDurationMs > transitionDurationMs)) {
+ mBeginTransition.invalidate();
+ }
}
}
if (mEndTransition != null) {
final long transitionDurationMs = mEndTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+ mDurationMs - transitionDurationMs, transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+ mDurationMs - transitionDurationMs, transitionDurationMs);
/**
- * If the start time + duration has changed and if the old or the new
- * item overlaps the end transition, invalidate the transition
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
- (isOverlapping(oldStartTimeMs, oldDurationMs,
- mDurationMs - transitionDurationMs, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs,
- mDurationMs - transitionDurationMs, transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mEndTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+ ((oldStartTimeMs > mDurationMs - transitionDurationMs) ||
+ newStartTimeMs > mDurationMs - transitionDurationMs)) {
+ mEndTransition.invalidate();
+ }
}
}
}
@@ -743,10 +770,12 @@ public class MediaImageItem extends MediaItem {
setGeneratedImageClip(null);
setRegenerateClip(true);
}
+
if (mScaledFilename != null) {
new File(mScaledFilename).delete();
mScaledFilename = null;
}
+
if (mDecodedFilename != null) {
new File(mDecodedFilename).delete();
mDecodedFilename = null;
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 772b360590b4..2981b41c0b73 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -78,12 +78,9 @@ public class MediaVideoItem extends MediaItem {
*
* @throws IOException if the file cannot be opened for reading
*/
- public MediaVideoItem(VideoEditor editor, String mediaItemId,
- String filename,
- int renderingMode)
- throws IOException {
- this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE,
- 100, false, null);
+ public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
+ int renderingMode) throws IOException {
+ this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);
}
/**
@@ -105,20 +102,22 @@ public class MediaVideoItem extends MediaItem {
* @throws IOException if the file cannot be opened for reading
*/
MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
- int renderingMode,
- long beginMs, long endMs, int volumePercent, boolean muted,
+ int renderingMode, long beginMs, long endMs, int volumePercent, boolean muted,
String audioWaveformFilename) throws IOException {
super(editor, mediaItemId, filename, renderingMode);
+
if (editor instanceof VideoEditorImpl) {
mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
mVideoEditor = ((VideoEditorImpl)editor);
}
- Properties properties = null;
+
+ final Properties properties;
try {
properties = mMANativeHelper.getMediaProperties(filename);
} catch ( Exception e) {
- throw new IllegalArgumentException("Unsupported file or file not found");
+ throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
}
+
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_3GP:
break;
@@ -163,8 +162,7 @@ public class MediaVideoItem extends MediaItem {
mMuted = muted;
mAudioWaveformFilename = audioWaveformFilename;
if (audioWaveformFilename != null) {
- mWaveformData =
- new SoftReference<WaveformData>(
+ mWaveformData = new SoftReference<WaveformData>(
new WaveformData(audioWaveformFilename));
} else {
mWaveformData = null;
@@ -190,9 +188,11 @@ public class MediaVideoItem extends MediaItem {
if (beginMs > mDurationMs) {
throw new IllegalArgumentException("setExtractBoundaries: Invalid start time");
}
+
if (endMs > mDurationMs) {
throw new IllegalArgumentException("setExtractBoundaries: Invalid end time");
}
+
if ((endMs != -1) && (beginMs >= endMs) ) {
throw new IllegalArgumentException("setExtractBoundaries: Start time is greater than end time");
}
@@ -255,18 +255,18 @@ public class MediaVideoItem extends MediaItem {
*/
@Override
public Bitmap getThumbnail(int width, int height, long timeMs) {
- if (timeMs > mDurationMs)
- {
+ if (timeMs > mDurationMs) {
throw new IllegalArgumentException("Time Exceeds duration");
}
- if (timeMs < 0)
- {
+
+ if (timeMs < 0) {
throw new IllegalArgumentException("Invalid Time duration");
}
- if ((width <=0) || (height <= 0))
- {
+
+ if ((width <=0) || (height <= 0)) {
throw new IllegalArgumentException("Invalid Dimensions");
}
+
return mMANativeHelper.getPixels(super.getFilename(),
width, height,timeMs);
}
@@ -280,18 +280,21 @@ public class MediaVideoItem extends MediaItem {
if (startMs > endMs) {
throw new IllegalArgumentException("Start time is greater than end time");
}
+
if (endMs > mDurationMs) {
throw new IllegalArgumentException("End time is greater than file duration");
}
+
if ((height <= 0) || (width <= 0)) {
throw new IllegalArgumentException("Invalid dimension");
}
+
if (startMs == endMs) {
- Bitmap[] bitmap = new Bitmap[1];
- bitmap[0] = mMANativeHelper.getPixels(super.getFilename(),
- width, height,startMs);
+ final Bitmap[] bitmap = new Bitmap[1];
+ bitmap[0] = mMANativeHelper.getPixels(super.getFilename(), width, height,startMs);
return bitmap;
}
+
return mMANativeHelper.getPixelsList(super.getFilename(), width,
height,startMs,endMs,thumbnailCount);
}
@@ -324,40 +327,58 @@ public class MediaVideoItem extends MediaItem {
* {@inheritDoc}
*/
@Override
- void invalidateTransitions(long oldStartTimeMs, long oldDurationMs,
- long newStartTimeMs,
+ void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
long newDurationMs) {
/**
* Check if the item overlaps with the beginning and end transitions
*/
if (mBeginTransition != null) {
final long transitionDurationMs = mBeginTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+ mBeginBoundaryTimeMs, transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+ mBeginBoundaryTimeMs, transitionDurationMs);
/**
- * If the start time has changed and if the old or the new item
- * overlaps with the begin transition, invalidate the transition.
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (((oldStartTimeMs != newStartTimeMs)
- || (oldDurationMs != newDurationMs) )&&
- (isOverlapping(oldStartTimeMs, oldDurationMs,
- mBeginBoundaryTimeMs, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs,
- mBeginBoundaryTimeMs, transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mBeginTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs != newStartTimeMs) ||
+ !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+ newStartTimeMs + newDurationMs > transitionDurationMs)) {
+ mBeginTransition.invalidate();
+ }
}
}
if (mEndTransition != null) {
final long transitionDurationMs = mEndTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+ mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+ mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
/**
- * If the start time + duration has changed and if the old or the new
- * item overlaps the end transition, invalidate the transition
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
- (isOverlapping(oldStartTimeMs, oldDurationMs,
- mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs,
- mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mEndTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+ ((oldStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs) ||
+ newStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs)) {
+ mEndTransition.invalidate();
+ }
}
}
}
@@ -434,7 +455,7 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException("requested time not correct");
}
- Surface surface = surfaceHolder.getSurface();
+ final Surface surface = surfaceHolder.getSurface();
if (surface == null) {
throw new RuntimeException("Surface could not be retrieved from Surface holder");
}
@@ -442,8 +463,7 @@ public class MediaVideoItem extends MediaItem {
if (mFilename != null) {
return mMANativeHelper.renderMediaItemPreviewFrame(surface,
mFilename,timeMs,mWidth,mHeight);
- }
- else {
+ } else {
return 0;
}
}
@@ -462,7 +482,7 @@ public class MediaVideoItem extends MediaItem {
* Audio track
*/
public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
- throws IOException {
+ throws IOException {
int frameDuration = 0;
int sampleCount = 0;
final String projectPath = mMANativeHelper.getProjectPath();
@@ -481,19 +501,17 @@ public class MediaVideoItem extends MediaItem {
* Logic to get frame duration = (no. of frames per sample * 1000)/
* sampling frequency
*/
- if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+ if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AMRNB ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRNB*1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRNB;
- }
- else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+ } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AMRWB ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRWB * 1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRWB;
- }
- else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+ } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AAC_LC ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AAC * 1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
@@ -682,5 +700,4 @@ public class MediaVideoItem extends MediaItem {
return clipSettings;
}
-
}
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 27c41be671d5..0a01fb2e6f78 100755
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -85,6 +85,6 @@ LOCAL_MODULE:= libvideoeditor_jni
# to add this library to the prelink map and set this to true.
LOCAL_PRELINK_MODULE := false
-LOCAL_MODULE_TAGS := eng development
+LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/mediaeditor/VideoEditorLogging.h b/media/jni/mediaeditor/VideoEditorLogging.h
index ca8c0474d9da..c13f6ff8dcc7 100755
--- a/media/jni/mediaeditor/VideoEditorLogging.h
+++ b/media/jni/mediaeditor/VideoEditorLogging.h
@@ -21,12 +21,13 @@
#define VIDEOEDIT_LOG_INDENTATION (3)
+#define VIDEOEDIT_LOG_ERROR __android_log_print
+#define VIDEOEDIT_LOG_EXCEPTION __android_log_print
+
#ifdef VIDEOEDIT_LOGGING_ENABLED
#define VIDEOEDIT_LOG_ALLOCATION __android_log_print
#define VIDEOEDIT_LOG_API __android_log_print
-#define VIDEOEDIT_LOG_ERROR __android_log_print
-#define VIDEOEDIT_LOG_EXCEPTION __android_log_print
#define VIDEOEDIT_LOG_FUNCTION __android_log_print
#define VIDEOEDIT_LOG_RESULT(x,y, ...) LOGI(y, __VA_ARGS__ )
#define VIDEOEDIT_LOG_SETTING __android_log_print
@@ -40,8 +41,6 @@
#define VIDEOEDIT_LOG_ALLOCATION (void)
#define VIDEOEDIT_LOG_API (void)
-#define VIDEOEDIT_LOG_ERROR (void)
-#define VIDEOEDIT_LOG_EXCEPTION (void)
#define VIDEOEDIT_LOG_FUNCTION (void)
#define VIDEOEDIT_LOG_RESULT (void)
#define VIDEOEDIT_LOG_SETTING (void)
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index e66e4b90fbc3..643f6980f39e 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -437,7 +437,7 @@ static int videoEditor_renderPreviewFrame(JNIEnv* pEnv,
VideoEditor_renderPreviewFrameStr frameStr;
M4OSA_Context tnContext = M4OSA_NULL;
const char* pMessage = NULL;
- M4VIFI_ImagePlane *yuvPlane;
+ M4VIFI_ImagePlane *yuvPlane = NULL;
VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
"VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth);
@@ -1179,7 +1179,7 @@ static int removeAlphafromRGB8888 (
}
/** Remove the alpha channel */
- for (int i = 0, j = 0; i < frameSize_argb; i++) {
+ for (size_t i = 0, j = 0; i < frameSize_argb; i++) {
if ((i % 4) == 0) continue;
pFramingCtx->FramingRgb->pac_data[j] = pTmpData[i];
j++;
@@ -2729,7 +2729,7 @@ typedef struct
} M4AM_Buffer;
-M4OSA_UInt8 logLookUp[256]{
+M4OSA_UInt8 logLookUp[256] = {
0,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193,
194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210,
211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220,
@@ -2788,7 +2788,7 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL,
err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead);
if (inputFileHandle == M4OSA_NULL) {
VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
- "M4MA_generateAudioGraphFile: Cannot open input file 0x%x", err);
+ "M4MA_generateAudioGraphFile: Cannot open input file 0x%lx", err);
return err;
}
@@ -2822,7 +2822,7 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL,
bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16);
} else {
VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
- "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%x",\
+ "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%lx",
M4ERR_ALLOC);
return M4ERR_ALLOC;
}
@@ -2862,7 +2862,7 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL,
if (err != M4NO_ERROR) {
// if out value of bytes-read is 0, break
if ( numBytesToRead == 0) {
- VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%x",\
+ VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%lx",
numBytesToRead);
break; /* stop if file is empty or EOF */
}
@@ -2914,7 +2914,7 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL,
} while (numBytesToRead != 0);
- VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%x", volumeValuesCount);
+ VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%lx", volumeValuesCount);
/* if some error occured in fwrite */
if (numBytesToRead != 0) {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 153b2a66fd0d..65df68c4bf00 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1295,12 +1295,6 @@ status_t StagefrightRecorder::setupMPEG4Recording(
status_t err = OK;
sp<MediaWriter> writer = new MPEG4Writer(outputFd);
- // Add audio source first if it exists
- if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
- err = setupAudioEncoder(writer);
- if (err != OK) return err;
- *totalBitRate += mAudioBitRate;
- }
if (mVideoSource == VIDEO_SOURCE_DEFAULT
|| mVideoSource == VIDEO_SOURCE_CAMERA) {
@@ -1332,6 +1326,15 @@ status_t StagefrightRecorder::setupMPEG4Recording(
*totalBitRate += videoBitRate;
}
+ // Audio source is added at the end if it exists.
+ // This help make sure that the "recoding" sound is suppressed for
+ // camcorder applications in the recorded files.
+ if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
+ err = setupAudioEncoder(writer);
+ if (err != OK) return err;
+ *totalBitRate += mAudioBitRate;
+ }
+
if (mInterleaveDurationUs > 0) {
reinterpret_cast<MPEG4Writer *>(writer.get())->
setInterleaveDuration(mInterleaveDurationUs);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 58c4a2e8591e..11ac56ce296e 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -58,6 +58,8 @@ namespace android {
static int64_t kLowWaterMarkUs = 2000000ll; // 2secs
static int64_t kHighWaterMarkUs = 10000000ll; // 10secs
+static const size_t kLowWaterMarkBytes = 40000;
+static const size_t kHighWaterMarkBytes = 200000;
struct AwesomeEvent : public TimedEventQueue::Event {
AwesomeEvent(
@@ -610,9 +612,6 @@ void AwesomePlayer::onBufferingUpdate() {
// We don't know the bitrate of the stream, use absolute size
// limits to maintain the cache.
- const size_t kLowWaterMarkBytes = 40000;
- const size_t kHighWaterMarkBytes = 200000;
-
if ((mFlags & PLAYING) && !eos
&& (cachedDataRemaining < kLowWaterMarkBytes)) {
LOGI("cache is running low (< %d) , pausing.",
@@ -1535,6 +1534,34 @@ status_t AwesomePlayer::finishSetDataSource_l() {
mConnectingDataSource.clear();
dataSource = mCachedSource;
+
+ // We're going to prefill the cache before trying to instantiate
+ // the extractor below, as the latter is an operation that otherwise
+ // could block on the datasource for a significant amount of time.
+ // During that time we'd be unable to abort the preparation phase
+ // without this prefill.
+
+ mLock.unlock();
+
+ for (;;) {
+ status_t finalStatus;
+ size_t cachedDataRemaining =
+ mCachedSource->approxDataRemaining(&finalStatus);
+
+ if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
+ || (mFlags & PREPARE_CANCELLED)) {
+ break;
+ }
+
+ usleep(200000);
+ }
+
+ mLock.lock();
+
+ if (mFlags & PREPARE_CANCELLED) {
+ LOGI("Prepare cancelled while waiting for initial cache fill.");
+ return UNKNOWN_ERROR;
+ }
} else if (!strncasecmp(mUri.string(), "httplive://", 11)) {
String8 uri("http://");
uri.append(mUri.string() + 11);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 06c4c980681a..a47ee3a04264 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -590,6 +590,7 @@ status_t MPEG4Writer::stop() {
status_t err = OK;
int64_t maxDurationUs = 0;
+ int64_t minDurationUs = 0x7fffffffffffffffLL;
for (List<Track *>::iterator it = mTracks.begin();
it != mTracks.end(); ++it) {
status_t status = (*it)->stop();
@@ -601,6 +602,14 @@ status_t MPEG4Writer::stop() {
if (durationUs > maxDurationUs) {
maxDurationUs = durationUs;
}
+ if (durationUs < minDurationUs) {
+ minDurationUs = durationUs;
+ }
+ }
+
+ if (mTracks.size() > 1) {
+ LOGD("Duration from tracks range is [%lld, %lld] us",
+ minDurationUs, maxDurationUs);
}
stopWriterThread();
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 20f16555517a..741aa1ca0124 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
#define LOG_TAG "NuCachedSource2"
#include <utils/Log.h>
@@ -487,4 +488,5 @@ void NuCachedSource2::getDrmInfo(DecryptHandle **handle, DrmManagerClient **clie
String8 NuCachedSource2::getUri() {
return mSource->getUri();
}
+
} // namespace android
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index e731080c8046..f20a4cbcca21 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -438,8 +438,7 @@ rinse_repeat:
if (mSeqNumber < firstSeqNumberInPlaylist
|| mSeqNumber > lastSeqNumberInPlaylist) {
- if (mSeqNumber < firstSeqNumberInPlaylist
- && mPrevBandwidthIndex != (ssize_t)bandwidthIndex) {
+ if (mPrevBandwidthIndex != (ssize_t)bandwidthIndex) {
// Go back to the previous bandwidth.
LOGI("new bandwidth does not have the sequence number "
diff --git a/packages/SystemUI/assets/fonts/AndroidClock.ttf b/packages/SystemUI/assets/fonts/AndroidClock.ttf
index 39451831c1a0..7b550eeda2d8 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock.ttf
Binary files differ
diff --git a/packages/SystemUI/assets/fonts/AndroidClock2.ttf b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
index fa0221ebafb0..a95d5482840c 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock2.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
new file mode 100644
index 000000000000..9812339f04c8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png
new file mode 100644
index 000000000000..4f61511af1ae
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
new file mode 100644
index 000000000000..475712560a74
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
new file mode 100644
index 000000000000..8436f5a9af1e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
new file mode 100644
index 000000000000..60050751fa95
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
new file mode 100644
index 000000000000..83068a9b3f38
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png
new file mode 100644
index 000000000000..e6f2f34a4a65
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
new file mode 100644
index 000000000000..2591521f2cc3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
new file mode 100644
index 000000000000..56a4a1df1d74
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
new file mode 100644
index 000000000000..77546575f3a2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
new file mode 100644
index 000000000000..afc4057471e9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
index dadb0cd3704f..92ffde9988e0 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
index 51d7cc245d70..0cd05a30b737 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
index 335960243cfe..993ea5591c8b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
new file mode 100644
index 000000000000..22d6c797fb47
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
new file mode 100644
index 000000000000..24166dae0e23
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
new file mode 100644
index 000000000000..85d9795d90d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
new file mode 100644
index 000000000000..b389a3505cbc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/panel_notification.png b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
new file mode 100644
index 000000000000..3789f3cc3d9f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
deleted file mode 100755
index e9589d918b5c..000000000000
--- a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml
new file mode 100644
index 000000000000..037132219cb6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.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.
+-->
+
+<bitmap
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/notify_panel_bg_protect"
+ android:tileMode="repeat"
+ />
+
diff --git a/packages/SystemUI/res/drawable/status_bar_item_background.xml b/packages/SystemUI/res/drawable/status_bar_item_background.xml
index 9da92a79751a..3a50aa957b03 100644
--- a/packages/SystemUI/res/drawable/status_bar_item_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_item_background.xml
@@ -20,7 +20,6 @@
>
<item
android:drawable="@drawable/notification_item_background_color"
- android:left="16dp"
/>
</layer-list>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 0533b6f5e66c..852b72974f37 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -78,15 +78,14 @@
</LinearLayout>
<!-- fake space bar zone -->
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/fake_space_bar"
+ <com.android.systemui.statusbar.policy.EventHole android:id="@+id/fake_space_bar"
android:layout_height="match_parent"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:layout_toRightOf="@+id/navigationArea"
android:layout_toLeftOf="@+id/notificationArea"
android:visibility="gone"
- systemui:keyCode="62"
/>
</RelativeLayout>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
index 72e2c0bb863e..5a41421d1bf0 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
@@ -53,7 +53,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
- android:paddingTop="5dp"
android:layout_marginLeft="8dp"
/>
</com.android.systemui.statusbar.tablet.NotificationIconArea>
@@ -63,23 +62,25 @@
android:id="@+id/notificationTrigger"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:gravity="center"
>
<com.android.systemui.statusbar.tablet.HoloClock
android:id="@+id/clock"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
>
<TextView android:id="@+id/time_bg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:singleLine="true"
- android:textSize="72dip"
+ android:textSize="40sp"
android:textColor="#1f1f1f" />
<TextView android:id="@+id/time_fg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:singleLine="true"
- android:textSize="72dip"
+ android:textSize="40sp"
android:textColor="#2e2e2e" />
</com.android.systemui.statusbar.tablet.HoloClock>
@@ -101,14 +102,13 @@
android:id="@+id/signal_battery_cluster"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
android:gravity="center"
>
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="19dp"
android:layout_marginRight="4dp"
>
<ImageView
@@ -126,10 +126,6 @@
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="19dp"
- android:layout_marginLeft="2dp"
- android:layout_marginRight="2dp"
/>
</LinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
index 7f84b21458b5..4cf28eee4e74 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
@@ -18,159 +18,37 @@
<com.android.systemui.statusbar.tablet.NotificationPanel
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:id="@+id/panel_root"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="right"
+ android:background="@drawable/notify_panel_bg_protect_tiled"
>
- <View
- android:id="@+id/scrim"
- android:background="@drawable/notify_panel_bg_protect"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- />
-
<RelativeLayout
android:id="@+id/content_parent"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
>
- <RelativeLayout
- android:id="@+id/title_area"
- android:layout_height="160dp"
- android:layout_width="384dp"
- android:layout_marginLeft="24dp"
- android:paddingTop="20dp"
- android:orientation="vertical"
+
+ <include layout="@layout/status_bar_notification_panel_title"
+ android:layout_width="471dp"
+ android:layout_height="465dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
- android:background="@drawable/panel_notification_tiled"
- >
-
- <com.android.systemui.statusbar.tablet.HoloClock
- android:id="@+id/clock"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_alignParentTop="true"
- android:layout_marginRight="40dip"
- android:layout_marginBottom="4dip"
- >
- <TextView android:id="@+id/time_bg"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="right"
- android:singleLine="true"
- android:textSize="90dip"
- android:textColor="#999999" />
- <TextView android:id="@+id/time_fg"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="right"
- android:singleLine="true"
- android:textSize="90dip"
- android:textColor="#666666" />
- </com.android.systemui.statusbar.tablet.HoloClock>
-
- <com.android.systemui.statusbar.policy.DateView
- android:id="@+id/date"
- style="@style/StatusBarNotificationText"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_below="@id/clock"
- android:layout_marginTop="4dp"
- android:layout_marginRight="48dp"
- android:gravity="right"
- />
-
- <ImageView
- android:id="@+id/battery"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_below="@id/date"
- android:layout_marginLeft="48dp"
- android:layout_marginTop="18dp"
- android:layout_marginRight="8dp"
- android:baseline="15dp"
- />
-
- <TextView
- android:id="@+id/battery_text"
- style="@style/StatusBarNotificationText"
- android:layout_width="56dp"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/battery"
- android:layout_alignBaseline="@id/battery"
- android:singleLine="true"
- android:text="@string/status_bar_settings_settings_button"
- />
-
- <ImageView
- android:id="@+id/network_signal"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_toRightOf="@id/battery_text"
- android:layout_alignBaseline="@id/battery"
- android:layout_marginRight="8dp"
- android:baseline="15dp"
- />
-
- <ImageView
- android:id="@+id/network_type"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_toRightOf="@id/battery_text"
- android:layout_alignBaseline="@id/battery"
- android:layout_marginRight="8dp"
- android:baseline="15dp"
- />
-
- <TextView
- android:id="@+id/network_text"
- style="@style/StatusBarNotificationText"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/network_signal"
- android:layout_alignBaseline="@id/battery"
- android:singleLine="true"
- android:text="@string/status_bar_settings_settings_button"
- />
-
- <ImageView
- android:id="@+id/settings_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@id/battery"
- android:layout_alignParentRight="true"
- android:paddingRight="16dp"
- android:src="@drawable/ic_notification_open"
- android:baseline="21dp"
- />
-
- <ImageView
- android:id="@+id/notification_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignBaseline="@id/battery"
- android:paddingRight="16dp"
- android:visibility="invisible"
- android:src="@drawable/status_bar_veto"
- android:baseline="21dp"
- />
- </RelativeLayout>
+ />
<LinearLayout
android:id="@+id/content_frame"
+ android:background="@drawable/notify_panel_notify_bg"
android:layout_height="wrap_content"
- android:layout_width="408dp"
+ android:layout_width="447dp"
android:orientation="vertical"
- android:layout_below="@id/title_area"
android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="352dp"
>
<ScrollView
android:id="@+id/notification_scroller"
@@ -183,23 +61,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|bottom"
- android:animateLayoutChanges="true"
- android:animationCache="false"
android:orientation="vertical"
android:clickable="true"
android:focusable="true"
android:descendantFocusability="afterDescendants"
- systemui:insetLeft="16dp"
>
</com.android.systemui.statusbar.tablet.NotificationLinearLayout>
</ScrollView>
- <ImageView
- android:id="@+id/notification_glow"
- android:layout_width="match_parent"
- android:layout_height="@dimen/status_bar_panel_bottom_offset"
- android:layout_marginLeft="16dp"
- android:src="@drawable/notify_item_glow_bottom"
- />
</LinearLayout>
</RelativeLayout>
@@ -211,7 +79,7 @@
android:layout_alignTop="@id/content_parent"
android:layout_alignLeft="@id/content_parent"
android:layout_marginLeft="100dip"
- android:layout_marginTop="-100dip"
+ android:layout_marginTop="50dip"
/>
</com.android.systemui.statusbar.tablet.NotificationPanel>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
new file mode 100644
index 000000000000..40f2247753b5
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
@@ -0,0 +1,158 @@
+<!--
+ 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.
+-->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:id="@+id/title_area"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ android:background="@drawable/notify_panel_clock_bg"
+ >
+ <ImageView
+ android:id="@+id/network_signal"
+ android:layout_height="32dp"
+ android:layout_width="32dp"
+ android:scaleType="centerInside"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentBottom="true"
+ android:baseline="22dp"
+ android:layout_marginLeft="32dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="16dp"
+ />
+
+ <ImageView
+ android:id="@+id/network_type"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_alignLeft="@id/network_signal"
+ android:layout_alignBottom="@id/network_signal"
+ android:layout_marginRight="8dp"
+ />
+
+ <TextView
+ android:id="@+id/network_text"
+ style="@style/StatusBarNotificationText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/network_signal"
+ android:layout_marginRight="8dp"
+ android:layout_alignBaseline="@id/network_signal"
+ android:singleLine="true"
+ android:text="@string/status_bar_settings_settings_button"
+ />
+
+ <ImageView
+ android:id="@+id/battery"
+ android:layout_height="32dp"
+ android:layout_width="32dp"
+ android:scaleType="centerInside"
+ android:layout_toRightOf="@id/network_text"
+ android:layout_alignBaseline="@id/network_signal"
+ android:baseline="22dp"
+ />
+
+ <TextView
+ android:id="@+id/battery_text"
+ style="@style/StatusBarNotificationText"
+ android:layout_width="56dp"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/battery"
+ android:layout_alignBaseline="@id/battery"
+ android:layout_marginRight="8dp"
+ android:singleLine="true"
+ android:text="@string/status_bar_settings_settings_button"
+ />
+
+ <ImageView
+ android:id="@+id/settings_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@id/battery"
+ android:layout_alignParentRight="true"
+ android:paddingRight="16dp"
+ android:src="@drawable/ic_notification_open"
+ android:baseline="21dp"
+ />
+
+ <ImageView
+ android:id="@+id/notification_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_alignBaseline="@id/battery"
+ android:paddingRight="16dp"
+ android:visibility="invisible"
+ android:src="@drawable/status_bar_veto"
+ android:baseline="21dp"
+ />
+
+ <View
+ android:id="@+id/title_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginLeft="32dp"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="64dip"
+ android:background="@android:drawable/divider_horizontal_dark"
+ />
+
+ <com.android.systemui.statusbar.tablet.HoloClock
+ android:id="@+id/clock"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_alignParentRight="true"
+ android:layout_above="@id/title_divider"
+ android:layout_marginRight="32dip"
+ android:layout_marginBottom="8dip"
+ >
+ <TextView android:id="@+id/time_bg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:singleLine="true"
+ android:textSize="72sp"
+ android:textColor="#999999" />
+ <TextView android:id="@+id/time_fg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:singleLine="true"
+ android:textSize="72sp"
+ android:textColor="#666666" />
+ </com.android.systemui.statusbar.tablet.HoloClock>
+
+ <com.android.systemui.statusbar.policy.DateView
+ android:id="@+id/date"
+ style="@style/StatusBarNotificationText"
+ android:layout_height="wrap_content"
+ android:layout_width="120dp"
+ android:layout_alignBottom="@id/clock"
+ android:layout_alignParentLeft="true"
+ android:gravity="left"
+ android:layout_marginLeft="32dp"
+ />
+
+ <Button
+ android:id="@+id/mode_toggle"
+ android:background="@null"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
index e97345b1dc72..233cb46f0b85 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
@@ -32,7 +32,6 @@
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/large_icon"
android:layout_toLeftOf="@id/veto"
- android:layout_marginLeft="16dp"
android:focusable="true"
android:clickable="true"
/>
@@ -40,7 +39,6 @@
<View
android:layout_width="match_parent"
android:layout_height="1dp"
- android:layout_marginLeft="16dp"
android:layout_alignParentBottom="true"
android:background="@android:drawable/divider_horizontal_dark"
/>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index 8a477e4f110c..1dbd75980e8e 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -22,8 +22,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/status_bar_item_background"
- android:paddingLeft="16dp"
- android:paddingRight="46dp"
+ android:paddingRight="48dp"
>
<!-- Airplane mode -->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
new file mode 100644
index 000000000000..47e758c58fe6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
@@ -0,0 +1,99 @@
+/*
+ * 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.policy;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Region;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.ServiceManager;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.HapticFeedbackConstants;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewTreeObserver;
+import android.widget.RemoteViews.RemoteView;
+
+import com.android.systemui.R;
+
+public class EventHole extends View implements ViewTreeObserver.OnComputeInternalInsetsListener {
+ private static final String TAG = "StatusBar.EventHole";
+
+ private boolean mWindowVis;
+ private int[] mLoc = new int[2];
+
+ public EventHole(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public EventHole(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ mWindowVis = visibility == View.VISIBLE;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+ }
+
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
+ final boolean visible = isShown() && mWindowVis && getWidth() > 0 && getHeight() > 0;
+ final int[] loc = mLoc;
+ getLocationInWindow(loc);
+ final int l = loc[0];
+ final int r = l + getWidth();
+ final int t = loc[1];
+ final int b = t + getHeight();
+
+ View top = this;
+ while (top.getParent() instanceof View) {
+ top = (View)top.getParent();
+ }
+
+ if (visible) {
+ info.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ info.touchableRegion.set(0, 0, top.getWidth(), top.getHeight());
+ info.touchableRegion.op(l, t, r, b, Region.Op.DIFFERENCE);
+ } else {
+ info.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+ }
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
index 7012ddcbce8d..28f485c1e350 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -124,9 +124,9 @@ public class InputMethodButton extends ImageView {
if (subtype != null) {
return pm.getDrawable(imi.getPackageName(), subtype.getIconResId(),
imi.getServiceInfo().applicationInfo);
- } else if (imi.getSubtypes().size() > 0) {
+ } else if (imi.getSubtypeCount() > 0) {
return pm.getDrawable(imi.getPackageName(),
- imi.getSubtypes().get(0).getIconResId(),
+ imi.getSubtypeAt(0).getIconResId(),
imi.getServiceInfo().applicationInfo);
} else {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index cc200e39d028..a3ccef998099 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -342,9 +342,9 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, O
if (subtype != null) {
return mPackageManager.getDrawable(imi.getPackageName(), subtype.getIconResId(),
imi.getServiceInfo().applicationInfo);
- } else if (imi.getSubtypes().size() > 0) {
+ } else if (imi.getSubtypeCount() > 0) {
return mPackageManager.getDrawable(imi.getPackageName(),
- imi.getSubtypes().get(0).getIconResId(),
+ imi.getSubtypeAt(0).getIconResId(),
imi.getServiceInfo().applicationInfo);
} else {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 45a22b61904d..9f48b483dd25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.tablet;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -32,10 +33,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.systemui.R;
@@ -47,14 +48,14 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
boolean mShowing;
View mTitleArea;
+ View mModeToggle;
View mSettingsButton;
View mNotificationButton;
View mNotificationScroller;
- View mNotificationGlow;
ViewGroup mContentFrame;
- Rect mContentArea;
+ Rect mContentArea = new Rect();
View mSettingsView;
- View mScrim, mGlow;
+ View mGlow;
ViewGroup mContentParent;
Choreographer mChoreo = new Choreographer();
@@ -76,16 +77,15 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
mContentParent = (ViewGroup)findViewById(R.id.content_parent);
mContentParent.bringToFront();
mTitleArea = findViewById(R.id.title_area);
- mTitleArea.setOnClickListener(this);
+ mModeToggle = findViewById(R.id.mode_toggle);
+ mModeToggle.setOnClickListener(this);
- mScrim = findViewById(R.id.scrim);
mGlow = findViewById(R.id.glow);
mSettingsButton = (ImageView)findViewById(R.id.settings_button);
mNotificationButton = (ImageView)findViewById(R.id.notification_button);
mNotificationScroller = findViewById(R.id.notification_scroller);
- mNotificationGlow = findViewById(R.id.notification_glow);
mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
}
@@ -101,7 +101,6 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
} else {
mShowing = show;
setVisibility(show ? View.VISIBLE : View.GONE);
- mChoreo.jumpTo(show);
}
}
@@ -118,60 +117,82 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
super.onVisibilityChanged(v, vis);
// when we hide, put back the notifications
if (!isShown()) {
- switchToNotificationMode();
+ if (mSettingsView != null) removeSettingsView();
+ mNotificationScroller.setVisibility(View.VISIBLE);
+ mNotificationScroller.setAlpha(1f);
mNotificationScroller.scrollTo(0, 0);
+ updatePanelModeButtons();
}
}
- /**
- * We need to be aligned at the bottom. LinearLayout can't do this, so instead,
- * let LinearLayout do all the hard work, and then shift everything down to the bottom.
- */
+ /*
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- mChoreo.setPanelHeight(mContentParent.getHeight());
+
+ if (DEBUG) Slog.d(TAG, String.format("PANEL: onLayout: (%d, %d, %d, %d)", l, t, r, b));
}
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- mContentArea = null;
+
+ if (DEBUG) {
+ Slog.d(TAG, String.format("PANEL: onSizeChanged: (%d -> %d, %d -> %d)",
+ oldw, w, oldh, h));
+ }
}
+ */
public void onClick(View v) {
- if (v == mTitleArea) {
- if (mSettingsView == null) {
- switchToSettingsMode();
- } else {
- switchToNotificationMode();
- }
+ if (v == mModeToggle) {
+ swapPanels();
}
}
- public void switchToSettingsMode() {
- removeSettingsView();
- addSettingsView();
- mSettingsButton.setVisibility(View.INVISIBLE);
- mNotificationScroller.setVisibility(View.GONE);
- mNotificationButton.setVisibility(View.VISIBLE);
- }
+ final static int PANEL_FADE_DURATION = 150;
- public void switchToNotificationMode() {
- removeSettingsView();
- mSettingsButton.setVisibility(View.VISIBLE);
- mNotificationScroller.setVisibility(View.VISIBLE);
- mNotificationButton.setVisibility(View.INVISIBLE);
+ public void swapPanels() {
+ final View toShow, toHide;
+ if (mSettingsView == null) {
+ addSettingsView();
+ toShow = mSettingsView;
+ toHide = mNotificationScroller;
+ } else {
+ toShow = mNotificationScroller;
+ toHide = mSettingsView;
+ }
+ Animator a = ObjectAnimator.ofFloat(toHide, "alpha", 1f, 0f)
+ .setDuration(PANEL_FADE_DURATION);
+ a.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator _a) {
+ toHide.setVisibility(View.GONE);
+ toShow.setVisibility(View.VISIBLE);
+ ObjectAnimator.ofFloat(toShow, "alpha", 0f, 1f)
+ .setDuration(PANEL_FADE_DURATION)
+ .start();
+ if (toHide == mSettingsView) {
+ removeSettingsView();
+ }
+ updatePanelModeButtons();
+ }
+ });
+ a.start();
+ }
+
+ public void updatePanelModeButtons() {
+ final boolean settingsVisible = (mSettingsView != null);
+ mSettingsButton.setVisibility(!settingsVisible ? View.VISIBLE : View.INVISIBLE);
+ mNotificationButton.setVisibility(settingsVisible ? View.VISIBLE : View.INVISIBLE);
}
public boolean isInContentArea(int x, int y) {
- if (mContentArea == null) {
- mContentArea = new Rect(mContentFrame.getLeft(),
- mTitleArea.getTop(),
- mContentFrame.getRight(),
- mContentFrame.getBottom());
- offsetDescendantRectToMyCoords(mContentParent, mContentArea);
- }
+ mContentArea.left = mContentFrame.getLeft() + mContentFrame.getPaddingLeft();
+ mContentArea.top = mTitleArea.getTop() + mTitleArea.getPaddingTop();
+ mContentArea.right = mContentFrame.getRight() - mContentFrame.getPaddingRight();
+ mContentArea.bottom = mContentFrame.getBottom() - mContentFrame.getPaddingBottom();
+ offsetDescendantRectToMyCoords(mContentParent, mContentArea);
return mContentArea.contains(x, y);
}
@@ -182,10 +203,12 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
}
}
+ // NB: it will be invisible until you show it
void addSettingsView() {
LayoutInflater infl = LayoutInflater.from(getContext());
mSettingsView = infl.inflate(R.layout.status_bar_settings_view, mContentFrame, false);
- mContentFrame.addView(mSettingsView, mContentFrame.indexOfChild(mNotificationGlow));
+ mSettingsView.setVisibility(View.GONE);
+ mContentFrame.addView(mSettingsView);
}
private class Choreographer implements Animator.AnimatorListener {
@@ -194,18 +217,21 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
AnimatorSet mContentAnim;
// should group this into a multi-property animation
- final int OPEN_DURATION = 136;
- final int CLOSE_DURATION = 250;
+ final static int OPEN_DURATION = 136;
+ final static int CLOSE_DURATION = 250;
// the panel will start to appear this many px from the end
- final int HYPERSPACE_OFFRAMP = 30;
+ final int HYPERSPACE_OFFRAMP = 100;
Choreographer() {
}
void createAnimation(boolean appearing) {
- Animator bgAnim = ObjectAnimator.ofFloat(mScrim,
- "alpha", mScrim.getAlpha(), appearing ? 1 : 0);
+ // mVisible: previous state; appearing: new state
+
+ View root = findViewById(R.id.panel_root);
+ Animator bgAnim = ObjectAnimator.ofInt(root.getBackground(), "alpha",
+ mVisible ? 255 : 0, appearing ? 255 : 0);
float start, end;
@@ -215,34 +241,33 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
if (appearing) {
// we want to go from near-the-top to the top, unless we're half-open in the right
// general vicinity
- start = (y < HYPERSPACE_OFFRAMP)
- ? y
- : HYPERSPACE_OFFRAMP;
+ start = (y < HYPERSPACE_OFFRAMP) ? y : HYPERSPACE_OFFRAMP;
end = 0;
} else {
start = y;
end = y + HYPERSPACE_OFFRAMP;
}
- Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY", start, end);
+ Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY",
+ start, end);
posAnim.setInterpolator(appearing
- ? new android.view.animation.DecelerateInterpolator(2.0f)
- : new android.view.animation.AccelerateInterpolator(2.0f));
+ ? new android.view.animation.DecelerateInterpolator(1.0f)
+ : new android.view.animation.AccelerateInterpolator(1.0f));
- Animator glowAnim = ObjectAnimator.ofFloat(mGlow, "alpha",
- mGlow.getAlpha(), appearing ? 1.0f : 0.0f);
+ Animator glowAnim = ObjectAnimator.ofInt(mGlow.getBackground(), "alpha",
+ mVisible ? 255 : 0, appearing ? 255 : 0);
glowAnim.setInterpolator(appearing
? new android.view.animation.AccelerateInterpolator(1.0f)
: new android.view.animation.DecelerateInterpolator(1.0f));
mContentAnim = new AnimatorSet();
mContentAnim
- .play(ObjectAnimator.ofFloat(mContentParent, "alpha", mContentParent.getAlpha(),
- appearing ? 1.0f : 0.0f))
- .with(glowAnim)
+ .play(ObjectAnimator.ofFloat(mContentParent, "alpha",
+ mContentParent.getAlpha(), appearing ? 1.0f : 0.0f))
.with(bgAnim)
+ .with(glowAnim)
.with(posAnim)
;
- mContentAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
+ mContentAnim.setDuration((DEBUG?10:1)*(appearing ? OPEN_DURATION : CLOSE_DURATION));
mContentAnim.addListener(this);
}
@@ -252,30 +277,12 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
createAnimation(appearing);
mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mGlow.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mContentAnim.start();
mVisible = appearing;
}
- void jumpTo(boolean appearing) {
-// setBgAlpha(appearing ? 255 : 0);
- mContentParent.setTranslationY(appearing ? 0 : mPanelHeight);
- }
-
- public void setPanelHeight(int h) {
- if (DEBUG) Slog.d(TAG, "panelHeight=" + h);
- mPanelHeight = h;
- if (mPanelHeight == 0) {
- // fully closed, no animation necessary
- } else if (mVisible) {
- if (DEBUG) {
- Slog.d(TAG, "panelHeight not zero but trying to open; scheduling an anim"
- + " to open fully");
- }
- startAnimation(true);
- }
- }
-
public void onAnimationCancel(Animator animation) {
if (DEBUG) Slog.d(TAG, "onAnimationCancel");
// force this to zero so we close the window
@@ -288,6 +295,7 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
setVisibility(View.GONE);
}
mContentParent.setLayerType(View.LAYER_TYPE_NONE, null);
+ mGlow.setLayerType(View.LAYER_TYPE_NONE, null);
mContentAnim = null;
}
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 6db74d133372..a3a58edc89da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -189,7 +189,7 @@ public class TabletStatusBar extends StatusBar implements
mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- 720, // ViewGroup.LayoutParams.MATCH_PARENT,
+ 512, // ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
diff --git a/packages/VpnServices/Android.mk b/packages/VpnServices/Android.mk
deleted file mode 100644
index 6cdf67438ed8..000000000000
--- a/packages/VpnServices/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES :=
-
-LOCAL_PACKAGE_NAME := VpnServices
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
-
-########################
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/VpnServices/AndroidManifest.xml b/packages/VpnServices/AndroidManifest.xml
deleted file mode 100644
index 6092e302c9bf..000000000000
--- a/packages/VpnServices/AndroidManifest.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.vpn"
- android:sharedUserId="android.uid.system"
- >
- <application android:label="@string/app_label">
-
- <service android:name=".VpnServiceBinder" android:process=":remote">
- <intent-filter>
- <!-- These are the interfaces supported by the service, which
- you can bind to. -->
- <action android:name="android.net.vpn.IVpnService" />
- <!-- This is an action code you can use to select the service
- without explicitly supplying the implementation class. -->
- <action android:name="android.net.vpn.SERVICE" />
- </intent-filter>
- </service>
-
- </application>
-
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
-</manifest>
diff --git a/packages/VpnServices/MODULE_LICENSE_APACHE2 b/packages/VpnServices/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/packages/VpnServices/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/packages/VpnServices/NOTICE b/packages/VpnServices/NOTICE
deleted file mode 100644
index c5b1efa7aac7..000000000000
--- a/packages/VpnServices/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-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.
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/packages/VpnServices/res/values-ar/strings.xml b/packages/VpnServices/res/values-ar/strings.xml
deleted file mode 100644
index 6bac1200a17a..000000000000
--- a/packages/VpnServices/res/values-ar/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"خدمات الشبكة الظاهرية الخاصة (VPN)"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"تم توصيل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"تم فصل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"يمكنك اللمس لإعادة الاتصال بالشبكة الظاهرية الخاصة (VPN)."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-bg/strings.xml b/packages/VpnServices/res/values-bg/strings.xml
deleted file mode 100644
index fdcbf640f4dd..000000000000
--- a/packages/VpnServices/res/values-bg/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN услуги"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе установена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе прекъсната"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Докоснете за повторно свързване с VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ca/strings.xml b/packages/VpnServices/res/values-ca/strings.xml
deleted file mode 100644
index b37790ab55cc..000000000000
--- a/packages/VpnServices/res/values-ca/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Serveis VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconnectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toqueu-ho per tornar-vos a connectar a una VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-cs/strings.xml b/packages/VpnServices/res/values-cs/strings.xml
deleted file mode 100644
index 96d4cc5362c4..000000000000
--- a/packages/VpnServices/res/values-cs/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Služby VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je připojena"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojena"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotykem se znovu připojíte k síti VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-da/strings.xml b/packages/VpnServices/res/values-da/strings.xml
deleted file mode 100644
index 0f05bbc46938..000000000000
--- a/packages/VpnServices/res/values-da/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN forbundet"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN afbrudt"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryk for at oprette forbindelse til et VPN igen."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-de/strings.xml b/packages/VpnServices/res/values-de/strings.xml
deleted file mode 100644
index b907be8b579f..000000000000
--- a/packages/VpnServices/res/values-de/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN-Dienste"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> mit VPN verbunden"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> von VPN getrennt"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Zur Wiederherstellung der Verbindung mit einem VPN berühren"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-el/strings.xml b/packages/VpnServices/res/values-el/strings.xml
deleted file mode 100644
index d96f3e015a04..000000000000
--- a/packages/VpnServices/res/values-el/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Υπηρεσίες VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> συνδέθηκε"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> αποσυνδέθηκε"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Πατήστε για να επανασυνδεθείτε σε ένα VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-en-rGB/strings.xml b/packages/VpnServices/res/values-en-rGB/strings.xml
deleted file mode 100644
index 905c2652be5d..000000000000
--- a/packages/VpnServices/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN Services"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN connected"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN disconnected"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Touch to reconnect to a VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-es-rUS/strings.xml b/packages/VpnServices/res/values-es-rUS/strings.xml
deleted file mode 100644
index 8f5053c15cf0..000000000000
--- a/packages/VpnServices/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN conectados"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocar para volver a conectarse a una VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-es/strings.xml b/packages/VpnServices/res/values-es/strings.xml
deleted file mode 100644
index 91824599a958..000000000000
--- a/packages/VpnServices/res/values-es/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toca para volver a conectarte a una red VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fa/strings.xml b/packages/VpnServices/res/values-fa/strings.xml
deleted file mode 100644
index 7cee16d2fedf..000000000000
--- a/packages/VpnServices/res/values-fa/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"سرویس های VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN وصل شد"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN قطع شد"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"برای اتصال مجدد به VPN لمس کنید."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fi/strings.xml b/packages/VpnServices/res/values-fi/strings.xml
deleted file mode 100644
index b15202aae76c..000000000000
--- a/packages/VpnServices/res/values-fi/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN-palvelut"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys muodostettu"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys katkaistu"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Yhdistä VPN-verkkoon uudelleen koskettamalla."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fr/strings.xml b/packages/VpnServices/res/values-fr/strings.xml
deleted file mode 100644
index 4a93e0ad7863..000000000000
--- a/packages/VpnServices/res/values-fr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Services VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connecté"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> déconnecté"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Touchez l\'écran pour vous reconnecter à un VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-hr/strings.xml b/packages/VpnServices/res/values-hr/strings.xml
deleted file mode 100644
index aedb536adf4d..000000000000
--- a/packages/VpnServices/res/values-hr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN usluge"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN priključen"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN je isključen"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotaknite za ponovno povezivanje s VPN-om."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-hu/strings.xml b/packages/VpnServices/res/values-hu/strings.xml
deleted file mode 100644
index 44f542782a7e..000000000000
--- a/packages/VpnServices/res/values-hu/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN-szolgáltatások"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Kapcsolódva a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózathoz"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Kapcsolat bontva a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózattal"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Érintse meg az újracsatlakozáshoz."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-in/strings.xml b/packages/VpnServices/res/values-in/strings.xml
deleted file mode 100644
index 8b6b4c24663a..000000000000
--- a/packages/VpnServices/res/values-in/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Layanan VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> terhubung"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> terputus"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Sentuh untuk terhubung kembali ke suatu VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-it/strings.xml b/packages/VpnServices/res/values-it/strings.xml
deleted file mode 100644
index 1c7a5889a30b..000000000000
--- a/packages/VpnServices/res/values-it/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Servizi VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> collegata"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> scollegata"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocca per riconnetterti a una rete VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-iw/strings.xml b/packages/VpnServices/res/values-iw/strings.xml
deleted file mode 100644
index 74971d6d99cc..000000000000
--- a/packages/VpnServices/res/values-iw/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"שירותי VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> מחובר"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> נותק"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"גע כדי להתחבר שוב ל-VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ja/strings.xml b/packages/VpnServices/res/values-ja/strings.xml
deleted file mode 100644
index 548d8a987e06..000000000000
--- a/packages/VpnServices/res/values-ja/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPNサービス"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが接続されました"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが切断されました"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"タップしてVPNに再接続してください。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ko/strings.xml b/packages/VpnServices/res/values-ko/strings.xml
deleted file mode 100644
index 4185291eb7ef..000000000000
--- a/packages/VpnServices/res/values-ko/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN 서비스"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결됨"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결 끊김"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"VPN에 다시 연결하려면 터치하세요."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-lt/strings.xml b/packages/VpnServices/res/values-lt/strings.xml
deleted file mode 100644
index 58f1f58c0c93..000000000000
--- a/packages/VpnServices/res/values-lt/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPT paslaugos"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT prijungtas"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT atjungtas"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Palieskite, kad būtų iš naujo sujungta su VPT."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-lv/strings.xml b/packages/VpnServices/res/values-lv/strings.xml
deleted file mode 100644
index cb80908c4b99..000000000000
--- a/packages/VpnServices/res/values-lv/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN pakalpojumi"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN ir savienots"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN ir atvienots"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Pieskarieties, lai atkārtoti izveidotu savienojumu ar VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-nb/strings.xml b/packages/VpnServices/res/values-nb/strings.xml
deleted file mode 100644
index 4790600eba12..000000000000
--- a/packages/VpnServices/res/values-nb/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Koblet til VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Koblet fra VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Trykk for å koble til et VPN på nytt"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-nl/strings.xml b/packages/VpnServices/res/values-nl/strings.xml
deleted file mode 100644
index 175c7ddc324f..000000000000
--- a/packages/VpnServices/res/values-nl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN-services"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> verbonden via VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN-verbinding met <xliff:g id="PROFILENAME">%s</xliff:g> verbroken"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Raak aan om opnieuw verbinding te maken met een VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pl/strings.xml b/packages/VpnServices/res/values-pl/strings.xml
deleted file mode 100644
index 565d2497eabb..000000000000
--- a/packages/VpnServices/res/values-pl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Usługi VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Połączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Rozłączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotknij, aby ponownie połączyć się z siecią VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pt-rPT/strings.xml b/packages/VpnServices/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 020188f3ed3d..000000000000
--- a/packages/VpnServices/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Serviços VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> ligado"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desligado"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para voltar a ligar a uma VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pt/strings.xml b/packages/VpnServices/res/values-pt/strings.xml
deleted file mode 100644
index f47652ac580b..000000000000
--- a/packages/VpnServices/res/values-pt/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Serviços de VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para reconectar-se a uma VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-rm/strings.xml b/packages/VpnServices/res/values-rm/strings.xml
deleted file mode 100644
index 80f281709be3..000000000000
--- a/packages/VpnServices/res/values-rm/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Servetschs VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connectà"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> deconnectà"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tutgar per reconnectar ad in VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ro/strings.xml b/packages/VpnServices/res/values-ro/strings.xml
deleted file mode 100644
index a22792cb2604..000000000000
--- a/packages/VpnServices/res/values-ro/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Servicii VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectat"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> deconectat"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Atingeţi pentru a vă reconecta la o reţea VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ru/strings.xml b/packages/VpnServices/res/values-ru/strings.xml
deleted file mode 100644
index 8a839c307112..000000000000
--- a/packages/VpnServices/res/values-ru/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Службы VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) подключена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) отключена"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Нажмите, чтобы повторно подключиться к VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sk/strings.xml b/packages/VpnServices/res/values-sk/strings.xml
deleted file mode 100644
index 167b6f389e44..000000000000
--- a/packages/VpnServices/res/values-sk/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Služby VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je pripojená"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojená"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotykom sa znova pripojíte k sieti VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sl/strings.xml b/packages/VpnServices/res/values-sl/strings.xml
deleted file mode 100644
index c5b72c4459e0..000000000000
--- a/packages/VpnServices/res/values-sl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Storitve VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN profila <xliff:g id="PROFILENAME">%s</xliff:g> je povezan"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN profila <xliff:g id="PROFILENAME">%s</xliff:g> je izklopljen"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotaknite se, če želite preklopiti v navidezno zasebno omrežje."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sr/strings.xml b/packages/VpnServices/res/values-sr/strings.xml
deleted file mode 100644
index bfe6cc88fc8a..000000000000
--- a/packages/VpnServices/res/values-sr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN услуге"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је успостављена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је прекинута"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Додирните да бисте се поново повезали са VPN-ом."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sv/strings.xml b/packages/VpnServices/res/values-sv/strings.xml
deleted file mode 100644
index 24f9f58323e3..000000000000
--- a/packages/VpnServices/res/values-sv/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN-tjänster"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN anslutet"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN frånkopplat"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryck här om du vill återansluta till ett VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-th/strings.xml b/packages/VpnServices/res/values-th/strings.xml
deleted file mode 100644
index 3aa9c6ea8892..000000000000
--- a/packages/VpnServices/res/values-th/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"บริการ VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> เชื่อมต่อ VPN แล้ว"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> ตัดการเชื่อมต่อ VPN แล้ว"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"แตะเพื่อเชื่อมต่อกับ VPN อีกครั้ง"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-tl/strings.xml b/packages/VpnServices/res/values-tl/strings.xml
deleted file mode 100644
index bd988a1c3d1c..000000000000
--- a/packages/VpnServices/res/values-tl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Mga serbisyo ng VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Hindi konektado ang <xliff:g id="PROFILENAME">%s</xliff:g> VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Hindi konektado ang <xliff:g id="PROFILENAME">%s</xliff:g> VPN"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Galawin upang muling kumonekta sa VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-tr/strings.xml b/packages/VpnServices/res/values-tr/strings.xml
deleted file mode 100644
index 8666b35a7e37..000000000000
--- a/packages/VpnServices/res/values-tr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN Hizmetleri"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlandı"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlantısı kesildi"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Bir VPN\'ye tekrar bağlanmak için dokunun."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-uk/strings.xml b/packages/VpnServices/res/values-uk/strings.xml
deleted file mode 100644
index 208659a40cb4..000000000000
--- a/packages/VpnServices/res/values-uk/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Служби VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> підключ. ч-з VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> роз\'єднано"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Натисн. для повт. з\'єдн. з VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-vi/strings.xml b/packages/VpnServices/res/values-vi/strings.xml
deleted file mode 100644
index 3022c9c02494..000000000000
--- a/packages/VpnServices/res/values-vi/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"Dịch vụ VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Đã kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Đã ngắt kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Chạm để kết nối lại với VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-zh-rCN/strings.xml b/packages/VpnServices/res/values-zh-rCN/strings.xml
deleted file mode 100644
index cad08e15366a..000000000000
--- a/packages/VpnServices/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"虚拟专用网服务"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”已连接"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”连接已断开"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"轻触可重新连接到虚拟专用网。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-zh-rTW/strings.xml b/packages/VpnServices/res/values-zh-rTW/strings.xml
deleted file mode 100644
index ee5a42b51c98..000000000000
--- a/packages/VpnServices/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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="app_label" msgid="4589592829302498102">"VPN 服務"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已連線"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已中斷連線"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"輕觸即可重新連線至 VPN。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values/strings.xml b/packages/VpnServices/res/values/strings.xml
deleted file mode 100755
index d82f52a69d45..000000000000
--- a/packages/VpnServices/res/values/strings.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Title for the VPN Services activity. -->
- <string name="app_label">VPN Services</string>
-
- <string name="vpn_notification_title_connected"><xliff:g id="profilename">%s</xliff:g> VPN connected</string>
- <string name="vpn_notification_title_disconnected"><xliff:g id="profilename">%s</xliff:g> VPN disconnected</string>
- <string name="vpn_notification_hint_disconnected">Touch to reconnect to a VPN.</string>
-</resources>
-
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
deleted file mode 100644
index eeafd5a1639c..000000000000
--- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
+++ /dev/null
@@ -1,188 +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.
- */
-
-package com.android.server.vpn;
-
-import android.app.Service;
-import android.content.Intent;
-import android.net.vpn.IVpnService;
-import android.net.vpn.L2tpIpsecProfile;
-import android.net.vpn.L2tpIpsecPskProfile;
-import android.net.vpn.L2tpProfile;
-import android.net.vpn.PptpProfile;
-import android.net.vpn.VpnManager;
-import android.net.vpn.VpnProfile;
-import android.net.vpn.VpnState;
-import android.os.Environment;
-import android.os.IBinder;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * The service class for managing a VPN connection. It implements the
- * {@link IVpnService} binder interface.
- */
-public class VpnServiceBinder extends Service {
- private static final String TAG = VpnServiceBinder.class.getSimpleName();
- private static final boolean DBG = true;
-
- private static final String STATES_FILE_RELATIVE_PATH = "/misc/vpn/.states";
-
- // The actual implementation is delegated to the VpnService class.
- private VpnService<? extends VpnProfile> mService;
-
- // TODO(oam): Test VPN when EFS is enabled (will do later)...
- private static String getStateFilePath() {
- // This call will return the correcu directory whether Encrypted FS is enabled or not
- // Disabled: /data/misc/vpn/.states Enabled: /data/secure/misc/vpn/.states
- return Environment.getSecureDataDirectory().getPath() + STATES_FILE_RELATIVE_PATH;
- }
-
- private final IBinder mBinder = new IVpnService.Stub() {
- public boolean connect(VpnProfile p, String username, String password) {
- return VpnServiceBinder.this.connect(p, username, password);
- }
-
- public void disconnect() {
- VpnServiceBinder.this.disconnect();
- }
-
- public void checkStatus(VpnProfile p) {
- VpnServiceBinder.this.checkStatus(p);
- }
- };
-
- @Override
- public void onCreate() {
- super.onCreate();
- checkSavedStates();
- }
-
-
- @Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- void saveStates() throws IOException {
- if (DBG) Log.d("VpnServiceBinder", " saving states");
- ObjectOutputStream oos =
- new ObjectOutputStream(new FileOutputStream(getStateFilePath()));
- oos.writeObject(mService);
- oos.close();
- }
-
- void removeStates() {
- try {
- File f = new File(getStateFilePath());
- if (f.exists()) f.delete();
- } catch (Throwable e) {
- if (DBG) Log.d("VpnServiceBinder", " remove states: " + e);
- }
- }
-
- private synchronized boolean connect(final VpnProfile p,
- final String username, final String password) {
- if (mService != null) return false;
- final VpnService s = mService = createService(p);
-
- new Thread(new Runnable() {
- public void run() {
- s.onConnect(username, password);
- }
- }).start();
- return true;
- }
-
- private synchronized void disconnect() {
- if (mService == null) return;
- final VpnService s = mService;
-
- new Thread(new Runnable() {
- public void run() {
- s.onDisconnect();
- }
- }).start();
- }
-
- private synchronized void checkStatus(VpnProfile p) {
- if ((mService == null)
- || (!p.getName().equals(mService.mProfile.getName()))) {
- broadcastConnectivity(p.getName(), VpnState.IDLE);
- } else {
- broadcastConnectivity(p.getName(), mService.getState());
- }
- }
-
- private void checkSavedStates() {
- try {
- ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
- getStateFilePath()));
- mService = (VpnService<? extends VpnProfile>) ois.readObject();
- mService.recover(this);
- ois.close();
- } catch (FileNotFoundException e) {
- // do nothing
- } catch (Throwable e) {
- Log.i("VpnServiceBinder", "recovery error, remove states: " + e);
- removeStates();
- }
- }
-
- private VpnService<? extends VpnProfile> createService(VpnProfile p) {
- switch (p.getType()) {
- case L2TP:
- L2tpService l2tp = new L2tpService();
- l2tp.setContext(this, (L2tpProfile) p);
- return l2tp;
-
- case PPTP:
- PptpService pptp = new PptpService();
- pptp.setContext(this, (PptpProfile) p);
- return pptp;
-
- case L2TP_IPSEC_PSK:
- L2tpIpsecPskService psk = new L2tpIpsecPskService();
- psk.setContext(this, (L2tpIpsecPskProfile) p);
- return psk;
-
- case L2TP_IPSEC:
- L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
- l2tpIpsec.setContext(this, (L2tpIpsecProfile) p);
- return l2tpIpsec;
-
- default:
- return null;
- }
- }
-
- private void broadcastConnectivity(String name, VpnState s) {
- new VpnManager(this).broadcastConnectivity(name, s);
- }
-}
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index eb4d930e3f85..5b80a93ab9d5 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -100,17 +100,27 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
+ // TODO: re-enable on phones with keyboards
+ final boolean isPhysicalKbShowing = false;
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
mKeyboardViewAlpha = (PasswordEntryKeyboardView) findViewById(R.id.keyboardAlpha);
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
mPasswordEntry.setOnEditorActionListener(this);
+ mPasswordEntry.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ if (mIsAlpha && !isPhysicalKbShowing) {
+ mKeyboardViewAlpha.setVisibility(
+ mKeyboardViewAlpha.getVisibility() == View.VISIBLE
+ ? View.GONE : View.VISIBLE);
+ mCallback.pokeWakelock();
+ }
+ }
+ });
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
mEmergencyCallButton.setOnClickListener(this);
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
- // TODO: re-enable on phones with keyboards
- boolean isPhysicalKbShowing = false;
//mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
if (mKeyboardViewAlpha == null || !mIsAlpha) {
mKeyboardHelper.setKeyboardMode(mIsAlpha ?
@@ -123,24 +133,21 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
mKeyboardHelperAlpha.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
mKeyboardView.setVisibility(View.GONE);
- mKeyboardViewAlpha.setVisibility(isPhysicalKbShowing ? View.INVISIBLE : View.VISIBLE);
mPasswordEntry.setWidth(mKeyboardViewAlpha.getLayoutParams().width);
}
- mPasswordEntry.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0,
- 0, 0);
mPasswordEntry.requestFocus();
// This allows keyboards with overlapping qwerty/numeric keys to choose just the
// numeric keys.
if (mIsAlpha) {
mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
- mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code,
- StatusView.LOCK_ICON);
+ // mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code,
+ // StatusView.LOCK_ICON);
} else {
mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
- mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code,
- StatusView.LOCK_ICON);
+ //mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code,
+ // StatusView.LOCK_ICON);
}
mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 16c042d646e6..11ad4e468a9a 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -5443,19 +5443,21 @@ void AudioFlinger::EffectModule::process()
// clear auxiliary effect input buffer for next accumulation
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
- memset(mConfig.inputCfg.buffer.raw, 0, mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
+ memset(mConfig.inputCfg.buffer.raw, 0,
+ mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
}
} else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
- mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw){
- // If an insert effect is idle and input buffer is different from output buffer, copy input to
- // output
+ mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
+ // If an insert effect is idle and input buffer is different from output buffer,
+ // accumulate input onto output
sp<EffectChain> chain = mChain.promote();
if (chain != 0 && chain->activeTracks() != 0) {
- size_t size = mConfig.inputCfg.buffer.frameCount * sizeof(int16_t);
- if (mConfig.inputCfg.channels == CHANNEL_STEREO) {
- size *= 2;
+ size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2; //always stereo here
+ int16_t *in = mConfig.inputCfg.buffer.s16;
+ int16_t *out = mConfig.outputCfg.buffer.s16;
+ for (size_t i = 0; i < frameCnt; i++) {
+ out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]);
}
- memcpy(mConfig.outputCfg.buffer.raw, mConfig.inputCfg.buffer.raw, size);
}
}
}
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 8e9a5a4aa98f..2e832568cf90 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -744,7 +744,7 @@ SwitchInputMapper::~SwitchInputMapper() {
}
uint32_t SwitchInputMapper::getSources() {
- return 0;
+ return AINPUT_SOURCE_SWITCH;
}
void SwitchInputMapper::process(const RawEvent* rawEvent) {
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 775747ca67cf..98d627d300dc 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -1484,7 +1484,7 @@ TEST_F(SwitchInputMapperTest, GetSources) {
SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
addMapperAndConfigure(mapper);
- ASSERT_EQ(uint32_t(0), mapper->getSources());
+ ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources());
}
TEST_F(SwitchInputMapperTest, GetSwitchState) {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 2321e30f3f5c..bd3c554a5be5 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -32,6 +32,7 @@ import android.net.NetworkStateTracker;
import android.net.NetworkUtils;
import android.net.Proxy;
import android.net.ProxyProperties;
+import android.net.vpn.VpnManager;
import android.net.wifi.WifiStateTracker;
import android.os.Binder;
import android.os.Handler;
@@ -442,6 +443,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
mSettingsObserver.observe(mContext);
loadGlobalProxy();
+
+ VpnManager.startVpnService(context);
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 4d406209e74b..48c21b28d063 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -118,7 +118,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private static final int NOT_A_SUBTYPE_ID = -1;
private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID);
- private static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_MODE_VOICE = "voice";
@@ -576,7 +575,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (!allowsImplicitlySelectedSubtypes || enabledSubtypes.size() > 0) {
return enabledSubtypes;
} else {
- return getApplicableSubtypesLocked(mRes, imi.getSubtypes());
+ return getApplicableSubtypesLocked(mRes, getSubtypes(imi));
}
}
}
@@ -1015,10 +1014,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
if (id.equals(mCurMethodId)) {
- ArrayList<InputMethodSubtype> subtypes = info.getSubtypes();
InputMethodSubtype subtype = null;
- if (subtypeId >= 0 && subtypeId < subtypes.size()) {
- subtype = subtypes.get(subtypeId);
+ if (subtypeId >= 0 && subtypeId < info.getSubtypeCount()) {
+ subtype = info.getSubtypeAt(subtypeId);
}
if (subtype != mCurrentSubtype) {
synchronized (mMethodMap) {
@@ -1544,6 +1542,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
& ApplicationInfo.FLAG_SYSTEM) != 0;
}
+ private static ArrayList<InputMethodSubtype> getSubtypes(InputMethodInfo imi) {
+ ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int i = 0; i < subtypeCount; ++i) {
+ subtypes.add(imi.getSubtypeAt(i));
+ }
+ return subtypes;
+ }
+
private boolean chooseNewDefaultIMELocked() {
List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
if (enabled != null && enabled.size() > 0) {
@@ -1640,12 +1647,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private void showInputMethodAndSubtypeEnabler(String inputMethodId) {
- Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER);
+ Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (!TextUtils.isEmpty(inputMethodId)) {
- intent.putExtra(EXTRA_INPUT_METHOD_ID, inputMethodId);
+ intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, inputMethodId);
}
mContext.startActivity(intent);
}
@@ -1681,7 +1688,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
ArrayList<String> subtypes = immis.get(i).second;
if (subtypes != null && subtypes.size() == 0) {
ArrayList<InputMethodSubtype> applicableSubtypes =
- getApplicableSubtypesLocked(mRes, imi.getSubtypes());
+ getApplicableSubtypesLocked(mRes, getSubtypes(imi));
final int numSubtypes = applicableSubtypes.size();
for (int j = 0; j < numSubtypes; ++j) {
subtypes.add(String.valueOf(applicableSubtypes.get(j).hashCode()));
@@ -1711,11 +1718,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (property == null) {
continue;
}
- ArrayList<InputMethodSubtype> subtypes = property.getSubtypes();
CharSequence label = property.loadLabel(pm);
if (showSubtypes && enabledSubtypeSet.size() > 0) {
- for (int j = 0; j < subtypes.size(); ++j) {
- InputMethodSubtype subtype = subtypes.get(j);
+ final int subtypeCount = property.getSubtypeCount();
+ for (int j = 0; j < subtypeCount; ++j) {
+ InputMethodSubtype subtype = property.getSubtypeAt(j);
if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))) {
CharSequence title;
int nameResId = subtype.getNameResId();
@@ -1791,7 +1798,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
hideInputMethodMenu();
if (im != null) {
if ((subtypeId < 0)
- || (subtypeId >= im.getSubtypes().size())) {
+ || (subtypeId >= im.getSubtypeCount())) {
subtypeId = NOT_A_SUBTYPE_ID;
}
setInputMethodLocked(im.getId(), subtypeId);
@@ -1916,10 +1923,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
mCurrentSubtype = null;
} else {
- final ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
- if (subtypeId < subtypes.size()) {
- mSettings.putSelectedSubtype(subtypes.get(subtypeId).hashCode());
- mCurrentSubtype = subtypes.get(subtypeId);
+ if (subtypeId < imi.getSubtypeCount()) {
+ InputMethodSubtype subtype = imi.getSubtypeAt(subtypeId);
+ mSettings.putSelectedSubtype(subtype.hashCode());
+ mCurrentSubtype = subtype;
} else {
mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
mCurrentSubtype = null;
@@ -1967,9 +1974,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
if (imi != null) {
- ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
- for (int i = 0; i < subtypes.size(); ++i) {
- InputMethodSubtype ims = subtypes.get(i);
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int i = 0; i < subtypeCount; ++i) {
+ InputMethodSubtype ims = imi.getSubtypeAt(i);
if (subtypeHashCode == ims.hashCode()) {
return i;
}
@@ -2113,13 +2120,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// 4. Search by the current subtype's locale from all subtypes.
if (subtype == null && mCurrentSubtype != null) {
subtype = findLastResortApplicableSubtypeLocked(
- mRes, imi.getSubtypes(), mode, mCurrentSubtype.getLocale(), false);
+ mRes, getSubtypes(imi), mode, mCurrentSubtype.getLocale(), false);
}
// 5. Search by the system locale from all subtypes.
// 6. Search the first enabled subtype matched with mode from all subtypes.
if (subtype == null) {
subtype = findLastResortApplicableSubtypeLocked(
- mRes, imi.getSubtypes(), mode, null, true);
+ mRes, getSubtypes(imi), mode, null, true);
}
if (subtype != null) {
if (imiId.equals(mCurMethodId)) {
@@ -2197,7 +2204,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
} else {
mCurrentSubtype =
- mMethodMap.get(lastInputMethodId).getSubtypes().get(subtypeId);
+ getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId);
}
}
return mCurrentSubtype;
@@ -2320,8 +2327,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
for (Pair<String, ArrayList<String>> imsPair : imsList) {
InputMethodInfo info = mMethodMap.get(imsPair.first);
if (info != null && info.getId().equals(imi.getId())) {
- ArrayList<InputMethodSubtype> subtypes = info.getSubtypes();
- for (InputMethodSubtype ims: subtypes) {
+ final int subtypeCount = info.getSubtypeCount();
+ for (int i = 0; i < subtypeCount; ++i) {
+ InputMethodSubtype ims = info.getSubtypeAt(i);
for (String s: imsPair.second) {
if (String.valueOf(ims.hashCode()).equals(s)) {
enabledSubtypes.add(ims);
@@ -2561,9 +2569,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
InputMethodInfo ime = mMethodMap.get(imeId);
// If IME is enabled and no subtypes are enabled, applicable subtypes
// are enabled implicitly, so needs to treat them to be enabled.
- if (ime != null && ime.getSubtypes().size() > 0) {
+ if (ime != null && ime.getSubtypeCount() > 0) {
List<InputMethodSubtype> implicitlySelectedSubtypes =
- getApplicableSubtypesLocked(mRes, ime.getSubtypes());
+ getApplicableSubtypesLocked(mRes, getSubtypes(ime));
if (implicitlySelectedSubtypes != null) {
final int N = implicitlySelectedSubtypes.size();
for (int i = 0; i < N; ++i) {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3e930aeb085d..2af291dadd32 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -583,7 +583,7 @@ public class WindowManagerService extends IWindowManager.Stub
void broadcastDragStartedLw(final float touchX, final float touchY) {
// Cache a base-class instance of the clip metadata so that parceling
// works correctly in calling out to the apps.
- mDataDescription = mData.getDescription();
+ mDataDescription = (mData != null) ? mData.getDescription() : null;
mNotifiedWindows.clear();
mDragInProgress = true;
@@ -708,16 +708,20 @@ public class WindowManagerService extends IWindowManager.Stub
// Move the surface to the given touch
if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION notifyMoveLw");
- mSurface.openTransaction();
+ Surface.openTransaction();
try {
mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
} finally {
- mSurface.closeTransaction();
+ Surface.closeTransaction();
if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
}
// Tell the affected window
WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+ if (touchedWin == null) {
+ if (DEBUG_DRAG) Slog.d(TAG, "No touched win at x=" + x + " y=" + y);
+ return;
+ }
if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
final IBinder touchedBinder = touchedWin.mClient.asBinder();
if (touchedBinder != mLocalWin) {
@@ -5865,7 +5869,7 @@ public class WindowManagerService extends IWindowManager.Stub
final InputWindow inputWindow = windowList.add();
inputWindow.inputChannel = mDragState.mServerChannel;
inputWindow.name = "drag";
- inputWindow.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ inputWindow.layoutParamsFlags = 0;
inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
inputWindow.visible = true;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2ef85d5feaa1..9e9a4f21a2d3 100755
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6817,6 +6817,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (info.durationMillis != -1) {
sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
}
+ if (info.numInstances != -1) {
+ sb.append("Instance-Count: ").append(info.numInstances).append("\n");
+ }
if (info.tags != null) {
for (String tag : info.tags) {
sb.append("Span-Tag: ").append(tag).append("\n");
diff --git a/services/sensorservice/RotationVectorSensor.cpp b/services/sensorservice/RotationVectorSensor.cpp
index 418e7f8d0d05..3abfc12bcbf3 100644
--- a/services/sensorservice/RotationVectorSensor.cpp
+++ b/services/sensorservice/RotationVectorSensor.cpp
@@ -34,9 +34,9 @@ static inline T clamp(T v) {
RotationVectorSensor::RotationVectorSensor(sensor_t const* list, size_t count)
: mSensorDevice(SensorDevice::getInstance()),
- mALowPass(M_SQRT1_2, 5.0f),
+ mALowPass(M_SQRT1_2, 1.5f),
mAX(mALowPass), mAY(mALowPass), mAZ(mALowPass),
- mMLowPass(M_SQRT1_2, 2.5f),
+ mMLowPass(M_SQRT1_2, 1.5f),
mMX(mMLowPass), mMY(mMLowPass), mMZ(mMLowPass)
{
for (size_t i=0 ; i<count ; i++) {
diff --git a/services/sensorservice/RotationVectorSensor.h b/services/sensorservice/RotationVectorSensor.h
index b7c951274564..17699f8a4e74 100644
--- a/services/sensorservice/RotationVectorSensor.h
+++ b/services/sensorservice/RotationVectorSensor.h
@@ -38,9 +38,9 @@ class RotationVectorSensor : public SensorInterface {
double mAccTime;
double mMagTime;
SecondOrderLowPassFilter mALowPass;
- BiquadFilter mAX, mAY, mAZ;
+ CascadedBiquadFilter mAX, mAY, mAZ;
SecondOrderLowPassFilter mMLowPass;
- BiquadFilter mMX, mMY, mMZ;
+ CascadedBiquadFilter mMX, mMY, mMZ;
public:
RotationVectorSensor(sensor_t const* list, size_t count);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index fde68f6e07f6..37307391fd9f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -691,22 +691,6 @@ void Layer::unlockPageFlip(
}
}
-void Layer::finishPageFlip()
-{
- ClientRef::Access sharedClient(mUserClientRef);
- SharedBufferServer* lcblk(sharedClient.get());
- if (lcblk) {
- int buf = mBufferManager.getActiveBufferIndex();
- if (buf >= 0) {
- status_t err = lcblk->unlock( buf );
- LOGE_IF(err!=NO_ERROR,
- "layer %p, buffer=%d wasn't locked!",
- this, buf);
- }
- }
-}
-
-
void Layer::dump(String8& result, char* buffer, size_t SIZE) const
{
LayerBaseClient::dump(result, buffer, SIZE);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5444d2f1945d..290811982eac 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -75,7 +75,6 @@ public:
virtual uint32_t doTransaction(uint32_t transactionFlags);
virtual void lockPageFlip(bool& recomputeVisibleRegions);
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
- virtual void finishPageFlip();
virtual bool needsBlending() const { return mNeedsBlending; }
virtual bool needsDithering() const { return mNeedsDithering; }
virtual bool needsFiltering() const;
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 0c1fcf912493..464841b3962e 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -273,10 +273,6 @@ void LayerBase::unlockPageFlip(
}
}
-void LayerBase::finishPageFlip()
-{
-}
-
void LayerBase::invalidate()
{
if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
@@ -534,6 +530,12 @@ void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
result.append(buffer);
}
+void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
+{
+ LayerBase::dump(result, scratch, size);
+}
+
+
// ---------------------------------------------------------------------------
int32_t LayerBaseClient::sIdentity = 1;
@@ -585,6 +587,12 @@ void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
result.append(buffer);
}
+
+void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
+{
+ LayerBaseClient::dump(result, scratch, size);
+}
+
// ---------------------------------------------------------------------------
LayerBaseClient::Surface::Surface(
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index f6c49fc24339..1a34f52ad317 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -174,11 +174,6 @@ public:
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
/**
- * finishPageFlip - called after all surfaces have drawn.
- */
- virtual void finishPageFlip();
-
- /**
* needsBlending - true if this surface needs blending
*/
virtual bool needsBlending() const { return false; }
@@ -211,6 +206,7 @@ public:
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void shortDump(String8& result, char* scratch, size_t size) const;
enum { // flags for doTransaction()
@@ -324,6 +320,7 @@ public:
protected:
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void shortDump(String8& result, char* scratch, size_t size) const;
private:
mutable Mutex mLock;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f5835c90a524..694af70cf8fd 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -394,14 +394,10 @@ bool SurfaceFlinger::threadLoop()
logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
postFramebuffer();
- logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
- unlockClients();
-
logger.log(GraphicLog::SF_REPAINT_DONE, index);
} else {
// pretend we did the post
hw.compositionComplete();
- unlockClients();
usleep(16667); // 60 fps period
}
return true;
@@ -926,17 +922,6 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
}
}
-void SurfaceFlinger::unlockClients()
-{
- const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
- const size_t count = drawingLayers.size();
- sp<LayerBase> const* const layers = drawingLayers.array();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer = layers[i];
- layer->finishPageFlip();
- }
-}
-
void SurfaceFlinger::debugFlashRegions()
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -1497,8 +1482,13 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
result.append(buffer);
}
+ /*
+ * Dump the visible layer list
+ */
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
+ snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+ result.append(buffer);
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(currentLayers[i]);
layer->dump(result, buffer, SIZE);
@@ -1508,6 +1498,24 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
}
+ /*
+ * Dump the layers in the purgatory
+ */
+
+ const size_t purgatorySize = mLayerPurgatory.size();
+ snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+ result.append(buffer);
+ for (size_t i=0 ; i<purgatorySize ; i++) {
+ const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ layer->shortDump(result, buffer, SIZE);
+ }
+
+ /*
+ * Dump SurfaceFlinger global state
+ */
+
+ snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+ result.append(buffer);
mWormholeRegion.dump(result, "WormholeRegion");
const DisplayHardware& hw(graphicPlane(0).displayHardware());
snprintf(buffer, SIZE,
@@ -1533,6 +1541,9 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
result.append(buffer);
}
+ /*
+ * Dump HWComposer state
+ */
HWComposer& hwc(hw.getHwComposer());
snprintf(buffer, SIZE, " h/w composer %s and %s\n",
hwc.initCheck()==NO_ERROR ? "present" : "not present",
@@ -1540,6 +1551,9 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
result.append(buffer);
hwc.dump(result, buffer, SIZE);
+ /*
+ * Dump gralloc state
+ */
const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
alloc.dump(result);
hw.dump(result);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index eabdc645941a..6dd91ac707f9 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -314,7 +314,6 @@ private:
void handleRepaint();
void postFramebuffer();
void composeSurfaces(const Region& dirty);
- void unlockClients();
ssize_t addClientLayer(const sp<Client>& client,
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index c1434245acce..a3d3781d085a 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -30,6 +30,7 @@ import android.text.TextUtils;
import android.util.EventLog;
import java.net.InetAddress;
+import java.net.Inet4Address;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -448,22 +449,65 @@ public abstract class DataConnection extends HierarchicalStateMachine {
NetworkInterface networkInterface = NetworkInterface.getByName(interfaceName);
linkProperties.setInterfaceName(interfaceName);
- // TODO: Get gateway and dns via RIL interface not property?
- String gatewayAddress = SystemProperties.get(prefix + "gw");
- linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+ if (response.length >= 5) {
+ log("response.length >=5 using response for ip='" + response[2] +
+ "' dns='" + response[3] + "' gateway='" + response[4] + "'");
+ String [] addresses = response[2].split(" ");
+ String [] dnses = response[3].split(" ");
+ String gateway = response[4];
+ for (String addr : addresses) {
+ LinkAddress la;
+ if (!InetAddress.isNumeric(addr)) {
+ throw new RuntimeException(
+ "Vendor ril bug: Non-numeric ip addr=" + addr);
+ }
+ InetAddress ia = InetAddress.getByName(addr);
+ if (ia instanceof Inet4Address) {
+ la = new LinkAddress(ia, 32);
+ } else {
+ la = new LinkAddress(ia, 128);
+ }
+ linkProperties.addLinkAddress(la);
+ }
+
+ if (dnses.length != 0) {
+ for (String addr : dnses) {
+ if (!InetAddress.isNumeric(addr)) {
+ throw new RuntimeException(
+ "Vendor ril bug: Non-numeric dns addr=" + addr);
+ }
+ InetAddress ia = InetAddress.getByName(addr);
+ linkProperties.addDns(ia);
+ }
+ result = SetupResult.SUCCESS;
+ } else {
+ result = SetupResult.ERR_BadDns;
+ }
+
+ if (!InetAddress.isNumeric(gateway)) {
+ throw new RuntimeException(
+ "Vendor ril bug: Non-numeric gateway addr=" + gateway);
+ }
+ linkProperties.setGateway(InetAddress.getByName(gateway));
- for (InterfaceAddress addr : networkInterface.getInterfaceAddresses()) {
- linkProperties.addLinkAddress(new LinkAddress(addr));
- }
- // TODO: Get gateway and dns via RIL interface not property?
- String dnsServers[] = new String[2];
- dnsServers[0] = SystemProperties.get(prefix + "dns1");
- dnsServers[1] = SystemProperties.get(prefix + "dns2");
- if (isDnsOk(dnsServers)) {
- linkProperties.addDns(InetAddress.getByName(dnsServers[0]));
- linkProperties.addDns(InetAddress.getByName(dnsServers[1]));
} else {
- result = SetupResult.ERR_BadDns;
+ log("response.length < 5 using properties for dns and gateway");
+ for (InterfaceAddress addr : networkInterface.getInterfaceAddresses()) {
+ linkProperties.addLinkAddress(new LinkAddress(addr));
+ }
+
+ String gatewayAddress = SystemProperties.get(prefix + "gw");
+ linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+
+ String dnsServers[] = new String[2];
+ dnsServers[0] = SystemProperties.get(prefix + "dns1");
+ dnsServers[1] = SystemProperties.get(prefix + "dns2");
+ if (isDnsOk(dnsServers)) {
+ linkProperties.addDns(InetAddress.getByName(dnsServers[0]));
+ linkProperties.addDns(InetAddress.getByName(dnsServers[1]));
+ } else {
+ result = SetupResult.ERR_BadDns;
+ }
}
} catch (UnknownHostException e1) {
log("onSetupCompleted: UnknowHostException " + e1);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index b2d2a98e32ee..39a4614ed46b 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -122,6 +122,8 @@ public class FileFilter {
ignoreResultList.add("storage/indexeddb"); // indexeddb not supported
ignoreResultList.add("storage/private-browsing-readonly.html"); // private browsing not supported
ignoreResultList.add("websocket/tests/workers"); // workers not supported
+ ignoreResultList.add("dom/xhtml/level2/html/htmldocument04.xhtml"); // /mnt/sdcard on SR uses lowercase filesystem, this test checks filename and is case senstive.
+ ignoreResultList.add("dom/html/level2/html/htmldocument04.html"); // ditto
// Expected failures due to missing expected results
ignoreResultList.add("dom/xhtml/level3/core/canonicalform08.xhtml");
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index a3466e27e597..9c4fa975bec0 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -37,6 +37,7 @@ import android.util.Log;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.ConsoleMessage;
+import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
@@ -827,6 +828,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
setDefaultWebSettings(mWebView);
mIsGeolocationPermissionSet = false;
mPendingGeolocationPermissionCallbacks = null;
+ CookieManager.getInstance().removeAllCookie();
}
private long[] getDrawWebViewTime(WebView view, int count) {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 691aff2866c3..1d67964dc26b 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -25,6 +25,15 @@
android:hardwareAccelerated="true">
<activity
+ android:name="ShapesActivity"
+ android:label="_Shapes">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="SimplePatchActivity"
android:label="_SimplePatch"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
@@ -53,6 +62,15 @@
</activity>
<activity
+ android:name="ViewLayersActivity3"
+ android:label="_ViewLayers3">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="AlphaLayersActivity"
android:label="_αLayers">
<intent-filter>
diff --git a/tests/HwAccelerationTest/res/layout/view_layers_3.xml b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
new file mode 100644
index 000000000000..a820f5f2c43f
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:background="#30ff0000"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+ <LinearLayout
+ android:background="#3000ff00"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="12dip">
+
+ <ListView
+ android:id="@+id/list1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:background="#300000ff"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+</LinearLayout>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java
new file mode 100644
index 000000000000..536a669cba19
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java
@@ -0,0 +1,92 @@
+/*
+ * 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.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ShapesActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(new ShapesView(this));
+ }
+
+ static class ShapesView extends View {
+ private Paint mNormalPaint;
+ private Paint mStrokePaint;
+ private Paint mFillPaint;
+ private RectF mRect;
+
+ ShapesView(Context c) {
+ super(c);
+
+ mRect = new RectF(0.0f, 0.0f, 160.0f, 90.0f);
+
+ mNormalPaint = new Paint();
+ mNormalPaint.setAntiAlias(true);
+ mNormalPaint.setColor(0xff0000ff);
+ mNormalPaint.setStrokeWidth(6.0f);
+ mNormalPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+
+ mStrokePaint = new Paint();
+ mStrokePaint.setAntiAlias(true);
+ mStrokePaint.setColor(0xff0000ff);
+ mStrokePaint.setStrokeWidth(6.0f);
+ mStrokePaint.setStyle(Paint.Style.STROKE);
+
+ mFillPaint = new Paint();
+ mFillPaint.setAntiAlias(true);
+ mFillPaint.setColor(0xff0000ff);
+ mFillPaint.setStyle(Paint.Style.FILL);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.save();
+ canvas.translate(50.0f, 50.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mNormalPaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mStrokePaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mFillPaint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(250.0f, 50.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mNormalPaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mStrokePaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mFillPaint);
+ canvas.restore();
+ }
+ }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
new file mode 100644
index 000000000000..c8ae75bfb701
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
@@ -0,0 +1,108 @@
+/*
+ * 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.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ViewLayersActivity3 extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.view_layers_3);
+
+ setupList(R.id.list1);
+ }
+
+ private void setupList(int listId) {
+ final ListView list = (ListView) findViewById(listId);
+ list.setAdapter(new SimpleListAdapter(this));
+ list.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ ((View) list.getParent()).setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+
+ private static class SimpleListAdapter extends ArrayAdapter<String> {
+ public SimpleListAdapter(Context context) {
+ super(context, android.R.layout.simple_list_item_1, DATA_LIST);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView v = (TextView) super.getView(position, convertView, parent);
+ final Resources r = getContext().getResources();
+ final DisplayMetrics metrics = r.getDisplayMetrics();
+ v.setCompoundDrawablePadding((int) (6 * metrics.density + 0.5f));
+ v.setCompoundDrawablesWithIntrinsicBounds(r.getDrawable(R.drawable.icon),
+ null, null, null);
+ return v;
+ }
+ }
+
+ private static final String[] DATA_LIST = {
+ "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+ "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+ "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+ "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+ "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+ "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
+ "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
+ "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+ "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+ "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+ "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+ "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+ "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+ "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+ "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+ "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+ "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+ "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+ "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+ "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+ "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+ "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+ "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+ "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+ "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+ "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+ "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+ "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+ "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+ "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+ "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+ "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+ "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+ "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+ "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+ "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+ "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+ "Ukraine", "United Arab Emirates", "United Kingdom",
+ "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+ "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+ "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+ };
+}
diff --git a/vpn/java/android/net/vpn/IVpnService.aidl b/vpn/java/android/net/vpn/IVpnService.aidl
index fedccb0d8795..6bf3eddee551 100644
--- a/vpn/java/android/net/vpn/IVpnService.aidl
+++ b/vpn/java/android/net/vpn/IVpnService.aidl
@@ -24,10 +24,11 @@ import android.net.vpn.VpnProfile;
*/
interface IVpnService {
/**
- * Sets up the VPN connection.
+ * Sets up a VPN connection.
* @param profile the profile object
* @param username the username for authentication
* @param password the corresponding password for authentication
+ * @return true if VPN is successfully connected
*/
boolean connect(in VpnProfile profile, String username, String password);
@@ -37,7 +38,13 @@ interface IVpnService {
void disconnect();
/**
- * Makes the service broadcast the connectivity state.
+ * Gets the the current connection state.
*/
- void checkStatus(in VpnProfile profile);
+ String getState(in VpnProfile profile);
+
+ /**
+ * Returns the idle state.
+ * @return true if the system is not connecting/connected to a VPN
+ */
+ boolean isIdle();
}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce40b5d0c122..02486bbab611 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -16,17 +16,19 @@
package android.net.vpn;
-import java.io.File;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ServiceConnection;
import android.os.Environment;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemProperties;
import android.util.Log;
+import com.android.server.vpn.VpnServiceBinder;
+
/**
* The class provides interface to manage all VPN-related tasks, including:
* <ul>
@@ -40,8 +42,6 @@ import android.util.Log;
* {@hide}
*/
public class VpnManager {
- // Action for broadcasting a connectivity state.
- private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
/** Key to the profile name of a connectivity broadcast event. */
public static final String BROADCAST_PROFILE_NAME = "profile_name";
/** Key to the connectivity state of a connectivity broadcast event. */
@@ -74,8 +74,10 @@ public class VpnManager {
private static final String PACKAGE_PREFIX =
VpnManager.class.getPackage().getName() + ".";
- // Action to start VPN service
- private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE";
+ // Action for broadcasting a connectivity state.
+ private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
+
+ private static final String VPN_SERVICE_NAME = "vpn";
// Action to start VPN settings
private static final String ACTION_VPN_SETTINGS =
@@ -96,13 +98,76 @@ public class VpnManager {
return VpnType.values();
}
+ public static void startVpnService(Context c) {
+ ServiceManager.addService(VPN_SERVICE_NAME, new VpnServiceBinder(c));
+ }
+
private Context mContext;
+ private IVpnService mVpnService;
/**
* Creates a manager object with the specified context.
*/
public VpnManager(Context c) {
mContext = c;
+ createVpnServiceClient();
+ }
+
+ private void createVpnServiceClient() {
+ IBinder b = ServiceManager.getService(VPN_SERVICE_NAME);
+ mVpnService = IVpnService.Stub.asInterface(b);
+ }
+
+ /**
+ * Sets up a VPN connection.
+ * @param profile the profile object
+ * @param username the username for authentication
+ * @param password the corresponding password for authentication
+ * @return true if VPN is successfully connected
+ */
+ public boolean connect(VpnProfile p, String username, String password) {
+ try {
+ return mVpnService.connect(p, username, password);
+ } catch (RemoteException e) {
+ Log.e(TAG, "connect()", e);
+ return false;
+ }
+ }
+
+ /**
+ * Tears down the VPN connection.
+ */
+ public void disconnect() {
+ try {
+ mVpnService.disconnect();
+ } catch (RemoteException e) {
+ Log.e(TAG, "disconnect()", e);
+ }
+ }
+
+ /**
+ * Gets the the current connection state.
+ */
+ public VpnState getState(VpnProfile p) {
+ try {
+ return Enum.valueOf(VpnState.class, mVpnService.getState(p));
+ } catch (RemoteException e) {
+ Log.e(TAG, "getState()", e);
+ return VpnState.IDLE;
+ }
+ }
+
+ /**
+ * Returns the idle state.
+ * @return true if the system is not connecting/connected to a VPN
+ */
+ public boolean isIdle() {
+ try {
+ return mVpnService.isIdle();
+ } catch (RemoteException e) {
+ Log.e(TAG, "isIdle()", e);
+ return true;
+ }
}
/**
@@ -134,33 +199,6 @@ public class VpnManager {
}
}
- /**
- * Starts the VPN service to establish VPN connection.
- */
- public void startVpnService() {
- mContext.startService(new Intent(ACTION_VPN_SERVICE));
- }
-
- /**
- * Stops the VPN service.
- */
- public void stopVpnService() {
- mContext.stopService(new Intent(ACTION_VPN_SERVICE));
- }
-
- /**
- * Binds the specified ServiceConnection with the VPN service.
- */
- public boolean bindVpnService(ServiceConnection c) {
- if (!mContext.bindService(new Intent(ACTION_VPN_SERVICE), c, 0)) {
- Log.w(TAG, "failed to connect to VPN service");
- return false;
- } else {
- Log.d(TAG, "succeeded to connect to VPN service");
- return true;
- }
- }
-
/** Broadcasts the connectivity state of the specified profile. */
public void broadcastConnectivity(String profileName, VpnState s) {
broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR);
diff --git a/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java b/vpn/java/com/android/server/vpn/DaemonProxy.java
index 289ee458a0be..289ee458a0be 100644
--- a/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java
+++ b/vpn/java/com/android/server/vpn/DaemonProxy.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java b/vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
index 50e0de18ccd9..50e0de18ccd9 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
+++ b/vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/vpn/java/com/android/server/vpn/L2tpIpsecService.java
index 663b0e860f06..663b0e860f06 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
+++ b/vpn/java/com/android/server/vpn/L2tpIpsecService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java b/vpn/java/com/android/server/vpn/L2tpService.java
index 784a366f5b30..784a366f5b30 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java
+++ b/vpn/java/com/android/server/vpn/L2tpService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/PptpService.java b/vpn/java/com/android/server/vpn/PptpService.java
index de12710c7707..de12710c7707 100644
--- a/packages/VpnServices/src/com/android/server/vpn/PptpService.java
+++ b/vpn/java/com/android/server/vpn/PptpService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java b/vpn/java/com/android/server/vpn/VpnConnectingError.java
index 3c4ec7d8c41a..3c4ec7d8c41a 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java
+++ b/vpn/java/com/android/server/vpn/VpnConnectingError.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java b/vpn/java/com/android/server/vpn/VpnDaemons.java
index 499195fd67af..499195fd67af 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java
+++ b/vpn/java/com/android/server/vpn/VpnDaemons.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/vpn/java/com/android/server/vpn/VpnService.java
index a61842325627..4966c060e52d 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/vpn/java/com/android/server/vpn/VpnService.java
@@ -27,8 +27,9 @@ import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.R;
+
import java.io.IOException;
-import java.io.Serializable;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
@@ -37,8 +38,7 @@ import java.net.UnknownHostException;
/**
* The service base class for managing a type of VPN connection.
*/
-abstract class VpnService<E extends VpnProfile> implements Serializable {
- static final long serialVersionUID = 1L;
+abstract class VpnService<E extends VpnProfile> {
private static final boolean DBG = true;
private static final int NOTIFICATION_ID = 1;
@@ -55,10 +55,8 @@ abstract class VpnService<E extends VpnProfile> implements Serializable {
private final String TAG = VpnService.class.getSimpleName();
- // FIXME: profile is only needed in connecting phase, so we can just save
- // the profile name and service class name for recovery
E mProfile;
- transient VpnServiceBinder mContext;
+ transient Context mContext;
private VpnState mState = VpnState.IDLE;
private Throwable mError;
@@ -105,12 +103,8 @@ abstract class VpnService<E extends VpnProfile> implements Serializable {
return InetAddress.getByName(hostName).getHostAddress();
}
- void setContext(VpnServiceBinder context, E profile) {
+ void setContext(Context context, E profile) {
mProfile = profile;
- recover(context);
- }
-
- void recover(VpnServiceBinder context) {
mContext = context;
mNotification = new NotificationHelper();
@@ -124,6 +118,10 @@ abstract class VpnService<E extends VpnProfile> implements Serializable {
return mState;
}
+ boolean isIdle() {
+ return (mState == VpnState.IDLE);
+ }
+
synchronized boolean onConnect(String username, String password) {
try {
setState(VpnState.CONNECTING);
@@ -216,21 +214,12 @@ abstract class VpnService<E extends VpnProfile> implements Serializable {
mStartTime = System.currentTimeMillis();
- // Correct order to make sure VpnService doesn't break when killed:
- // (1) set state to CONNECTED
- // (2) save states
- // (3) set DNS
setState(VpnState.CONNECTED);
- saveSelf();
setVpnDns();
startConnectivityMonitor();
}
- private void saveSelf() throws IOException {
- mContext.saveStates();
- }
-
private synchronized void onFinalCleanUp() {
if (DBG) Log.d(TAG, "onFinalCleanUp()");
@@ -243,10 +232,7 @@ abstract class VpnService<E extends VpnProfile> implements Serializable {
restoreOriginalDomainSuffices();
setState(VpnState.IDLE);
- // stop the service itself
SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
- mContext.removeStates();
- mContext.stopSelf();
}
private boolean anyError() {
@@ -413,9 +399,6 @@ abstract class VpnService<E extends VpnProfile> implements Serializable {
}
}
- private class DaemonHelper implements Serializable {
- }
-
// Helper class for showing, updating notification.
private class NotificationHelper {
private NotificationManager mNotificationManager = (NotificationManager)
diff --git a/vpn/java/com/android/server/vpn/VpnServiceBinder.java b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
new file mode 100644
index 000000000000..c474ff9bd830
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
@@ -0,0 +1,117 @@
+/*
+ * 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.server.vpn;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.vpn.IVpnService;
+import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.L2tpIpsecPskProfile;
+import android.net.vpn.L2tpProfile;
+import android.net.vpn.PptpProfile;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.util.Log;
+
+/**
+ * The service class for managing a VPN connection. It implements the
+ * {@link IVpnService} binder interface.
+ */
+public class VpnServiceBinder extends IVpnService.Stub {
+ private static final String TAG = VpnServiceBinder.class.getSimpleName();
+ private static final boolean DBG = true;
+
+ // The actual implementation is delegated to the VpnService class.
+ private VpnService<? extends VpnProfile> mService;
+
+ private Context mContext;
+
+ public VpnServiceBinder(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public synchronized boolean connect(VpnProfile p, final String username,
+ final String password) {
+ if ((mService != null) && !mService.isIdle()) return false;
+ final VpnService s = mService = createService(p);
+
+ new Thread(new Runnable() {
+ public void run() {
+ s.onConnect(username, password);
+ }
+ }).start();
+ return true;
+ }
+
+ @Override
+ public synchronized void disconnect() {
+ if (mService == null) return;
+ final VpnService s = mService;
+ mService = null;
+
+ new Thread(new Runnable() {
+ public void run() {
+ s.onDisconnect();
+ }
+ }).start();
+ }
+
+ @Override
+ public synchronized String getState(VpnProfile p) {
+ if ((mService == null)
+ || (!p.getName().equals(mService.mProfile.getName()))) {
+ return VpnState.IDLE.toString();
+ } else {
+ return mService.getState().toString();
+ }
+ }
+
+ @Override
+ public synchronized boolean isIdle() {
+ return (mService == null || mService.isIdle());
+ }
+
+ private VpnService<? extends VpnProfile> createService(VpnProfile p) {
+ switch (p.getType()) {
+ case L2TP:
+ L2tpService l2tp = new L2tpService();
+ l2tp.setContext(mContext, (L2tpProfile) p);
+ return l2tp;
+
+ case PPTP:
+ PptpService pptp = new PptpService();
+ pptp.setContext(mContext, (PptpProfile) p);
+ return pptp;
+
+ case L2TP_IPSEC_PSK:
+ L2tpIpsecPskService psk = new L2tpIpsecPskService();
+ psk.setContext(mContext, (L2tpIpsecPskProfile) p);
+ return psk;
+
+ case L2TP_IPSEC:
+ L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
+ l2tpIpsec.setContext(mContext, (L2tpIpsecProfile) p);
+ return l2tpIpsec;
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index f96a5ae65e96..3cde949f204c 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -31,7 +31,7 @@ import android.util.Log;
* Tracks the state changes in supplicant and provides functionality
* that is based on these state changes:
* - detect a failed WPA handshake that loops indefinitely
- * - password failure handling
+ * - authentication failure handling
*/
class SupplicantStateTracker extends HierarchicalStateMachine {
@@ -39,14 +39,14 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
private static final boolean DBG = false;
private WifiStateMachine mWifiStateMachine;
- private int mPasswordFailuresCount = 0;
+ private int mAuthenticationFailuresCount = 0;
/* Indicates authentication failure in supplicant broadcast.
* TODO: enhance auth failure reporting to include notification
* for all type of failures: EAP, WPS & WPA networks */
private boolean mAuthFailureInSupplicantBroadcast = false;
- /* Maximum retries on a password failure notification */
- private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
+ /* Maximum retries on a authentication failure notification */
+ private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;
/* Tracks if networks have been disabled during a connection */
private boolean mNetworksDisabledDuringConnect = false;
@@ -155,8 +155,8 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
switch (message.what) {
- case WifiStateMachine.PASSWORD_MAY_BE_INCORRECT_EVENT:
- mPasswordFailuresCount++;
+ case WifiStateMachine.AUTHENTICATION_FAILURE_EVENT:
+ mAuthenticationFailuresCount++;
mAuthFailureInSupplicantBroadcast = true;
break;
case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
@@ -206,18 +206,17 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
- /* If a disconnect event happens after password key failure
+ /* If a disconnect event happens after authentication failure
* exceeds maximum retries, disable the network
*/
-
Message message = getCurrentMessage();
StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
- if (mPasswordFailuresCount >= MAX_RETRIES_ON_PASSWORD_FAILURE) {
+ if (mAuthenticationFailuresCount >= MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
Log.d(TAG, "Failed to authenticate, disabling network " +
stateChangeResult.networkId);
handleNetworkConnectionFailure(stateChangeResult.networkId);
- mPasswordFailuresCount = 0;
+ mAuthenticationFailuresCount = 0;
}
}
}
@@ -282,8 +281,8 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
- /* Reset password failure count */
- mPasswordFailuresCount = 0;
+ /* Reset authentication failure count */
+ mAuthenticationFailuresCount = 0;
if (mNetworksDisabledDuringConnect) {
WifiConfigStore.enableAllNetworks();
mNetworksDisabledDuringConnect = false;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 090ad3b6ad2a..ce3826167c4b 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -42,7 +42,8 @@ public class WifiMonitor {
private static final int LINK_SPEED = 5;
private static final int TERMINATING = 6;
private static final int DRIVER_STATE = 7;
- private static final int UNKNOWN = 8;
+ private static final int EAP_FAILURE = 8;
+ private static final int UNKNOWN = 9;
/** All events coming from the supplicant start with this prefix */
private static final String eventPrefix = "CTRL-EVENT-";
@@ -110,6 +111,17 @@ public class WifiMonitor {
* <code>state</code> is either STARTED or STOPPED
*/
private static final String driverStateEvent = "DRIVER-STATE";
+ /**
+ * <pre>
+ * CTRL-EVENT-EAP-FAILURE EAP authentication failed
+ * </pre>
+ */
+ private static final String eapFailureEvent = "EAP-FAILURE";
+
+ /**
+ * This indicates an authentication failure on EAP FAILURE event
+ */
+ private static final String eapAuthFailure = "EAP authentication failed";
/**
* Regex pattern for extracting an Ethernet-style MAC address from a string.
@@ -176,7 +188,7 @@ public class WifiMonitor {
if (!eventStr.startsWith(eventPrefix)) {
if (eventStr.startsWith(wpaEventPrefix) &&
0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
- handlePasswordKeyMayBeIncorrect();
+ mWifiStateMachine.notifyAuthenticationFailure();
} else if (eventStr.startsWith(wpsOverlapEvent)) {
mWifiStateMachine.notifyWpsOverlap();
}
@@ -207,16 +219,17 @@ public class WifiMonitor {
event = LINK_SPEED;
else if (eventName.equals(terminatingEvent))
event = TERMINATING;
- else if (eventName.equals(driverStateEvent)) {
+ else if (eventName.equals(driverStateEvent))
event = DRIVER_STATE;
- }
+ else if (eventName.equals(eapFailureEvent))
+ event = EAP_FAILURE;
else
event = UNKNOWN;
String eventData = eventStr;
if (event == DRIVER_STATE || event == LINK_SPEED)
eventData = eventData.split(" ")[1];
- else if (event == STATE_CHANGE) {
+ else if (event == STATE_CHANGE || event == EAP_FAILURE) {
int ind = eventStr.indexOf(" ");
if (ind != -1) {
eventData = eventStr.substring(ind + 1);
@@ -261,6 +274,10 @@ public class WifiMonitor {
// notify and exit
mWifiStateMachine.notifySupplicantLost();
break;
+ } else if (event == EAP_FAILURE) {
+ if (eventData.startsWith(eapAuthFailure)) {
+ mWifiStateMachine.notifyAuthenticationFailure();
+ }
} else {
handleEvent(event, eventData);
}
@@ -284,10 +301,6 @@ public class WifiMonitor {
return false;
}
- private void handlePasswordKeyMayBeIncorrect() {
- mWifiStateMachine.notifyPasswordKeyMayBeIncorrect();
- }
-
private void handleDriverEvent(String state) {
if (state == null) {
return;
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index df21399e226c..4d0acdd7044c 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -212,8 +212,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
static final int SCAN_RESULTS_EVENT = 38;
/* Supplicate state changed */
static final int SUPPLICANT_STATE_CHANGE_EVENT = 39;
- /* Password may be incorrect */
- static final int PASSWORD_MAY_BE_INCORRECT_EVENT = 40;
+ /* Password failure and EAP authentication failure */
+ static final int AUTHENTICATION_FAILURE_EVENT = 40;
/* WPS overlap detected */
static final int WPS_OVERLAP_EVENT = 41;
@@ -1383,11 +1383,12 @@ public class WifiStateMachine extends HierarchicalStateMachine {
}
/**
- * Send the tracker a notification that a user-entered password key
- * may be incorrect (i.e., caused authentication to fail).
+ * Send the tracker a notification that a user provided
+ * configuration caused authentication failure - this could
+ * be a password failure or a EAP authentication failure
*/
- void notifyPasswordKeyMayBeIncorrect() {
- sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+ void notifyAuthenticationFailure() {
+ sendMessage(AUTHENTICATION_FAILURE_EVENT);
}
/**
@@ -1515,7 +1516,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case NETWORK_DISCONNECTION_EVENT:
case SCAN_RESULTS_EVENT:
case SUPPLICANT_STATE_CHANGE_EVENT:
- case PASSWORD_MAY_BE_INCORRECT_EVENT:
+ case AUTHENTICATION_FAILURE_EVENT:
case WPS_OVERLAP_EVENT:
case CMD_BLACKLIST_NETWORK:
case CMD_CLEAR_BLACKLIST:
@@ -2067,7 +2068,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case SUPPLICANT_STATE_CHANGE_EVENT:
case NETWORK_CONNECTION_EVENT:
case NETWORK_DISCONNECTION_EVENT:
- case PASSWORD_MAY_BE_INCORRECT_EVENT:
+ case AUTHENTICATION_FAILURE_EVENT:
case WPS_OVERLAP_EVENT:
case CMD_SET_SCAN_TYPE:
case CMD_SET_HIGH_PERF_MODE:
@@ -2300,8 +2301,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
StateChangeResult stateChangeResult;
switch(message.what) {
- case PASSWORD_MAY_BE_INCORRECT_EVENT:
- mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+ case AUTHENTICATION_FAILURE_EVENT:
+ mSupplicantStateTracker.sendMessage(AUTHENTICATION_FAILURE_EVENT);
break;
case WPS_OVERLAP_EVENT:
/* We just need to broadcast the error */