summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--api/current.txt573
-rw-r--r--cmds/app_process/Android.mk25
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java34
-rw-r--r--core/java/android/app/ApplicationPackageManager.java49
-rw-r--r--core/java/android/app/Notification.java118
-rw-r--r--core/java/android/app/PackageInstallObserver.java49
-rw-r--r--core/java/android/content/Intent.java5
-rw-r--r--core/java/android/content/pm/IPackageInstallObserver2.aidl45
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl16
-rw-r--r--core/java/android/content/pm/PackageManager.java143
-rw-r--r--core/java/android/content/pm/PackageParser.java1
-rw-r--r--core/java/android/content/res/ColorStateList.java23
-rw-r--r--core/java/android/content/res/TypedArray.java5
-rw-r--r--core/java/android/net/http/CertificateChainValidator.java11
-rw-r--r--core/java/android/os/storage/IMountService.java60
-rw-r--r--core/java/android/provider/MediaStore.java4
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/text/DynamicLayout.java17
-rw-r--r--core/java/android/text/Html.java2
-rw-r--r--core/java/android/text/Layout.java12
-rw-r--r--core/java/android/text/MeasuredText.java6
-rw-r--r--core/java/android/text/PackedIntVector.java7
-rw-r--r--core/java/android/text/PackedObjectVector.java15
-rw-r--r--core/java/android/text/SpannableStringBuilder.java53
-rw-r--r--core/java/android/text/SpannableStringInternal.java14
-rw-r--r--core/java/android/text/StaticLayout.java27
-rw-r--r--core/java/android/text/TextLine.java2
-rw-r--r--core/java/android/text/TextUtils.java2
-rw-r--r--core/java/android/util/ArrayMap.java22
-rw-r--r--core/java/android/util/ArraySet.java18
-rw-r--r--core/java/android/util/ContainerHelpers.java4
-rw-r--r--core/java/android/util/LongArray.java8
-rw-r--r--core/java/android/util/LongSparseArray.java57
-rw-r--r--core/java/android/util/LongSparseLongArray.java49
-rw-r--r--core/java/android/util/SparseArray.java57
-rw-r--r--core/java/android/util/SparseBooleanArray.java57
-rw-r--r--core/java/android/util/SparseIntArray.java57
-rw-r--r--core/java/android/util/SparseLongArray.java49
-rw-r--r--core/java/android/view/RenderNode.java10
-rw-r--r--core/java/android/view/View.java13
-rw-r--r--core/java/android/widget/Editor.java8
-rw-r--r--core/java/android/widget/RemoteViews.java94
-rw-r--r--core/java/android/widget/SpellChecker.java21
-rw-r--r--core/java/com/android/internal/app/ProcessStats.java22
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java48
-rw-r--r--core/java/com/android/internal/util/GrowingArrayUtils.java196
-rw-r--r--core/java/com/android/internal/util/ImageUtils.java (renamed from packages/SystemUI/src/com/android/systemui/ImageUtils.java)6
-rw-r--r--core/java/com/android/internal/util/LegacyNotificationUtil.java193
-rw-r--r--core/java/com/android/internal/widget/ILockSettings.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java14
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp44
-rw-r--r--core/jni/android/graphics/Canvas.cpp34
-rw-r--r--core/jni/android/graphics/ColorFilter.cpp10
-rw-r--r--core/jni/android/graphics/Graphics.cpp20
-rw-r--r--core/jni/android/graphics/Matrix.cpp63
-rw-r--r--core/jni/android/graphics/Paint.cpp10
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp14
-rw-r--r--core/jni/android_net_LocalSocketImpl.cpp6
-rw-r--r--core/jni/android_nio_utils.cpp2
-rw-r--r--core/jni/android_os_Debug.cpp6
-rw-r--r--core/jni/android_server_NetworkManagementSocketTagger.cpp4
-rw-r--r--core/jni/android_text_AndroidBidi.cpp2
-rw-r--r--core/jni/android_text_AndroidCharacter.cpp15
-rw-r--r--core/jni/android_text_format_Time.cpp66
-rw-r--r--core/jni/android_util_Log.cpp2
-rw-r--r--core/jni/android_view_RenderNode.cpp16
-rw-r--r--core/jni/android_view_SurfaceControl.cpp46
-rw-r--r--core/res/res/color/background_cache_hint_selector_holo_dark.xml (renamed from core/res/res/drawable/background_cache_hint_selector_holo_dark.xml)0
-rw-r--r--core/res/res/color/background_cache_hint_selector_holo_light.xml (renamed from core/res/res/drawable/background_cache_hint_selector_holo_light.xml)0
-rw-r--r--core/res/res/color/background_cache_hint_selector_quantum_dark.xml (renamed from core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml)0
-rw-r--r--core/res/res/color/background_cache_hint_selector_quantum_light.xml (renamed from core/res/res/drawable/background_cache_hint_selector_quantum_light.xml)0
-rw-r--r--core/res/res/drawable/ab_transparent_quantum.xml (renamed from core/res/res/drawable/ab_transparent_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ab_transparent_quantum_light.xml19
-rw-r--r--core/res/res/drawable/activated_background_quantum.xml (renamed from core/res/res/drawable/activated_background_quantum_dark.xml)8
-rw-r--r--core/res/res/drawable/activated_background_quantum_light.xml20
-rw-r--r--core/res/res/drawable/btn_borderless_quantum.xml (renamed from core/res/res/drawable/btn_borderless_quantum_dark.xml)6
-rw-r--r--core/res/res/drawable/btn_borderless_quantum_light.xml19
-rw-r--r--core/res/res/drawable/btn_check_quantum.xml (renamed from core/res/res/drawable/btn_check_quantum_dark.xml)8
-rw-r--r--core/res/res/drawable/btn_check_quantum_light.xml34
-rw-r--r--core/res/res/drawable/btn_color_quantum.xml (renamed from core/res/res/drawable/btn_color_quantum_dark.xml)6
-rw-r--r--core/res/res/drawable/btn_color_quantum_light.xml29
-rw-r--r--core/res/res/drawable/btn_default_quantum.xml (renamed from core/res/res/drawable/btn_default_quantum_dark.xml)8
-rw-r--r--core/res/res/drawable/btn_default_quantum_light.xml21
-rw-r--r--core/res/res/drawable/btn_radio_quantum.xml (renamed from core/res/res/drawable/btn_radio_quantum_dark.xml)8
-rw-r--r--core/res/res/drawable/btn_radio_quantum_light.xml34
-rw-r--r--core/res/res/drawable/btn_star_quantum.xml (renamed from core/res/res/drawable/btn_star_quantum_dark.xml)6
-rw-r--r--core/res/res/drawable/btn_star_quantum_light.xml30
-rw-r--r--core/res/res/drawable/edit_text_quantum.xml (renamed from core/res/res/drawable/edit_text_quantum_dark.xml)12
-rw-r--r--core/res/res/drawable/edit_text_quantum_light.xml42
-rw-r--r--core/res/res/drawable/expander_group_quantum.xml (renamed from core/res/res/drawable/expander_group_quantum_dark.xml)4
-rw-r--r--core/res/res/drawable/expander_group_quantum_light.xml26
-rw-r--r--core/res/res/drawable/fastscroll_thumb_quantum.xml (renamed from core/res/res/drawable/fastscroll_thumb_quantum_dark.xml)4
-rw-r--r--core/res/res/drawable/fastscroll_thumb_quantum_light.xml26
-rw-r--r--core/res/res/drawable/fastscroll_track_quantum.xml (renamed from core/res/res/drawable/fastscroll_track_quantum_light.xml)2
-rw-r--r--core/res/res/drawable/fastscroll_track_quantum_dark.xml19
-rw-r--r--core/res/res/drawable/ic_ab_back_quantum.xml (renamed from core/res/res/drawable/ic_ab_back_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_ab_back_quantum_light.xml20
-rw-r--r--core/res/res/drawable/ic_cab_done_quantum.xml (renamed from core/res/res/drawable/ic_cab_done_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_cab_done_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_dialog_alert_quantum.xml (renamed from core/res/res/drawable/ic_dialog_alert_quantum_light.xml)2
-rw-r--r--core/res/res/drawable/ic_dialog_alert_quantum_dark.xml19
-rw-r--r--core/res/res/drawable/ic_find_next_quantum.xml (renamed from core/res/res/drawable/ic_find_next_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_find_next_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_find_previous_quantum.xml (renamed from core/res/res/drawable/ic_find_previous_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_find_previous_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_menu_copy_quantum.xml (renamed from core/res/res/drawable/ic_menu_copy_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_copy_quantum_light.xml20
-rw-r--r--core/res/res/drawable/ic_menu_cut_quantum.xml (renamed from core/res/res/drawable/ic_menu_cut_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_cut_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_menu_find_quantum.xml (renamed from core/res/res/drawable/ic_menu_find_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_find_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_menu_moreoverflow_quantum.xml (renamed from core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_menu_paste_quantum.xml (renamed from core/res/res/drawable/ic_menu_paste_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_paste_quantum_light.xml20
-rw-r--r--core/res/res/drawable/ic_menu_search_quantum.xml (renamed from core/res/res/drawable/ic_menu_search_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_search_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_menu_selectall_quantum.xml (renamed from core/res/res/drawable/ic_menu_selectall_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_selectall_quantum_light.xml19
-rw-r--r--core/res/res/drawable/ic_menu_share_quantum.xml (renamed from core/res/res/drawable/ic_menu_share_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/ic_menu_share_quantum_light.xml19
-rw-r--r--core/res/res/drawable/item_background_quantum.xml (renamed from core/res/res/drawable/item_background_borderless_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/item_background_quantum_dark.xml18
-rw-r--r--core/res/res/drawable/list_divider_quantum.xml (renamed from core/res/res/drawable/list_divider_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/list_divider_quantum_light.xml19
-rw-r--r--core/res/res/drawable/list_section_divider_quantum.xml (renamed from core/res/res/drawable/list_section_divider_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/list_section_divider_quantum_light.xml19
-rw-r--r--core/res/res/drawable/notification_icon_legacy_bg.xml (renamed from packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml)0
-rw-r--r--core/res/res/drawable/notification_icon_legacy_bg_inset.xml (renamed from packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml)0
-rw-r--r--core/res/res/drawable/notification_quantum_background.xml2
-rw-r--r--core/res/res/drawable/progress_horizontal_quantum.xml (renamed from core/res/res/drawable/progress_horizontal_quantum_dark.xml)6
-rw-r--r--core/res/res/drawable/progress_horizontal_quantum_light.xml34
-rw-r--r--core/res/res/drawable/scrollbar_handle_quantum.xml (renamed from core/res/res/drawable/scrollbar_handle_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/scrollbar_handle_quantum_light.xml19
-rw-r--r--core/res/res/drawable/scrubber_control_selector_quantum.xml (renamed from core/res/res/drawable/scrubber_control_selector_quantum_dark.xml)4
-rw-r--r--core/res/res/drawable/scrubber_control_selector_quantum_light.xml26
-rw-r--r--core/res/res/drawable/scrubber_progress_horizontal_quantum.xml (renamed from core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml)4
-rw-r--r--core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml26
-rw-r--r--core/res/res/drawable/spinner_background_quantum.xml (renamed from core/res/res/drawable/spinner_background_quantum_dark.xml)6
-rw-r--r--core/res/res/drawable/spinner_background_quantum_light.xml31
-rw-r--r--core/res/res/drawable/switch_inner_quantum.xml (renamed from core/res/res/drawable/switch_inner_quantum_dark.xml)8
-rw-r--r--core/res/res/drawable/switch_inner_quantum_light.xml34
-rw-r--r--core/res/res/drawable/switch_track_quantum.xml (renamed from core/res/res/drawable/switch_track_quantum_dark.xml)4
-rw-r--r--core/res/res/drawable/switch_track_quantum_light.xml26
-rw-r--r--core/res/res/drawable/tab_indicator_quantum.xml (renamed from core/res/res/drawable/tab_indicator_quantum_dark.xml)12
-rw-r--r--core/res/res/drawable/tab_indicator_quantum_light.xml43
-rw-r--r--core/res/res/drawable/text_cursor_quantum.xml (renamed from core/res/res/drawable/text_cursor_quantum_dark.xml)2
-rw-r--r--core/res/res/drawable/text_cursor_quantum_light.xml19
-rw-r--r--core/res/res/layout/notification_quantum_action.xml2
-rw-r--r--core/res/res/layout/notification_quantum_action_list.xml2
-rw-r--r--core/res/res/layout/notification_quantum_action_tombstone.xml2
-rw-r--r--core/res/res/layout/notification_template_quantum_base.xml2
-rw-r--r--core/res/res/layout/notification_template_quantum_big_base.xml4
-rw-r--r--core/res/res/layout/notification_template_quantum_big_text.xml6
-rw-r--r--core/res/res/layout/notification_template_quantum_inbox.xml6
-rw-r--r--core/res/res/values/attrs.xml155
-rw-r--r--core/res/res/values/colors.xml3
-rw-r--r--core/res/res/values/colors_quantum.xml12
-rw-r--r--core/res/res/values/dimens.xml3
-rw-r--r--core/res/res/values/ids.xml1
-rw-r--r--core/res/res/values/public.xml70
-rw-r--r--core/res/res/values/styles_quantum.xml727
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/res/res/values/themes.xml4
-rw-r--r--core/res/res/values/themes_quantum.xml134
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageManagerTests.java10
-rw-r--r--docs/html/design/index.jd1
-rw-r--r--docs/html/develop/index.jd1
-rw-r--r--docs/html/distribute/index.jd1
-rw-r--r--docs/html/google/play-services/index.jd2
-rw-r--r--docs/html/images/tools/as-buildvariants.pngbin0 -> 7739 bytes
-rw-r--r--docs/html/images/tools/as-demoflavordirs.pngbin0 -> 21279 bytes
-rw-r--r--docs/html/images/tools/as-gradlebutton.pngbin0 -> 1297 bytes
-rw-r--r--docs/html/images/tools/as-gradleconsole.pngbin0 -> 29196 bytes
-rw-r--r--docs/html/images/tools/as-gradlepanel.pngbin0 -> 33680 bytes
-rw-r--r--docs/html/images/tools/as-gradlesync.pngbin0 -> 23107 bytes
-rw-r--r--docs/html/images/tools/as-mainscreen.pngbin0 -> 178076 bytes
-rw-r--r--docs/html/index.jd3
-rw-r--r--docs/html/sdk/installing/installing-adt.jd23
-rw-r--r--docs/html/sdk/installing/studio-build.jd1065
-rw-r--r--docs/html/tools/sdk/eclipse-adt.jd6
-rw-r--r--docs/html/tools/support-library/index.jd28
-rw-r--r--docs/html/tools/tools_toc.cs2
-rw-r--r--docs/html/wear/design/index.html607
-rw-r--r--docs/html/wear/design/index.jd173
-rw-r--r--docs/html/wear/design/user-interface.html498
-rw-r--r--docs/html/wear/design/user-interface.jd58
-rw-r--r--docs/html/wear/index.jd (renamed from docs/html/wear/index.html)352
-rw-r--r--docs/html/wear/license.jd (renamed from docs/html/wear/license.html)445
-rw-r--r--docs/html/wear/notifications/creating.html722
-rw-r--r--docs/html/wear/notifications/creating.jd289
-rw-r--r--docs/html/wear/notifications/pages.html500
-rw-r--r--docs/html/wear/notifications/pages.jd61
-rw-r--r--docs/html/wear/notifications/remote-input.html652
-rw-r--r--docs/html/wear/notifications/remote-input.jd213
-rw-r--r--docs/html/wear/notifications/stacks.html512
-rw-r--r--docs/html/wear/notifications/stacks.jd72
-rw-r--r--docs/html/wear/preview/signup.jd (renamed from docs/html/wear/preview/signup.html)446
-rw-r--r--docs/html/wear/preview/start.html693
-rw-r--r--docs/html/wear/preview/start.jd254
-rw-r--r--docs/html/wear/wear_toc.cs74
-rw-r--r--graphics/java/android/graphics/TemporaryBuffer.java2
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java4
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/RevealDrawable.java317
-rw-r--r--graphics/java/android/graphics/drawable/Ripple.java257
-rw-r--r--graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java309
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java1955
-rw-r--r--libs/androidfw/BackupData.cpp8
-rw-r--r--libs/androidfw/BackupHelpers.cpp21
-rw-r--r--libs/androidfw/CursorWindow.cpp4
-rw-r--r--libs/androidfw/ResourceTypes.cpp6
-rw-r--r--libs/common_time/common_time_server.cpp2
-rw-r--r--libs/common_time/utils.cpp4
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp4
-rw-r--r--libs/hwui/DeferredLayerUpdater.h1
-rw-r--r--libs/hwui/DisplayListOp.h34
-rw-r--r--libs/hwui/Layer.cpp11
-rw-r--r--libs/hwui/Layer.h6
-rw-r--r--libs/hwui/OpenGLRenderer.cpp7
-rw-r--r--libs/hwui/OpenGLRenderer.h2
-rw-r--r--libs/hwui/Outline.h1
-rw-r--r--libs/hwui/RenderNode.cpp46
-rw-r--r--libs/hwui/RenderNode.h3
-rw-r--r--libs/hwui/RenderProperties.cpp41
-rw-r--r--libs/hwui/RenderProperties.h29
-rw-r--r--libs/hwui/ResourceCache.cpp4
-rw-r--r--libs/hwui/RevealClip.h78
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp2
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp143
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.h98
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp57
-rw-r--r--libs/hwui/renderthread/RenderProxy.h8
-rw-r--r--libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c12
-rw-r--r--media/java/android/media/MediaFocusControl.java484
-rw-r--r--media/java/android/media/PlayerRecord.java (renamed from media/java/android/media/MediaController.java)202
-rwxr-xr-xmedia/java/android/mtp/MtpDatabase.java9
-rw-r--r--media/jni/android_mtp_MtpDatabase.cpp11
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java7
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml6
-rw-r--r--packages/SystemUI/res/values-land/dimens.xml3
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java245
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java153
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java505
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java816
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/PiecewiseLinearIndentationFunctor.java112
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackIndentationFunctor.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java399
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java153
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java5
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java41
-rw-r--r--services/core/java/com/android/server/MountService.java51
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityStack.java1
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java67
-rwxr-xr-xservices/core/java/com/android/server/pm/PackageManagerService.java145
-rw-r--r--services/core/java/com/android/server/pm/Settings.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java12
-rw-r--r--services/core/jni/com_android_server_AlarmManagerService.cpp4
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java31
-rw-r--r--tests/DynamicDrawableTest/Android.mk26
-rw-r--r--tests/DynamicDrawableTest/AndroidManifest.xml99
-rw-r--r--tests/DynamicDrawableTest/lint.xml3
-rw-r--r--tests/DynamicDrawableTest/res/drawable-hdpi/icon.pngbin0 -> 5141 bytes
-rw-r--r--tests/DynamicDrawableTest/res/drawable/icon.pngbin0 -> 3133 bytes
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml73
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml46
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml137
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml126
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml147
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml76
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml45
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml48
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml41
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml114
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml62
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml90
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml82
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml54
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml48
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml46
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml46
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml45
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml45
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml37
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml33
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_test01.xml31
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_test02.xml31
-rw-r--r--tests/DynamicDrawableTest/res/values/strings.xml (renamed from core/res/res/drawable/item_background_borderless_quantum_light.xml)4
-rw-r--r--tests/DynamicDrawableTest/res/values/styles.xml (renamed from core/res/res/drawable/item_background_quantum_light.xml)6
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java69
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java89
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java43
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java95
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java36
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java152
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java25
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java8
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java64
312 files changed, 12209 insertions, 9897 deletions
diff --git a/Android.mk b/Android.mk
index 33e64d0..eeec945 100644
--- a/Android.mk
+++ b/Android.mk
@@ -120,6 +120,7 @@ LOCAL_SRC_FILES += \
core/java/android/content/pm/IPackageDataObserver.aidl \
core/java/android/content/pm/IPackageDeleteObserver.aidl \
core/java/android/content/pm/IPackageInstallObserver.aidl \
+ core/java/android/content/pm/IPackageInstallObserver2.aidl \
core/java/android/content/pm/IPackageManager.aidl \
core/java/android/content/pm/IPackageMoveObserver.aidl \
core/java/android/content/pm/IPackageStatsObserver.aidl \
diff --git a/api/current.txt b/api/current.txt
index 97c1c74..faeab39 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -287,6 +287,7 @@ package android {
field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
field public static final int alwaysRetainTaskState = 16843267; // 0x1010203
field public static final int angle = 16843168; // 0x10101a0
+ field public static final int animate = 16843822; // 0x101042e
field public static final int animateFirstView = 16843477; // 0x10102d5
field public static final int animateLayoutChanges = 16843506; // 0x10102f2
field public static final int animateOnClick = 16843356; // 0x101025c
@@ -373,12 +374,19 @@ package android {
field public static final int clipChildren = 16842986; // 0x10100ea
field public static final int clipOrientation = 16843274; // 0x101020a
field public static final int clipToPadding = 16842987; // 0x10100eb
+ field public static final int clipToPath = 16843821; // 0x101042d
field public static final int codes = 16843330; // 0x1010242
field public static final int collapseColumns = 16843083; // 0x101014b
field public static final int color = 16843173; // 0x10101a5
field public static final int colorActivatedHighlight = 16843664; // 0x1010390
field public static final int colorBackground = 16842801; // 0x1010031
field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
+ field public static final int colorButtonNormal = 16843828; // 0x1010434
+ field public static final int colorButtonNormalColored = 16843830; // 0x1010436
+ field public static final int colorButtonPressed = 16843829; // 0x1010435
+ field public static final int colorButtonPressedColored = 16843831; // 0x1010437
+ field public static final int colorControlActivated = 16843827; // 0x1010433
+ field public static final int colorControlNormal = 16843826; // 0x1010432
field public static final int colorFocusedHighlight = 16843663; // 0x101038f
field public static final int colorForeground = 16842800; // 0x1010030
field public static final int colorForegroundInverse = 16843270; // 0x1010206
@@ -399,10 +407,10 @@ package android {
field public static final int content = 16843355; // 0x101025b
field public static final int contentAuthority = 16843408; // 0x1010290
field public static final int contentDescription = 16843379; // 0x1010273
- field public static final int controlX1 = 16843771; // 0x10103fb
- field public static final int controlX2 = 16843773; // 0x10103fd
- field public static final int controlY1 = 16843772; // 0x10103fc
- field public static final int controlY2 = 16843774; // 0x10103fe
+ field public static final int controlX1 = 16843799; // 0x1010417
+ field public static final int controlX2 = 16843801; // 0x1010419
+ field public static final int controlY1 = 16843800; // 0x1010418
+ field public static final int controlY2 = 16843802; // 0x101041a
field public static final int cropToPadding = 16843043; // 0x1010123
field public static final int cursorVisible = 16843090; // 0x1010152
field public static final int customNavigationLayout = 16843474; // 0x10102d2
@@ -465,6 +473,7 @@ package android {
field public static final int dropDownWidth = 16843362; // 0x1010262
field public static final int duplicateParentState = 16842985; // 0x10100e9
field public static final int duration = 16843160; // 0x1010198
+ field public static final int durations = 16843814; // 0x1010426
field public static final int editTextBackground = 16843602; // 0x1010352
field public static final int editTextColor = 16843601; // 0x1010351
field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -505,13 +514,15 @@ package android {
field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
field public static final int fastScrollPreviewBackgroundLeft = 16843575; // 0x1010337
field public static final int fastScrollPreviewBackgroundRight = 16843576; // 0x1010338
- field public static final int fastScrollStyle = 16843766; // 0x10103f6
+ field public static final int fastScrollStyle = 16843794; // 0x1010412
field public static final int fastScrollTextColor = 16843609; // 0x1010359
field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
+ field public static final int fill = 16843809; // 0x1010421
field public static final int fillAfter = 16843197; // 0x10101bd
field public static final int fillBefore = 16843196; // 0x10101bc
field public static final int fillEnabled = 16843343; // 0x101024f
+ field public static final int fillOpacity = 16843808; // 0x1010420
field public static final int fillViewport = 16843130; // 0x101017a
field public static final int filter = 16843035; // 0x101011b
field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4
@@ -531,7 +542,7 @@ package android {
field public static final int format12Hour = 16843722; // 0x10103ca
field public static final int format24Hour = 16843723; // 0x10103cb
field public static final int fragment = 16843491; // 0x10102e3
- field public static final int fragmentBreadCrumbsStyle = 16843765; // 0x10103f5
+ field public static final int fragmentBreadCrumbsStyle = 16843793; // 0x1010411
field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
field public static final int fragmentFadeEnterAnimation = 16843497; // 0x10102e9
@@ -660,6 +671,34 @@ package android {
field public static final int keyboardMode = 16843341; // 0x101024d
field public static final int keycode = 16842949; // 0x10100c5
field public static final int killAfterRestore = 16843420; // 0x101029c
+ field public static final int l_resource_pad1 = 16843792; // 0x1010410
+ field public static final int l_resource_pad10 = 16843783; // 0x1010407
+ field public static final int l_resource_pad11 = 16843782; // 0x1010406
+ field public static final int l_resource_pad12 = 16843781; // 0x1010405
+ field public static final int l_resource_pad13 = 16843780; // 0x1010404
+ field public static final int l_resource_pad14 = 16843779; // 0x1010403
+ field public static final int l_resource_pad15 = 16843778; // 0x1010402
+ field public static final int l_resource_pad16 = 16843777; // 0x1010401
+ field public static final int l_resource_pad17 = 16843776; // 0x1010400
+ field public static final int l_resource_pad18 = 16843775; // 0x10103ff
+ field public static final int l_resource_pad19 = 16843774; // 0x10103fe
+ field public static final int l_resource_pad2 = 16843791; // 0x101040f
+ field public static final int l_resource_pad20 = 16843773; // 0x10103fd
+ field public static final int l_resource_pad21 = 16843772; // 0x10103fc
+ field public static final int l_resource_pad22 = 16843771; // 0x10103fb
+ field public static final int l_resource_pad23 = 16843770; // 0x10103fa
+ field public static final int l_resource_pad24 = 16843769; // 0x10103f9
+ field public static final int l_resource_pad25 = 16843768; // 0x10103f8
+ field public static final int l_resource_pad26 = 16843767; // 0x10103f7
+ field public static final int l_resource_pad27 = 16843766; // 0x10103f6
+ field public static final int l_resource_pad28 = 16843765; // 0x10103f5
+ field public static final int l_resource_pad3 = 16843790; // 0x101040e
+ field public static final int l_resource_pad4 = 16843789; // 0x101040d
+ field public static final int l_resource_pad5 = 16843788; // 0x101040c
+ field public static final int l_resource_pad6 = 16843787; // 0x101040b
+ field public static final int l_resource_pad7 = 16843786; // 0x101040a
+ field public static final int l_resource_pad8 = 16843785; // 0x1010409
+ field public static final int l_resource_pad9 = 16843784; // 0x1010408
field public static final int label = 16842753; // 0x1010001
field public static final int labelFor = 16843718; // 0x10103c6
field public static final int labelTextSize = 16843317; // 0x1010235
@@ -715,6 +754,7 @@ package android {
field public static final int layout_x = 16843135; // 0x101017f
field public static final int layout_y = 16843136; // 0x1010180
field public static final int left = 16843181; // 0x10101ad
+ field public static final int limitTo = 16843823; // 0x101042f
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
field public static final int lines = 16843092; // 0x1010154
@@ -817,6 +857,7 @@ package android {
field public static final int parentActivityName = 16843687; // 0x10103a7
field public static final deprecated int password = 16843100; // 0x101015c
field public static final int path = 16842794; // 0x101002a
+ field public static final int pathData = 16843810; // 0x1010422
field public static final int pathPattern = 16842796; // 0x101002c
field public static final int pathPrefix = 16842795; // 0x101002b
field public static final int permission = 16842758; // 0x1010006
@@ -826,7 +867,7 @@ package android {
field public static final int persistent = 16842765; // 0x101000d
field public static final int persistentDrawingCache = 16842990; // 0x10100ee
field public static final deprecated int phoneNumber = 16843111; // 0x1010167
- field public static final int pinned = 16843778; // 0x1010402
+ field public static final int pinned = 16843825; // 0x1010431
field public static final int pivotX = 16843189; // 0x10101b5
field public static final int pivotY = 16843190; // 0x10101b6
field public static final int popupAnimationStyle = 16843465; // 0x10102c9
@@ -881,6 +922,7 @@ package android {
field public static final int readPermission = 16842759; // 0x1010007
field public static final int repeatCount = 16843199; // 0x10101bf
field public static final int repeatMode = 16843200; // 0x10101c0
+ field public static final int repeatStyle = 16843816; // 0x1010428
field public static final int reqFiveWayNav = 16843314; // 0x1010232
field public static final int reqHardKeyboard = 16843305; // 0x1010229
field public static final int reqKeyboardType = 16843304; // 0x1010228
@@ -890,7 +932,7 @@ package android {
field public static final int required = 16843406; // 0x101028e
field public static final int requiredAccountType = 16843734; // 0x10103d6
field public static final int requiredForAllUsers = 16843728; // 0x10103d0
- field public static final int requiredForProfile = 16843777; // 0x1010401
+ field public static final int requiredForProfile = 16843824; // 0x1010430
field public static final int requiresFadingEdge = 16843685; // 0x10103a5
field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
field public static final int resizeMode = 16843619; // 0x1010363
@@ -954,6 +996,7 @@ package android {
field public static final int selectableItemBackground = 16843534; // 0x101030e
field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
+ field public static final int sequence = 16843815; // 0x1010427
field public static final int settingsActivity = 16843301; // 0x1010225
field public static final int shadowColor = 16843105; // 0x1010161
field public static final int shadowDx = 16843106; // 0x1010162
@@ -961,7 +1004,7 @@ package android {
field public static final int shadowRadius = 16843108; // 0x1010164
field public static final int shape = 16843162; // 0x101019a
field public static final int shareInterpolator = 16843195; // 0x10101bb
- field public static final int sharedElementName = 16843775; // 0x10103ff
+ field public static final int sharedElementName = 16843803; // 0x101041b
field public static final int sharedUserId = 16842763; // 0x101000b
field public static final int sharedUserLabel = 16843361; // 0x1010261
field public static final int shouldDisableView = 16843246; // 0x10101ee
@@ -1025,6 +1068,10 @@ package android {
field public static final int streamType = 16843273; // 0x1010209
field public static final int stretchColumns = 16843081; // 0x1010149
field public static final int stretchMode = 16843030; // 0x1010116
+ field public static final int stroke = 16843811; // 0x1010423
+ field public static final int strokeLineCap = 16843820; // 0x101042c
+ field public static final int strokeOpacity = 16843812; // 0x1010424
+ field public static final int strokeWidth = 16843813; // 0x1010425
field public static final int subtitle = 16843473; // 0x10102d1
field public static final int subtitleTextStyle = 16843513; // 0x10102f9
field public static final int subtypeExtraValue = 16843674; // 0x101039a
@@ -1138,7 +1185,7 @@ package android {
field public static final int tileMode = 16843265; // 0x1010201
field public static final int timeZone = 16843724; // 0x10103cc
field public static final int tint = 16843041; // 0x1010121
- field public static final int tintMode = 16843770; // 0x10103fa
+ field public static final int tintMode = 16843798; // 0x1010416
field public static final int title = 16843233; // 0x10101e1
field public static final int titleCondensed = 16843234; // 0x10101e2
field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -1160,11 +1207,15 @@ package android {
field public static final int transformPivotX = 16843552; // 0x1010320
field public static final int transformPivotY = 16843553; // 0x1010321
field public static final int transition = 16843743; // 0x10103df
- field public static final int transitionGroup = 16843776; // 0x1010400
+ field public static final int transitionGroup = 16843804; // 0x101041c
field public static final int transitionOrdering = 16843744; // 0x10103e0
field public static final int translationX = 16843554; // 0x1010322
field public static final int translationY = 16843555; // 0x1010323
- field public static final int translationZ = 16843769; // 0x10103f9
+ field public static final int translationZ = 16843797; // 0x1010415
+ field public static final int trigger = 16843805; // 0x101041d
+ field public static final int trimPathEnd = 16843818; // 0x101042a
+ field public static final int trimPathOffset = 16843819; // 0x101042b
+ field public static final int trimPathStart = 16843817; // 0x1010429
field public static final int type = 16843169; // 0x10101a1
field public static final int typeface = 16842902; // 0x1010096
field public static final int uiOptions = 16843672; // 0x1010398
@@ -1189,6 +1240,8 @@ package android {
field public static final int verticalGap = 16843328; // 0x1010240
field public static final int verticalScrollbarPosition = 16843572; // 0x1010334
field public static final int verticalSpacing = 16843029; // 0x1010115
+ field public static final int viewportHeight = 16843807; // 0x101041f
+ field public static final int viewportWidth = 16843806; // 0x101041e
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
field public static final int vmSafeMode = 16843448; // 0x10102b8
@@ -1221,8 +1274,8 @@ package android {
field public static final int windowBackground = 16842836; // 0x1010054
field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
field public static final int windowContentOverlay = 16842841; // 0x1010059
- field public static final int windowContentTransitionManager = 16843768; // 0x10103f8
- field public static final int windowContentTransitions = 16843767; // 0x10103f7
+ field public static final int windowContentTransitionManager = 16843796; // 0x1010414
+ field public static final int windowContentTransitions = 16843795; // 0x1010413
field public static final int windowDisablePreview = 16843298; // 0x1010222
field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
field public static final int windowEnterAnimation = 16842932; // 0x10100b4
@@ -1295,10 +1348,20 @@ package android {
field public static final int app_icon_size = 17104896; // 0x1050000
field public static final int dialog_min_width_major = 17104899; // 0x1050003
field public static final int dialog_min_width_minor = 17104900; // 0x1050004
+ field public static final int l_resource_pad1 = 17104912; // 0x1050010
+ field public static final int l_resource_pad10 = 17104903; // 0x1050007
+ field public static final int l_resource_pad2 = 17104911; // 0x105000f
+ field public static final int l_resource_pad3 = 17104910; // 0x105000e
+ field public static final int l_resource_pad4 = 17104909; // 0x105000d
+ field public static final int l_resource_pad5 = 17104908; // 0x105000c
+ field public static final int l_resource_pad6 = 17104907; // 0x105000b
+ field public static final int l_resource_pad7 = 17104906; // 0x105000a
+ field public static final int l_resource_pad8 = 17104905; // 0x1050009
+ field public static final int l_resource_pad9 = 17104904; // 0x1050008
field public static final int notification_large_icon_height = 17104902; // 0x1050006
field public static final int notification_large_icon_width = 17104901; // 0x1050005
- field public static final int recents_thumbnail_height = 17104903; // 0x1050007
- field public static final int recents_thumbnail_width = 17104904; // 0x1050008
+ field public static final int recents_thumbnail_height = 17104913; // 0x1050011
+ field public static final int recents_thumbnail_width = 17104914; // 0x1050012
field public static final int thumbnail_height = 17104897; // 0x1050001
field public static final int thumbnail_width = 17104898; // 0x1050002
}
@@ -1512,7 +1575,27 @@ package android {
field public static final int inputArea = 16908318; // 0x102001e
field public static final int inputExtractEditText = 16908325; // 0x1020025
field public static final int keyboardView = 16908326; // 0x1020026
+ field public static final int l_resource_pad1 = 16908352; // 0x1020040
+ field public static final int l_resource_pad10 = 16908343; // 0x1020037
+ field public static final int l_resource_pad11 = 16908342; // 0x1020036
+ field public static final int l_resource_pad12 = 16908341; // 0x1020035
+ field public static final int l_resource_pad13 = 16908340; // 0x1020034
+ field public static final int l_resource_pad14 = 16908339; // 0x1020033
+ field public static final int l_resource_pad15 = 16908338; // 0x1020032
+ field public static final int l_resource_pad16 = 16908337; // 0x1020031
+ field public static final int l_resource_pad17 = 16908336; // 0x1020030
+ field public static final int l_resource_pad18 = 16908335; // 0x102002f
+ field public static final int l_resource_pad19 = 16908334; // 0x102002e
+ field public static final int l_resource_pad2 = 16908351; // 0x102003f
+ field public static final int l_resource_pad3 = 16908350; // 0x102003e
+ field public static final int l_resource_pad4 = 16908349; // 0x102003d
+ field public static final int l_resource_pad5 = 16908348; // 0x102003c
+ field public static final int l_resource_pad6 = 16908347; // 0x102003b
+ field public static final int l_resource_pad7 = 16908346; // 0x102003a
+ field public static final int l_resource_pad8 = 16908345; // 0x1020039
+ field public static final int l_resource_pad9 = 16908344; // 0x1020038
field public static final int list = 16908298; // 0x102000a
+ field public static final int mask = 16908354; // 0x1020042
field public static final int message = 16908299; // 0x102000b
field public static final int paste = 16908322; // 0x1020022
field public static final int primary = 16908300; // 0x102000c
@@ -1521,7 +1604,7 @@ package android {
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
field public static final int selectedIcon = 16908302; // 0x102000e
- field public static final int shared_element_name = 16908334; // 0x102002e
+ field public static final int shared_element_name = 16908353; // 0x1020041
field public static final int startSelectingText = 16908328; // 0x1020028
field public static final int stopSelectingText = 16908329; // 0x1020029
field public static final int summary = 16908304; // 0x1020010
@@ -1661,12 +1744,6 @@ package android {
field public static final int MediaButton_Play = 16973882; // 0x103003a
field public static final int MediaButton_Previous = 16973880; // 0x1030038
field public static final int MediaButton_Rew = 16973884; // 0x103003c
- field public static final int Quantum_ButtonBar = 16974498; // 0x10302a2
- field public static final int Quantum_ButtonBar_AlertDialog = 16974497; // 0x10302a1
- field public static final int Quantum_Light_ButtonBar = 16974501; // 0x10302a5
- field public static final int Quantum_Light_ButtonBar_AlertDialog = 16974500; // 0x10302a4
- field public static final int Quantum_Light_SegmentedButton = 16974502; // 0x10302a6
- field public static final int Quantum_SegmentedButton = 16974499; // 0x10302a3
field public static final int TextAppearance = 16973886; // 0x103003e
field public static final int TextAppearance_DeviceDefault = 16974253; // 0x10301ad
field public static final int TextAppearance_DeviceDefault_DialogWindowTitle = 16974264; // 0x10301b8
@@ -1742,40 +1819,48 @@ package android {
field public static final int TextAppearance_Large_Inverse = 16973891; // 0x1030043
field public static final int TextAppearance_Medium = 16973892; // 0x1030044
field public static final int TextAppearance_Medium_Inverse = 16973893; // 0x1030045
- field public static final int TextAppearance_Quantum = 16974318; // 0x10301ee
- field public static final int TextAppearance_Quantum_DialogWindowTitle = 16974319; // 0x10301ef
- field public static final int TextAppearance_Quantum_Inverse = 16974320; // 0x10301f0
- field public static final int TextAppearance_Quantum_Large = 16974321; // 0x10301f1
- field public static final int TextAppearance_Quantum_Large_Inverse = 16974322; // 0x10301f2
- field public static final int TextAppearance_Quantum_Medium = 16974323; // 0x10301f3
- field public static final int TextAppearance_Quantum_Medium_Inverse = 16974324; // 0x10301f4
- field public static final int TextAppearance_Quantum_SearchResult_Subtitle = 16974325; // 0x10301f5
- field public static final int TextAppearance_Quantum_SearchResult_Title = 16974326; // 0x10301f6
- field public static final int TextAppearance_Quantum_Small = 16974327; // 0x10301f7
- field public static final int TextAppearance_Quantum_Small_Inverse = 16974328; // 0x10301f8
- field public static final int TextAppearance_Quantum_Widget = 16974330; // 0x10301fa
- field public static final int TextAppearance_Quantum_Widget_ActionBar_Menu = 16974331; // 0x10301fb
- field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle = 16974332; // 0x10301fc
- field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle_Inverse = 16974333; // 0x10301fd
- field public static final int TextAppearance_Quantum_Widget_ActionBar_Title = 16974334; // 0x10301fe
- field public static final int TextAppearance_Quantum_Widget_ActionBar_Title_Inverse = 16974335; // 0x10301ff
- field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle = 16974336; // 0x1030200
- field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle_Inverse = 16974337; // 0x1030201
- field public static final int TextAppearance_Quantum_Widget_ActionMode_Title = 16974338; // 0x1030202
- field public static final int TextAppearance_Quantum_Widget_ActionMode_Title_Inverse = 16974339; // 0x1030203
- field public static final int TextAppearance_Quantum_Widget_Button = 16974340; // 0x1030204
- field public static final int TextAppearance_Quantum_Widget_DropDownHint = 16974341; // 0x1030205
- field public static final int TextAppearance_Quantum_Widget_DropDownItem = 16974342; // 0x1030206
- field public static final int TextAppearance_Quantum_Widget_EditText = 16974343; // 0x1030207
- field public static final int TextAppearance_Quantum_Widget_IconMenu_Item = 16974344; // 0x1030208
- field public static final int TextAppearance_Quantum_Widget_PopupMenu = 16974345; // 0x1030209
- field public static final int TextAppearance_Quantum_Widget_PopupMenu_Large = 16974346; // 0x103020a
- field public static final int TextAppearance_Quantum_Widget_PopupMenu_Small = 16974347; // 0x103020b
- field public static final int TextAppearance_Quantum_Widget_TabWidget = 16974348; // 0x103020c
- field public static final int TextAppearance_Quantum_Widget_TextView = 16974349; // 0x103020d
- field public static final int TextAppearance_Quantum_Widget_TextView_PopupMenu = 16974350; // 0x103020e
- field public static final int TextAppearance_Quantum_Widget_TextView_SpinnerItem = 16974351; // 0x103020f
- field public static final int TextAppearance_Quantum_WindowTitle = 16974329; // 0x10301f9
+ field public static final int TextAppearance_Quantum = 16974346; // 0x103020a
+ field public static final int TextAppearance_Quantum_Body1 = 16974534; // 0x10302c6
+ field public static final int TextAppearance_Quantum_Body2 = 16974533; // 0x10302c5
+ field public static final int TextAppearance_Quantum_Button = 16974537; // 0x10302c9
+ field public static final int TextAppearance_Quantum_Caption = 16974535; // 0x10302c7
+ field public static final int TextAppearance_Quantum_DialogWindowTitle = 16974347; // 0x103020b
+ field public static final int TextAppearance_Quantum_Display1 = 16974529; // 0x10302c1
+ field public static final int TextAppearance_Quantum_Display2 = 16974528; // 0x10302c0
+ field public static final int TextAppearance_Quantum_Display3 = 16974527; // 0x10302bf
+ field public static final int TextAppearance_Quantum_Display4 = 16974526; // 0x10302be
+ field public static final int TextAppearance_Quantum_Headline = 16974530; // 0x10302c2
+ field public static final int TextAppearance_Quantum_Inverse = 16974348; // 0x103020c
+ field public static final int TextAppearance_Quantum_Large = 16974349; // 0x103020d
+ field public static final int TextAppearance_Quantum_Large_Inverse = 16974350; // 0x103020e
+ field public static final int TextAppearance_Quantum_Medium = 16974351; // 0x103020f
+ field public static final int TextAppearance_Quantum_Medium_Inverse = 16974352; // 0x1030210
+ field public static final int TextAppearance_Quantum_Menu = 16974536; // 0x10302c8
+ field public static final int TextAppearance_Quantum_SearchResult_Subtitle = 16974353; // 0x1030211
+ field public static final int TextAppearance_Quantum_SearchResult_Title = 16974354; // 0x1030212
+ field public static final int TextAppearance_Quantum_Small = 16974355; // 0x1030213
+ field public static final int TextAppearance_Quantum_Small_Inverse = 16974356; // 0x1030214
+ field public static final int TextAppearance_Quantum_Subhead = 16974532; // 0x10302c4
+ field public static final int TextAppearance_Quantum_Title = 16974531; // 0x10302c3
+ field public static final int TextAppearance_Quantum_Widget = 16974358; // 0x1030216
+ field public static final int TextAppearance_Quantum_Widget_ActionBar_Menu = 16974359; // 0x1030217
+ field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle = 16974360; // 0x1030218
+ field public static final int TextAppearance_Quantum_Widget_ActionBar_Title = 16974361; // 0x1030219
+ field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle = 16974362; // 0x103021a
+ field public static final int TextAppearance_Quantum_Widget_ActionMode_Title = 16974363; // 0x103021b
+ field public static final int TextAppearance_Quantum_Widget_Button = 16974364; // 0x103021c
+ field public static final int TextAppearance_Quantum_Widget_DropDownHint = 16974365; // 0x103021d
+ field public static final int TextAppearance_Quantum_Widget_DropDownItem = 16974366; // 0x103021e
+ field public static final int TextAppearance_Quantum_Widget_EditText = 16974367; // 0x103021f
+ field public static final int TextAppearance_Quantum_Widget_IconMenu_Item = 16974368; // 0x1030220
+ field public static final int TextAppearance_Quantum_Widget_PopupMenu = 16974369; // 0x1030221
+ field public static final int TextAppearance_Quantum_Widget_PopupMenu_Large = 16974370; // 0x1030222
+ field public static final int TextAppearance_Quantum_Widget_PopupMenu_Small = 16974371; // 0x1030223
+ field public static final int TextAppearance_Quantum_Widget_TabWidget = 16974372; // 0x1030224
+ field public static final int TextAppearance_Quantum_Widget_TextView = 16974373; // 0x1030225
+ field public static final int TextAppearance_Quantum_Widget_TextView_PopupMenu = 16974374; // 0x1030226
+ field public static final int TextAppearance_Quantum_Widget_TextView_SpinnerItem = 16974375; // 0x1030227
+ field public static final int TextAppearance_Quantum_WindowTitle = 16974357; // 0x1030215
field public static final int TextAppearance_Small = 16973894; // 0x1030046
field public static final int TextAppearance_Small_Inverse = 16973895; // 0x1030047
field public static final int TextAppearance_StatusBar_EventContent = 16973927; // 0x1030067
@@ -1870,34 +1955,34 @@ package android {
field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
field public static final int Theme_NoTitleBar_OverlayActionModes = 16973930; // 0x103006a
field public static final int Theme_Panel = 16973913; // 0x1030059
- field public static final int Theme_Quantum = 16974352; // 0x1030210
- field public static final int Theme_Quantum_Dialog = 16974353; // 0x1030211
- field public static final int Theme_Quantum_DialogWhenLarge = 16974357; // 0x1030215
- field public static final int Theme_Quantum_DialogWhenLarge_NoActionBar = 16974358; // 0x1030216
- field public static final int Theme_Quantum_Dialog_MinWidth = 16974354; // 0x1030212
- field public static final int Theme_Quantum_Dialog_NoActionBar = 16974355; // 0x1030213
- field public static final int Theme_Quantum_Dialog_NoActionBar_MinWidth = 16974356; // 0x1030214
- field public static final int Theme_Quantum_InputMethod = 16974359; // 0x1030217
- field public static final int Theme_Quantum_Light = 16974367; // 0x103021f
- field public static final int Theme_Quantum_Light_DarkActionBar = 16974368; // 0x1030220
- field public static final int Theme_Quantum_Light_Dialog = 16974369; // 0x1030221
- field public static final int Theme_Quantum_Light_DialogWhenLarge = 16974373; // 0x1030225
- field public static final int Theme_Quantum_Light_DialogWhenLarge_NoActionBar = 16974374; // 0x1030226
- field public static final int Theme_Quantum_Light_Dialog_MinWidth = 16974370; // 0x1030222
- field public static final int Theme_Quantum_Light_Dialog_NoActionBar = 16974371; // 0x1030223
- field public static final int Theme_Quantum_Light_Dialog_NoActionBar_MinWidth = 16974372; // 0x1030224
- field public static final int Theme_Quantum_Light_NoActionBar = 16974375; // 0x1030227
- field public static final int Theme_Quantum_Light_NoActionBar_Fullscreen = 16974376; // 0x1030228
- field public static final int Theme_Quantum_Light_NoActionBar_Overscan = 16974377; // 0x1030229
- field public static final int Theme_Quantum_Light_NoActionBar_TranslucentDecor = 16974378; // 0x103022a
- field public static final int Theme_Quantum_Light_Panel = 16974379; // 0x103022b
- field public static final int Theme_Quantum_NoActionBar = 16974360; // 0x1030218
- field public static final int Theme_Quantum_NoActionBar_Fullscreen = 16974361; // 0x1030219
- field public static final int Theme_Quantum_NoActionBar_Overscan = 16974362; // 0x103021a
- field public static final int Theme_Quantum_NoActionBar_TranslucentDecor = 16974363; // 0x103021b
- field public static final int Theme_Quantum_Panel = 16974364; // 0x103021c
- field public static final int Theme_Quantum_Wallpaper = 16974365; // 0x103021d
- field public static final int Theme_Quantum_Wallpaper_NoTitleBar = 16974366; // 0x103021e
+ field public static final int Theme_Quantum = 16974376; // 0x1030228
+ field public static final int Theme_Quantum_Dialog = 16974377; // 0x1030229
+ field public static final int Theme_Quantum_DialogWhenLarge = 16974381; // 0x103022d
+ field public static final int Theme_Quantum_DialogWhenLarge_NoActionBar = 16974382; // 0x103022e
+ field public static final int Theme_Quantum_Dialog_MinWidth = 16974378; // 0x103022a
+ field public static final int Theme_Quantum_Dialog_NoActionBar = 16974379; // 0x103022b
+ field public static final int Theme_Quantum_Dialog_NoActionBar_MinWidth = 16974380; // 0x103022c
+ field public static final int Theme_Quantum_InputMethod = 16974383; // 0x103022f
+ field public static final int Theme_Quantum_Light = 16974391; // 0x1030237
+ field public static final int Theme_Quantum_Light_DarkActionBar = 16974392; // 0x1030238
+ field public static final int Theme_Quantum_Light_Dialog = 16974393; // 0x1030239
+ field public static final int Theme_Quantum_Light_DialogWhenLarge = 16974397; // 0x103023d
+ field public static final int Theme_Quantum_Light_DialogWhenLarge_NoActionBar = 16974398; // 0x103023e
+ field public static final int Theme_Quantum_Light_Dialog_MinWidth = 16974394; // 0x103023a
+ field public static final int Theme_Quantum_Light_Dialog_NoActionBar = 16974395; // 0x103023b
+ field public static final int Theme_Quantum_Light_Dialog_NoActionBar_MinWidth = 16974396; // 0x103023c
+ field public static final int Theme_Quantum_Light_NoActionBar = 16974399; // 0x103023f
+ field public static final int Theme_Quantum_Light_NoActionBar_Fullscreen = 16974400; // 0x1030240
+ field public static final int Theme_Quantum_Light_NoActionBar_Overscan = 16974401; // 0x1030241
+ field public static final int Theme_Quantum_Light_NoActionBar_TranslucentDecor = 16974402; // 0x1030242
+ field public static final int Theme_Quantum_Light_Panel = 16974403; // 0x1030243
+ field public static final int Theme_Quantum_NoActionBar = 16974384; // 0x1030230
+ field public static final int Theme_Quantum_NoActionBar_Fullscreen = 16974385; // 0x1030231
+ field public static final int Theme_Quantum_NoActionBar_Overscan = 16974386; // 0x1030232
+ field public static final int Theme_Quantum_NoActionBar_TranslucentDecor = 16974387; // 0x1030233
+ field public static final int Theme_Quantum_Panel = 16974388; // 0x1030234
+ field public static final int Theme_Quantum_Wallpaper = 16974389; // 0x1030235
+ field public static final int Theme_Quantum_Wallpaper_NoTitleBar = 16974390; // 0x1030236
field public static final int Theme_Translucent = 16973839; // 0x103000f
field public static final int Theme_Translucent_NoTitleBar = 16973840; // 0x1030010
field public static final int Theme_Translucent_NoTitleBar_Fullscreen = 16973841; // 0x1030011
@@ -1954,8 +2039,8 @@ package android {
field public static final int Widget_DeviceDefault_DropDownItem_Spinner = 16974178; // 0x1030162
field public static final int Widget_DeviceDefault_EditText = 16974154; // 0x103014a
field public static final int Widget_DeviceDefault_ExpandableListView = 16974155; // 0x103014b
- field public static final int Widget_DeviceDefault_FastScroll = 16974316; // 0x10301ec
- field public static final int Widget_DeviceDefault_FragmentBreadCrumbs = 16974311; // 0x10301e7
+ field public static final int Widget_DeviceDefault_FastScroll = 16974344; // 0x1030208
+ field public static final int Widget_DeviceDefault_FragmentBreadCrumbs = 16974339; // 0x1030203
field public static final int Widget_DeviceDefault_GridView = 16974156; // 0x103014c
field public static final int Widget_DeviceDefault_HorizontalScrollView = 16974171; // 0x103015b
field public static final int Widget_DeviceDefault_ImageButton = 16974157; // 0x103014d
@@ -1989,8 +2074,8 @@ package android {
field public static final int Widget_DeviceDefault_Light_DropDownItem_Spinner = 16974233; // 0x1030199
field public static final int Widget_DeviceDefault_Light_EditText = 16974206; // 0x103017e
field public static final int Widget_DeviceDefault_Light_ExpandableListView = 16974207; // 0x103017f
- field public static final int Widget_DeviceDefault_Light_FastScroll = 16974317; // 0x10301ed
- field public static final int Widget_DeviceDefault_Light_FragmentBreadCrumbs = 16974312; // 0x10301e8
+ field public static final int Widget_DeviceDefault_Light_FastScroll = 16974345; // 0x1030209
+ field public static final int Widget_DeviceDefault_Light_FragmentBreadCrumbs = 16974340; // 0x1030204
field public static final int Widget_DeviceDefault_Light_GridView = 16974208; // 0x1030180
field public static final int Widget_DeviceDefault_Light_HorizontalScrollView = 16974226; // 0x1030192
field public static final int Widget_DeviceDefault_Light_ImageButton = 16974209; // 0x1030181
@@ -2047,7 +2132,7 @@ package android {
field public static final int Widget_DropDownItem_Spinner = 16973868; // 0x103002c
field public static final int Widget_EditText = 16973859; // 0x1030023
field public static final int Widget_ExpandableListView = 16973860; // 0x1030024
- field public static final int Widget_FastScroll = 16974313; // 0x10301e9
+ field public static final int Widget_FastScroll = 16974341; // 0x1030205
field public static final int Widget_FragmentBreadCrumbs = 16973961; // 0x1030089
field public static final int Widget_Gallery = 16973877; // 0x1030035
field public static final int Widget_GridView = 16973874; // 0x1030032
@@ -2079,8 +2164,8 @@ package android {
field public static final int Widget_Holo_DropDownItem_Spinner = 16973995; // 0x10300ab
field public static final int Widget_Holo_EditText = 16973971; // 0x1030093
field public static final int Widget_Holo_ExpandableListView = 16973972; // 0x1030094
- field public static final int Widget_Holo_FastScroll = 16974314; // 0x10301ea
- field public static final int Widget_Holo_FragmentBreadCrumbs = 16974309; // 0x10301e5
+ field public static final int Widget_Holo_FastScroll = 16974342; // 0x1030206
+ field public static final int Widget_Holo_FragmentBreadCrumbs = 16974337; // 0x1030201
field public static final int Widget_Holo_GridView = 16973973; // 0x1030095
field public static final int Widget_Holo_HorizontalScrollView = 16973988; // 0x10300a4
field public static final int Widget_Holo_ImageButton = 16973974; // 0x1030096
@@ -2114,8 +2199,8 @@ package android {
field public static final int Widget_Holo_Light_DropDownItem_Spinner = 16974041; // 0x10300d9
field public static final int Widget_Holo_Light_EditText = 16974014; // 0x10300be
field public static final int Widget_Holo_Light_ExpandableListView = 16974015; // 0x10300bf
- field public static final int Widget_Holo_Light_FastScroll = 16974315; // 0x10301eb
- field public static final int Widget_Holo_Light_FragmentBreadCrumbs = 16974310; // 0x10301e6
+ field public static final int Widget_Holo_Light_FastScroll = 16974343; // 0x1030207
+ field public static final int Widget_Holo_Light_FragmentBreadCrumbs = 16974338; // 0x1030202
field public static final int Widget_Holo_Light_GridView = 16974016; // 0x10300c0
field public static final int Widget_Holo_Light_HorizontalScrollView = 16974034; // 0x10300d2
field public static final int Widget_Holo_Light_ImageButton = 16974017; // 0x10300c1
@@ -2185,127 +2270,128 @@ package android {
field public static final int Widget_ProgressBar_Large_Inverse = 16973916; // 0x103005c
field public static final int Widget_ProgressBar_Small = 16973854; // 0x103001e
field public static final int Widget_ProgressBar_Small_Inverse = 16973917; // 0x103005d
- field public static final int Widget_Quantum = 16974380; // 0x103022c
- field public static final int Widget_Quantum_ActionBar = 16974381; // 0x103022d
- field public static final int Widget_Quantum_ActionBar_Solid = 16974382; // 0x103022e
- field public static final int Widget_Quantum_ActionBar_TabBar = 16974383; // 0x103022f
- field public static final int Widget_Quantum_ActionBar_TabText = 16974384; // 0x1030230
- field public static final int Widget_Quantum_ActionBar_TabView = 16974385; // 0x1030231
- field public static final int Widget_Quantum_ActionButton = 16974386; // 0x1030232
- field public static final int Widget_Quantum_ActionButton_CloseMode = 16974387; // 0x1030233
- field public static final int Widget_Quantum_ActionButton_Overflow = 16974388; // 0x1030234
- field public static final int Widget_Quantum_ActionButton_TextButton = 16974389; // 0x1030235
- field public static final int Widget_Quantum_ActionMode = 16974390; // 0x1030236
- field public static final int Widget_Quantum_AutoCompleteTextView = 16974391; // 0x1030237
- field public static final int Widget_Quantum_Button = 16974392; // 0x1030238
- field public static final int Widget_Quantum_Button_Borderless = 16974393; // 0x1030239
- field public static final int Widget_Quantum_Button_Borderless_Small = 16974394; // 0x103023a
- field public static final int Widget_Quantum_Button_Inset = 16974395; // 0x103023b
- field public static final int Widget_Quantum_Button_Paper = 16974503; // 0x10302a7
- field public static final int Widget_Quantum_Button_Paper_Color = 16974504; // 0x10302a8
- field public static final int Widget_Quantum_Button_Small = 16974396; // 0x103023c
- field public static final int Widget_Quantum_Button_Toggle = 16974397; // 0x103023d
- field public static final int Widget_Quantum_CalendarView = 16974398; // 0x103023e
- field public static final int Widget_Quantum_CheckedTextView = 16974399; // 0x103023f
- field public static final int Widget_Quantum_CompoundButton_CheckBox = 16974400; // 0x1030240
- field public static final int Widget_Quantum_CompoundButton_RadioButton = 16974401; // 0x1030241
- field public static final int Widget_Quantum_CompoundButton_Star = 16974402; // 0x1030242
- field public static final int Widget_Quantum_DatePicker = 16974403; // 0x1030243
- field public static final int Widget_Quantum_DropDownItem = 16974404; // 0x1030244
- field public static final int Widget_Quantum_DropDownItem_Spinner = 16974405; // 0x1030245
- field public static final int Widget_Quantum_EditText = 16974406; // 0x1030246
- field public static final int Widget_Quantum_ExpandableListView = 16974407; // 0x1030247
- field public static final int Widget_Quantum_FastScroll = 16974408; // 0x1030248
- field public static final int Widget_Quantum_FragmentBreadCrumbs = 16974409; // 0x1030249
- field public static final int Widget_Quantum_GridView = 16974410; // 0x103024a
- field public static final int Widget_Quantum_HorizontalScrollView = 16974411; // 0x103024b
- field public static final int Widget_Quantum_ImageButton = 16974412; // 0x103024c
- field public static final int Widget_Quantum_Light = 16974436; // 0x1030264
- field public static final int Widget_Quantum_Light_ActionBar = 16974437; // 0x1030265
- field public static final int Widget_Quantum_Light_ActionBar_Solid = 16974438; // 0x1030266
- field public static final int Widget_Quantum_Light_ActionBar_Solid_Inverse = 16974439; // 0x1030267
- field public static final int Widget_Quantum_Light_ActionBar_TabBar = 16974440; // 0x1030268
- field public static final int Widget_Quantum_Light_ActionBar_TabBar_Inverse = 16974441; // 0x1030269
- field public static final int Widget_Quantum_Light_ActionBar_TabText = 16974442; // 0x103026a
- field public static final int Widget_Quantum_Light_ActionBar_TabText_Inverse = 16974443; // 0x103026b
- field public static final int Widget_Quantum_Light_ActionBar_TabView = 16974444; // 0x103026c
- field public static final int Widget_Quantum_Light_ActionBar_TabView_Inverse = 16974445; // 0x103026d
- field public static final int Widget_Quantum_Light_ActionButton = 16974446; // 0x103026e
- field public static final int Widget_Quantum_Light_ActionButton_CloseMode = 16974447; // 0x103026f
- field public static final int Widget_Quantum_Light_ActionButton_Overflow = 16974448; // 0x1030270
- field public static final int Widget_Quantum_Light_ActionMode = 16974450; // 0x1030272
- field public static final int Widget_Quantum_Light_ActionMode_Inverse = 16974449; // 0x1030271
- field public static final int Widget_Quantum_Light_AutoCompleteTextView = 16974451; // 0x1030273
- field public static final int Widget_Quantum_Light_Button = 16974452; // 0x1030274
- field public static final int Widget_Quantum_Light_Button_Borderless_Small = 16974453; // 0x1030275
- field public static final int Widget_Quantum_Light_Button_Inset = 16974454; // 0x1030276
- field public static final int Widget_Quantum_Light_Button_Paper = 16974505; // 0x10302a9
- field public static final int Widget_Quantum_Light_Button_Paper_Color = 16974506; // 0x10302aa
- field public static final int Widget_Quantum_Light_Button_Small = 16974455; // 0x1030277
- field public static final int Widget_Quantum_Light_Button_Toggle = 16974456; // 0x1030278
- field public static final int Widget_Quantum_Light_CalendarView = 16974457; // 0x1030279
- field public static final int Widget_Quantum_Light_CheckedTextView = 16974458; // 0x103027a
- field public static final int Widget_Quantum_Light_CompoundButton_CheckBox = 16974459; // 0x103027b
- field public static final int Widget_Quantum_Light_CompoundButton_RadioButton = 16974460; // 0x103027c
- field public static final int Widget_Quantum_Light_CompoundButton_Star = 16974461; // 0x103027d
- field public static final int Widget_Quantum_Light_DropDownItem = 16974462; // 0x103027e
- field public static final int Widget_Quantum_Light_DropDownItem_Spinner = 16974463; // 0x103027f
- field public static final int Widget_Quantum_Light_EditText = 16974464; // 0x1030280
- field public static final int Widget_Quantum_Light_ExpandableListView = 16974465; // 0x1030281
- field public static final int Widget_Quantum_Light_FastScroll = 16974466; // 0x1030282
- field public static final int Widget_Quantum_Light_FragmentBreadCrumbs = 16974467; // 0x1030283
- field public static final int Widget_Quantum_Light_GridView = 16974468; // 0x1030284
- field public static final int Widget_Quantum_Light_HorizontalScrollView = 16974469; // 0x1030285
- field public static final int Widget_Quantum_Light_ImageButton = 16974470; // 0x1030286
- field public static final int Widget_Quantum_Light_ListPopupWindow = 16974471; // 0x1030287
- field public static final int Widget_Quantum_Light_ListView = 16974472; // 0x1030288
- field public static final int Widget_Quantum_Light_ListView_DropDown = 16974473; // 0x1030289
- field public static final int Widget_Quantum_Light_MediaRouteButton = 16974474; // 0x103028a
- field public static final int Widget_Quantum_Light_PopupMenu = 16974475; // 0x103028b
- field public static final int Widget_Quantum_Light_PopupWindow = 16974476; // 0x103028c
- field public static final int Widget_Quantum_Light_ProgressBar = 16974477; // 0x103028d
- field public static final int Widget_Quantum_Light_ProgressBar_Horizontal = 16974478; // 0x103028e
- field public static final int Widget_Quantum_Light_ProgressBar_Inverse = 16974479; // 0x103028f
- field public static final int Widget_Quantum_Light_ProgressBar_Large = 16974480; // 0x1030290
- field public static final int Widget_Quantum_Light_ProgressBar_Large_Inverse = 16974481; // 0x1030291
- field public static final int Widget_Quantum_Light_ProgressBar_Small = 16974482; // 0x1030292
- field public static final int Widget_Quantum_Light_ProgressBar_Small_Inverse = 16974483; // 0x1030293
- field public static final int Widget_Quantum_Light_ProgressBar_Small_Title = 16974484; // 0x1030294
- field public static final int Widget_Quantum_Light_RatingBar = 16974485; // 0x1030295
- field public static final int Widget_Quantum_Light_RatingBar_Indicator = 16974486; // 0x1030296
- field public static final int Widget_Quantum_Light_RatingBar_Small = 16974487; // 0x1030297
- field public static final int Widget_Quantum_Light_ScrollView = 16974488; // 0x1030298
- field public static final int Widget_Quantum_Light_SeekBar = 16974489; // 0x1030299
- field public static final int Widget_Quantum_Light_Spinner = 16974490; // 0x103029a
- field public static final int Widget_Quantum_Light_Tab = 16974491; // 0x103029b
- field public static final int Widget_Quantum_Light_TabWidget = 16974492; // 0x103029c
- field public static final int Widget_Quantum_Light_TextView = 16974493; // 0x103029d
- field public static final int Widget_Quantum_Light_TextView_SpinnerItem = 16974494; // 0x103029e
- field public static final int Widget_Quantum_Light_WebTextView = 16974495; // 0x103029f
- field public static final int Widget_Quantum_Light_WebView = 16974496; // 0x10302a0
- field public static final int Widget_Quantum_ListPopupWindow = 16974413; // 0x103024d
- field public static final int Widget_Quantum_ListView = 16974414; // 0x103024e
- field public static final int Widget_Quantum_ListView_DropDown = 16974415; // 0x103024f
- field public static final int Widget_Quantum_MediaRouteButton = 16974416; // 0x1030250
- field public static final int Widget_Quantum_PopupMenu = 16974417; // 0x1030251
- field public static final int Widget_Quantum_PopupWindow = 16974418; // 0x1030252
- field public static final int Widget_Quantum_ProgressBar = 16974419; // 0x1030253
- field public static final int Widget_Quantum_ProgressBar_Horizontal = 16974420; // 0x1030254
- field public static final int Widget_Quantum_ProgressBar_Large = 16974421; // 0x1030255
- field public static final int Widget_Quantum_ProgressBar_Small = 16974422; // 0x1030256
- field public static final int Widget_Quantum_ProgressBar_Small_Title = 16974423; // 0x1030257
- field public static final int Widget_Quantum_RatingBar = 16974424; // 0x1030258
- field public static final int Widget_Quantum_RatingBar_Indicator = 16974425; // 0x1030259
- field public static final int Widget_Quantum_RatingBar_Small = 16974426; // 0x103025a
- field public static final int Widget_Quantum_ScrollView = 16974427; // 0x103025b
- field public static final int Widget_Quantum_SeekBar = 16974428; // 0x103025c
- field public static final int Widget_Quantum_Spinner = 16974429; // 0x103025d
- field public static final int Widget_Quantum_Tab = 16974430; // 0x103025e
- field public static final int Widget_Quantum_TabWidget = 16974431; // 0x103025f
- field public static final int Widget_Quantum_TextView = 16974432; // 0x1030260
- field public static final int Widget_Quantum_TextView_SpinnerItem = 16974433; // 0x1030261
- field public static final int Widget_Quantum_WebTextView = 16974434; // 0x1030262
- field public static final int Widget_Quantum_WebView = 16974435; // 0x1030263
+ field public static final int Widget_Quantum = 16974404; // 0x1030244
+ field public static final int Widget_Quantum_ActionBar = 16974405; // 0x1030245
+ field public static final int Widget_Quantum_ActionBar_Solid = 16974406; // 0x1030246
+ field public static final int Widget_Quantum_ActionBar_TabBar = 16974407; // 0x1030247
+ field public static final int Widget_Quantum_ActionBar_TabText = 16974408; // 0x1030248
+ field public static final int Widget_Quantum_ActionBar_TabView = 16974409; // 0x1030249
+ field public static final int Widget_Quantum_ActionButton = 16974410; // 0x103024a
+ field public static final int Widget_Quantum_ActionButton_CloseMode = 16974411; // 0x103024b
+ field public static final int Widget_Quantum_ActionButton_Overflow = 16974412; // 0x103024c
+ field public static final int Widget_Quantum_ActionButton_TextButton = 16974413; // 0x103024d
+ field public static final int Widget_Quantum_ActionMode = 16974414; // 0x103024e
+ field public static final int Widget_Quantum_AutoCompleteTextView = 16974415; // 0x103024f
+ field public static final int Widget_Quantum_Button = 16974416; // 0x1030250
+ field public static final int Widget_Quantum_ButtonBar = 16974422; // 0x1030256
+ field public static final int Widget_Quantum_ButtonBar_AlertDialog = 16974423; // 0x1030257
+ field public static final int Widget_Quantum_Button_Borderless = 16974417; // 0x1030251
+ field public static final int Widget_Quantum_Button_Borderless_Small = 16974418; // 0x1030252
+ field public static final int Widget_Quantum_Button_Inset = 16974419; // 0x1030253
+ field public static final int Widget_Quantum_Button_Paper = 16974522; // 0x10302ba
+ field public static final int Widget_Quantum_Button_Paper_Color = 16974523; // 0x10302bb
+ field public static final int Widget_Quantum_Button_Small = 16974420; // 0x1030254
+ field public static final int Widget_Quantum_Button_Toggle = 16974421; // 0x1030255
+ field public static final int Widget_Quantum_CalendarView = 16974424; // 0x1030258
+ field public static final int Widget_Quantum_CheckedTextView = 16974425; // 0x1030259
+ field public static final int Widget_Quantum_CompoundButton_CheckBox = 16974426; // 0x103025a
+ field public static final int Widget_Quantum_CompoundButton_RadioButton = 16974427; // 0x103025b
+ field public static final int Widget_Quantum_CompoundButton_Star = 16974428; // 0x103025c
+ field public static final int Widget_Quantum_DatePicker = 16974429; // 0x103025d
+ field public static final int Widget_Quantum_DropDownItem = 16974430; // 0x103025e
+ field public static final int Widget_Quantum_DropDownItem_Spinner = 16974431; // 0x103025f
+ field public static final int Widget_Quantum_EditText = 16974432; // 0x1030260
+ field public static final int Widget_Quantum_ExpandableListView = 16974433; // 0x1030261
+ field public static final int Widget_Quantum_FastScroll = 16974434; // 0x1030262
+ field public static final int Widget_Quantum_FragmentBreadCrumbs = 16974435; // 0x1030263
+ field public static final int Widget_Quantum_GridView = 16974436; // 0x1030264
+ field public static final int Widget_Quantum_HorizontalScrollView = 16974437; // 0x1030265
+ field public static final int Widget_Quantum_ImageButton = 16974438; // 0x1030266
+ field public static final int Widget_Quantum_Light = 16974463; // 0x103027f
+ field public static final int Widget_Quantum_Light_ActionBar = 16974464; // 0x1030280
+ field public static final int Widget_Quantum_Light_ActionBar_Solid = 16974465; // 0x1030281
+ field public static final int Widget_Quantum_Light_ActionBar_TabBar = 16974466; // 0x1030282
+ field public static final int Widget_Quantum_Light_ActionBar_TabText = 16974467; // 0x1030283
+ field public static final int Widget_Quantum_Light_ActionBar_TabView = 16974468; // 0x1030284
+ field public static final int Widget_Quantum_Light_ActionButton = 16974469; // 0x1030285
+ field public static final int Widget_Quantum_Light_ActionButton_CloseMode = 16974470; // 0x1030286
+ field public static final int Widget_Quantum_Light_ActionButton_Overflow = 16974471; // 0x1030287
+ field public static final int Widget_Quantum_Light_ActionMode = 16974472; // 0x1030288
+ field public static final int Widget_Quantum_Light_AutoCompleteTextView = 16974473; // 0x1030289
+ field public static final int Widget_Quantum_Light_Button = 16974474; // 0x103028a
+ field public static final int Widget_Quantum_Light_ButtonBar = 16974479; // 0x103028f
+ field public static final int Widget_Quantum_Light_ButtonBar_AlertDialog = 16974480; // 0x1030290
+ field public static final int Widget_Quantum_Light_Button_Borderless_Small = 16974475; // 0x103028b
+ field public static final int Widget_Quantum_Light_Button_Inset = 16974476; // 0x103028c
+ field public static final int Widget_Quantum_Light_Button_Paper = 16974524; // 0x10302bc
+ field public static final int Widget_Quantum_Light_Button_Paper_Color = 16974525; // 0x10302bd
+ field public static final int Widget_Quantum_Light_Button_Small = 16974477; // 0x103028d
+ field public static final int Widget_Quantum_Light_Button_Toggle = 16974478; // 0x103028e
+ field public static final int Widget_Quantum_Light_CalendarView = 16974481; // 0x1030291
+ field public static final int Widget_Quantum_Light_CheckedTextView = 16974482; // 0x1030292
+ field public static final int Widget_Quantum_Light_CompoundButton_CheckBox = 16974483; // 0x1030293
+ field public static final int Widget_Quantum_Light_CompoundButton_RadioButton = 16974484; // 0x1030294
+ field public static final int Widget_Quantum_Light_CompoundButton_Star = 16974485; // 0x1030295
+ field public static final int Widget_Quantum_Light_DropDownItem = 16974486; // 0x1030296
+ field public static final int Widget_Quantum_Light_DropDownItem_Spinner = 16974487; // 0x1030297
+ field public static final int Widget_Quantum_Light_EditText = 16974488; // 0x1030298
+ field public static final int Widget_Quantum_Light_ExpandableListView = 16974489; // 0x1030299
+ field public static final int Widget_Quantum_Light_FastScroll = 16974490; // 0x103029a
+ field public static final int Widget_Quantum_Light_FragmentBreadCrumbs = 16974491; // 0x103029b
+ field public static final int Widget_Quantum_Light_GridView = 16974492; // 0x103029c
+ field public static final int Widget_Quantum_Light_HorizontalScrollView = 16974493; // 0x103029d
+ field public static final int Widget_Quantum_Light_ImageButton = 16974494; // 0x103029e
+ field public static final int Widget_Quantum_Light_ListPopupWindow = 16974495; // 0x103029f
+ field public static final int Widget_Quantum_Light_ListView = 16974496; // 0x10302a0
+ field public static final int Widget_Quantum_Light_ListView_DropDown = 16974497; // 0x10302a1
+ field public static final int Widget_Quantum_Light_MediaRouteButton = 16974498; // 0x10302a2
+ field public static final int Widget_Quantum_Light_PopupMenu = 16974499; // 0x10302a3
+ field public static final int Widget_Quantum_Light_PopupWindow = 16974500; // 0x10302a4
+ field public static final int Widget_Quantum_Light_ProgressBar = 16974501; // 0x10302a5
+ field public static final int Widget_Quantum_Light_ProgressBar_Horizontal = 16974502; // 0x10302a6
+ field public static final int Widget_Quantum_Light_ProgressBar_Inverse = 16974503; // 0x10302a7
+ field public static final int Widget_Quantum_Light_ProgressBar_Large = 16974504; // 0x10302a8
+ field public static final int Widget_Quantum_Light_ProgressBar_Large_Inverse = 16974505; // 0x10302a9
+ field public static final int Widget_Quantum_Light_ProgressBar_Small = 16974506; // 0x10302aa
+ field public static final int Widget_Quantum_Light_ProgressBar_Small_Inverse = 16974507; // 0x10302ab
+ field public static final int Widget_Quantum_Light_ProgressBar_Small_Title = 16974508; // 0x10302ac
+ field public static final int Widget_Quantum_Light_RatingBar = 16974509; // 0x10302ad
+ field public static final int Widget_Quantum_Light_RatingBar_Indicator = 16974510; // 0x10302ae
+ field public static final int Widget_Quantum_Light_RatingBar_Small = 16974511; // 0x10302af
+ field public static final int Widget_Quantum_Light_ScrollView = 16974512; // 0x10302b0
+ field public static final int Widget_Quantum_Light_SeekBar = 16974513; // 0x10302b1
+ field public static final int Widget_Quantum_Light_SegmentedButton = 16974514; // 0x10302b2
+ field public static final int Widget_Quantum_Light_Spinner = 16974515; // 0x10302b3
+ field public static final int Widget_Quantum_Light_Tab = 16974516; // 0x10302b4
+ field public static final int Widget_Quantum_Light_TabWidget = 16974517; // 0x10302b5
+ field public static final int Widget_Quantum_Light_TextView = 16974518; // 0x10302b6
+ field public static final int Widget_Quantum_Light_TextView_SpinnerItem = 16974519; // 0x10302b7
+ field public static final int Widget_Quantum_Light_WebTextView = 16974520; // 0x10302b8
+ field public static final int Widget_Quantum_Light_WebView = 16974521; // 0x10302b9
+ field public static final int Widget_Quantum_ListPopupWindow = 16974439; // 0x1030267
+ field public static final int Widget_Quantum_ListView = 16974440; // 0x1030268
+ field public static final int Widget_Quantum_ListView_DropDown = 16974441; // 0x1030269
+ field public static final int Widget_Quantum_MediaRouteButton = 16974442; // 0x103026a
+ field public static final int Widget_Quantum_PopupMenu = 16974443; // 0x103026b
+ field public static final int Widget_Quantum_PopupWindow = 16974444; // 0x103026c
+ field public static final int Widget_Quantum_ProgressBar = 16974445; // 0x103026d
+ field public static final int Widget_Quantum_ProgressBar_Horizontal = 16974446; // 0x103026e
+ field public static final int Widget_Quantum_ProgressBar_Large = 16974447; // 0x103026f
+ field public static final int Widget_Quantum_ProgressBar_Small = 16974448; // 0x1030270
+ field public static final int Widget_Quantum_ProgressBar_Small_Title = 16974449; // 0x1030271
+ field public static final int Widget_Quantum_RatingBar = 16974450; // 0x1030272
+ field public static final int Widget_Quantum_RatingBar_Indicator = 16974451; // 0x1030273
+ field public static final int Widget_Quantum_RatingBar_Small = 16974452; // 0x1030274
+ field public static final int Widget_Quantum_ScrollView = 16974453; // 0x1030275
+ field public static final int Widget_Quantum_SeekBar = 16974454; // 0x1030276
+ field public static final int Widget_Quantum_SegmentedButton = 16974455; // 0x1030277
+ field public static final int Widget_Quantum_Spinner = 16974456; // 0x1030278
+ field public static final int Widget_Quantum_Tab = 16974457; // 0x1030279
+ field public static final int Widget_Quantum_TabWidget = 16974458; // 0x103027a
+ field public static final int Widget_Quantum_TextView = 16974459; // 0x103027b
+ field public static final int Widget_Quantum_TextView_SpinnerItem = 16974460; // 0x103027c
+ field public static final int Widget_Quantum_WebTextView = 16974461; // 0x103027d
+ field public static final int Widget_Quantum_WebView = 16974462; // 0x103027e
field public static final int Widget_RatingBar = 16973857; // 0x1030021
field public static final int Widget_ScrollView = 16973869; // 0x103002d
field public static final int Widget_SeekBar = 16973856; // 0x1030020
@@ -2316,6 +2402,34 @@ package android {
field public static final int Widget_TextView_PopupMenu = 16973865; // 0x1030029
field public static final int Widget_TextView_SpinnerItem = 16973866; // 0x103002a
field public static final int Widget_WebView = 16973875; // 0x1030033
+ field public static final int l_resource_pad1 = 16974336; // 0x1030200
+ field public static final int l_resource_pad10 = 16974327; // 0x10301f7
+ field public static final int l_resource_pad11 = 16974326; // 0x10301f6
+ field public static final int l_resource_pad12 = 16974325; // 0x10301f5
+ field public static final int l_resource_pad13 = 16974324; // 0x10301f4
+ field public static final int l_resource_pad14 = 16974323; // 0x10301f3
+ field public static final int l_resource_pad15 = 16974322; // 0x10301f2
+ field public static final int l_resource_pad16 = 16974321; // 0x10301f1
+ field public static final int l_resource_pad17 = 16974320; // 0x10301f0
+ field public static final int l_resource_pad18 = 16974319; // 0x10301ef
+ field public static final int l_resource_pad19 = 16974318; // 0x10301ee
+ field public static final int l_resource_pad2 = 16974335; // 0x10301ff
+ field public static final int l_resource_pad20 = 16974317; // 0x10301ed
+ field public static final int l_resource_pad21 = 16974316; // 0x10301ec
+ field public static final int l_resource_pad22 = 16974315; // 0x10301eb
+ field public static final int l_resource_pad23 = 16974314; // 0x10301ea
+ field public static final int l_resource_pad24 = 16974313; // 0x10301e9
+ field public static final int l_resource_pad25 = 16974312; // 0x10301e8
+ field public static final int l_resource_pad26 = 16974311; // 0x10301e7
+ field public static final int l_resource_pad27 = 16974310; // 0x10301e6
+ field public static final int l_resource_pad28 = 16974309; // 0x10301e5
+ field public static final int l_resource_pad3 = 16974334; // 0x10301fe
+ field public static final int l_resource_pad4 = 16974333; // 0x10301fd
+ field public static final int l_resource_pad5 = 16974332; // 0x10301fc
+ field public static final int l_resource_pad6 = 16974331; // 0x10301fb
+ field public static final int l_resource_pad7 = 16974330; // 0x10301fa
+ field public static final int l_resource_pad8 = 16974329; // 0x10301f9
+ field public static final int l_resource_pad9 = 16974328; // 0x10301f8
}
public static final class R.xml {
@@ -10760,10 +10874,6 @@ package android.graphics.drawable {
method public void setPicture(android.graphics.Picture);
}
- public class RevealDrawable extends android.graphics.drawable.LayerDrawable {
- ctor public RevealDrawable(android.graphics.drawable.Drawable[]);
- }
-
public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
ctor public RotateDrawable();
method public void draw(android.graphics.Canvas);
@@ -10833,7 +10943,8 @@ package android.graphics.drawable {
method public void addState(int[], android.graphics.drawable.Drawable);
}
- public class TouchFeedbackDrawable extends android.graphics.drawable.DrawableWrapper {
+ public class TouchFeedbackDrawable extends android.graphics.drawable.LayerDrawable {
+ method public android.graphics.Rect getDirtyBounds();
}
public class TransitionDrawable extends android.graphics.drawable.LayerDrawable implements android.graphics.drawable.Drawable.Callback {
@@ -10845,6 +10956,27 @@ package android.graphics.drawable {
method public void startTransition(int);
}
+ public class VectorDrawable extends android.graphics.drawable.Drawable {
+ ctor public VectorDrawable();
+ method public void draw(android.graphics.Canvas);
+ method public float geAnimationFraction();
+ method public int getOpacity();
+ method public int getRepeatCount();
+ method public void setAlpha(int);
+ method public void setAnimationFraction(float);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ method public void setDuration(long);
+ method public void setIntrinsicHeight(int);
+ method public void setIntrinsicWidth(int);
+ method public void setPadding(android.graphics.Rect);
+ method public void setPadding(int, int, int, int);
+ method public void setRepeatCount(int);
+ method public void setRepeatMode(int);
+ method public void start();
+ method public void stop();
+ field public static final int INFINITE = -1; // 0xffffffff
+ }
+
}
package android.graphics.drawable.shapes {
@@ -22125,6 +22257,7 @@ package android.provider {
field public static final java.lang.String EXTRA_MEDIA_ARTIST = "android.intent.extra.artist";
field public static final java.lang.String EXTRA_MEDIA_FOCUS = "android.intent.extra.focus";
field public static final java.lang.String EXTRA_MEDIA_GENRE = "android.intent.extra.genre";
+ field public static final java.lang.String EXTRA_MEDIA_PLAYLIST = "android.intent.extra.playlist";
field public static final java.lang.String EXTRA_MEDIA_RADIO_CHANNEL = "android.intent.extra.radio_channel";
field public static final java.lang.String EXTRA_MEDIA_TITLE = "android.intent.extra.title";
field public static final java.lang.String EXTRA_OUTPUT = "output";
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index cb7e1a0..7c25354 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -14,30 +14,11 @@ LOCAL_SHARED_LIBRARIES := \
libandroid_runtime
LOCAL_MODULE:= app_process
-LOCAL_32_BIT_ONLY := true
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := app_process
+LOCAL_MODULE_STEM_64 := app_process64
include $(BUILD_EXECUTABLE)
-ifeq ($(TARGET_IS_64_BIT),true)
-
-# 64-bit app_process64
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- app_main.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- liblog \
- libbinder \
- libandroid_runtime
-
-LOCAL_MODULE:= app_process64
-LOCAL_NO_2ND_ARCH := true
-include $(BUILD_EXECUTABLE)
-
-endif # TARGET_IS_64_BIT
-
# Build a variant of app_process binary linked with ASan runtime.
# ARM-only at the moment.
ifeq ($(TARGET_ARCH),arm)
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index d513a10..f415c85 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -25,7 +25,7 @@ import android.content.pm.ContainerEncryptionParams;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageManager;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
@@ -39,6 +39,7 @@ import android.content.pm.VerificationParams;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
+import android.os.Bundle;
import android.os.IUserManager;
import android.os.Process;
import android.os.RemoteException;
@@ -700,14 +701,23 @@ public final class Pm {
ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg);
}
- class PackageInstallObserver extends IPackageInstallObserver.Stub {
+ class PackageInstallObserver extends IPackageInstallObserver2.Stub {
boolean finished;
int result;
+ String extraPermission;
+ String extraPackage;
- public void packageInstalled(String name, int status) {
+ @Override
+ public void packageInstalled(String name, Bundle extras, int status) {
synchronized( this) {
finished = true;
result = status;
+ if (status == PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION) {
+ extraPermission = extras.getString(
+ PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION);
+ extraPackage = extras.getString(
+ PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
+ }
notifyAll();
}
}
@@ -717,7 +727,8 @@ public final class Pm {
* Converts a failure code into a string by using reflection to find a matching constant
* in PackageManager.
*/
- private String installFailureToString(int result) {
+ private String installFailureToString(PackageInstallObserver obs) {
+ final int result = obs.result;
Field[] fields = PackageManager.class.getFields();
for (Field f: fields) {
if (f.getType() == int.class) {
@@ -732,7 +743,16 @@ public final class Pm {
// get the int value and compare it to result.
try {
if (result == f.getInt(null)) {
- return fieldName;
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(fieldName);
+ if (obs.extraPermission != null) {
+ sb.append(" perm=");
+ sb.append(obs.extraPermission);
+ }
+ if (obs.extraPackage != null) {
+ sb.append(" pkg=" + obs.extraPackage);
+ }
+ return sb.toString();
}
} catch (IllegalAccessException e) {
// this shouldn't happen since we only look for public static fields.
@@ -956,7 +976,7 @@ public final class Pm {
VerificationParams verificationParams = new VerificationParams(verificationURI,
originatingURI, referrerURI, VerificationParams.NO_UID, null);
- mPm.installPackageWithVerificationAndEncryption(apkURI, obs, installFlags,
+ mPm.installPackageWithVerificationAndEncryptionEtc(apkURI, null, obs, installFlags,
installerPackageName, verificationParams, encryptionParams);
synchronized (obs) {
@@ -970,7 +990,7 @@ public final class Pm {
System.out.println("Success");
} else {
System.err.println("Failure ["
- + installFailureToString(obs.result)
+ + installFailureToString(obs)
+ "]");
}
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0615bd9..6ca5244 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -29,6 +29,7 @@ import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
@@ -1073,7 +1074,7 @@ final class ApplicationPackageManager extends PackageManager {
public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
String installerPackageName) {
try {
- mPM.installPackage(packageURI, observer, flags, installerPackageName);
+ mPM.installPackageEtc(packageURI, observer, null, flags, installerPackageName);
} catch (RemoteException e) {
// Should never happen!
}
@@ -1084,8 +1085,8 @@ final class ApplicationPackageManager extends PackageManager {
int flags, String installerPackageName, Uri verificationURI,
ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
try {
- mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
- verificationURI, manifestDigest, encryptionParams);
+ mPM.installPackageWithVerificationEtc(packageURI, observer, null, flags,
+ installerPackageName, verificationURI, manifestDigest, encryptionParams);
} catch (RemoteException e) {
// Should never happen!
}
@@ -1096,8 +1097,46 @@ final class ApplicationPackageManager extends PackageManager {
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
try {
- mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
- installerPackageName, verificationParams, encryptionParams);
+ mPM.installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null,
+ flags, installerPackageName, verificationParams, encryptionParams);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ // Expanded observer-API versions
+ @Override
+ public void installPackage(Uri packageURI, PackageInstallObserver observer,
+ int flags, String installerPackageName) {
+ try {
+ mPM.installPackageEtc(packageURI, null, observer.mObserver,
+ flags, installerPackageName);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
+ public void installPackageWithVerification(Uri packageURI,
+ PackageInstallObserver observer, int flags, String installerPackageName,
+ Uri verificationURI, ManifestDigest manifestDigest,
+ ContainerEncryptionParams encryptionParams) {
+ try {
+ mPM.installPackageWithVerificationEtc(packageURI, null, observer.mObserver, flags,
+ installerPackageName, verificationURI, manifestDigest, encryptionParams);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ PackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ try {
+ mPM.installPackageWithVerificationAndEncryptionEtc(packageURI, null,
+ observer.mObserver, flags, installerPackageName, verificationParams,
+ encryptionParams);
} catch (RemoteException e) {
// Should never happen!
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 13e74da..36d2635 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -17,12 +17,14 @@
package android.app;
import com.android.internal.R;
+import com.android.internal.util.LegacyNotificationUtil;
import android.annotation.IntDef;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.PorterDuff;
import android.media.AudioManager;
import android.net.Uri;
import android.os.BadParcelableException;
@@ -653,13 +655,6 @@ public class Notification implements Parcelable
public static final String EXTRA_AS_HEADS_UP = "headsup";
/**
- * Extra added from {@link Notification.Builder} to indicate that the remote views were inflated
- * from the builder, as opposed to being created directly from the application.
- * @hide
- */
- public static final String EXTRA_BUILDER_REMOTE_VIEWS = "android.builderRemoteViews";
-
- /**
* Allow certain system-generated notifications to appear before the device is provisioned.
* Only available to notifications coming from the android package.
* @hide
@@ -1315,6 +1310,7 @@ public class Notification implements Parcelable
private int mVisibility = VISIBILITY_PRIVATE;
private Notification mPublicVersion = null;
private boolean mQuantumTheme;
+ private final LegacyNotificationUtil mLegacyNotificationUtil;
/**
* Constructs a new Builder with the defaults:
@@ -1345,6 +1341,10 @@ public class Notification implements Parcelable
// TODO: Decide on targetSdk from calling app whether to use quantum theme.
mQuantumTheme = true;
+
+ // TODO: Decide on targetSdk from calling app whether to instantiate the processor at
+ // all.
+ mLegacyNotificationUtil = LegacyNotificationUtil.getInstance();
}
/**
@@ -1846,42 +1846,50 @@ public class Notification implements Parcelable
boolean showLine3 = false;
boolean showLine2 = false;
int smallIconImageViewId = R.id.icon;
- if (mLargeIcon != null) {
- contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
- smallIconImageViewId = R.id.right_icon;
- }
if (!mQuantumTheme && mPriority < PRIORITY_LOW) {
contentView.setInt(R.id.icon,
"setBackgroundResource", R.drawable.notification_template_icon_low_bg);
contentView.setInt(R.id.status_bar_latest_event_content,
"setBackgroundResource", R.drawable.notification_bg_low);
}
+ if (mLargeIcon != null) {
+ contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
+ processLegacyLargeIcon(mLargeIcon, contentView);
+ smallIconImageViewId = R.id.right_icon;
+ }
if (mSmallIcon != 0) {
contentView.setImageViewResource(smallIconImageViewId, mSmallIcon);
contentView.setViewVisibility(smallIconImageViewId, View.VISIBLE);
+ if (mLargeIcon != null) {
+ processLegacySmallIcon(mSmallIcon, smallIconImageViewId, contentView);
+ } else {
+ processLegacyLargeIcon(mSmallIcon, contentView);
+ }
+
} else {
contentView.setViewVisibility(smallIconImageViewId, View.GONE);
}
if (mContentTitle != null) {
- contentView.setTextViewText(R.id.title, mContentTitle);
+ contentView.setTextViewText(R.id.title, processLegacyText(mContentTitle));
}
if (mContentText != null) {
- contentView.setTextViewText(R.id.text, mContentText);
+ contentView.setTextViewText(R.id.text, processLegacyText(mContentText));
showLine3 = true;
}
if (mContentInfo != null) {
- contentView.setTextViewText(R.id.info, mContentInfo);
+ contentView.setTextViewText(R.id.info, processLegacyText(mContentInfo));
contentView.setViewVisibility(R.id.info, View.VISIBLE);
showLine3 = true;
} else if (mNumber > 0) {
final int tooBig = mContext.getResources().getInteger(
R.integer.status_bar_notification_info_maxnum);
if (mNumber > tooBig) {
- contentView.setTextViewText(R.id.info, mContext.getResources().getString(
- R.string.status_bar_notification_info_overflow));
+ contentView.setTextViewText(R.id.info, processLegacyText(
+ mContext.getResources().getString(
+ R.string.status_bar_notification_info_overflow)));
} else {
NumberFormat f = NumberFormat.getIntegerInstance();
- contentView.setTextViewText(R.id.info, f.format(mNumber));
+ contentView.setTextViewText(R.id.info, processLegacyText(f.format(mNumber)));
}
contentView.setViewVisibility(R.id.info, View.VISIBLE);
showLine3 = true;
@@ -1891,9 +1899,9 @@ public class Notification implements Parcelable
// Need to show three lines?
if (mSubText != null) {
- contentView.setTextViewText(R.id.text, mSubText);
+ contentView.setTextViewText(R.id.text, processLegacyText(mSubText));
if (mContentText != null) {
- contentView.setTextViewText(R.id.text2, mContentText);
+ contentView.setTextViewText(R.id.text2, processLegacyText(mContentText));
contentView.setViewVisibility(R.id.text2, View.VISIBLE);
showLine2 = true;
} else {
@@ -2001,15 +2009,78 @@ public class Notification implements Parcelable
tombstone ? getActionTombstoneLayoutResource()
: getActionLayoutResource());
button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
- button.setTextViewText(R.id.action0, action.title);
+ button.setTextViewText(R.id.action0, processLegacyText(action.title));
if (!tombstone) {
button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
}
button.setContentDescription(R.id.action0, action.title);
+ processLegacyAction(action, button);
return button;
}
/**
+ * @return Whether we are currently building a notification from a legacy (an app that
+ * doesn't create quantum notifications by itself) app.
+ */
+ private boolean isLegacy() {
+ return mLegacyNotificationUtil != null;
+ }
+
+ private void processLegacyAction(Action action, RemoteViews button) {
+ if (isLegacy()) {
+ if (mLegacyNotificationUtil.isGrayscale(mContext, action.icon)) {
+ button.setTextViewCompoundDrawablesRelativeColorFilter(R.id.action0, 0,
+ mContext.getResources().getColor(
+ R.color.notification_action_legacy_color_filter),
+ PorterDuff.Mode.MULTIPLY);
+ }
+ }
+ }
+
+ private CharSequence processLegacyText(CharSequence charSequence) {
+ if (isLegacy()) {
+ return mLegacyNotificationUtil.invertCharSequenceColors(charSequence);
+ } else {
+ return charSequence;
+ }
+ }
+
+ private void processLegacyLargeIcon(int largeIconId, RemoteViews contentView) {
+ if (isLegacy()) {
+ processLegacyLargeIcon(
+ mLegacyNotificationUtil.isGrayscale(mContext, largeIconId),
+ contentView);
+ }
+ }
+
+ private void processLegacyLargeIcon(Bitmap largeIcon, RemoteViews contentView) {
+ if (isLegacy()) {
+ processLegacyLargeIcon(
+ mLegacyNotificationUtil.isGrayscale(largeIcon),
+ contentView);
+ }
+ }
+
+ private void processLegacyLargeIcon(boolean isGrayscale, RemoteViews contentView) {
+ if (isLegacy() && isGrayscale) {
+ contentView.setInt(R.id.icon, "setBackgroundResource",
+ R.drawable.notification_icon_legacy_bg_inset);
+ }
+ }
+
+ private void processLegacySmallIcon(int smallIconDrawableId, int smallIconImageViewId,
+ RemoteViews contentView) {
+ if (isLegacy()) {
+ if (mLegacyNotificationUtil.isGrayscale(mContext, smallIconDrawableId)) {
+ contentView.setDrawableParameters(smallIconImageViewId, false, -1,
+ mContext.getResources().getColor(
+ R.color.notification_action_legacy_color_filter),
+ PorterDuff.Mode.MULTIPLY, -1);
+ }
+ }
+ }
+
+ /**
* Apply the unstyled operations and return a new {@link Notification} object.
* @hide
*/
@@ -2075,7 +2146,6 @@ public class Notification implements Parcelable
extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate);
extras.putBoolean(EXTRA_SHOW_CHRONOMETER, mUseChronometer);
extras.putBoolean(EXTRA_SHOW_WHEN, mShowWhen);
- extras.putBoolean(EXTRA_BUILDER_REMOTE_VIEWS, mContentView == null);
if (mLargeIcon != null) {
extras.putParcelable(EXTRA_LARGE_ICON, mLargeIcon);
}
@@ -2226,7 +2296,7 @@ public class Notification implements Parcelable
mSummaryTextSet ? mSummaryText
: mBuilder.mSubText;
if (overflowText != null) {
- contentView.setTextViewText(R.id.text, overflowText);
+ contentView.setTextViewText(R.id.text, mBuilder.processLegacyText(overflowText));
contentView.setViewVisibility(R.id.overflow_divider, View.VISIBLE);
contentView.setViewVisibility(R.id.line3, View.VISIBLE);
} else {
@@ -2437,7 +2507,7 @@ public class Notification implements Parcelable
contentView.setViewPadding(R.id.line1, 0, 0, 0, 0);
}
- contentView.setTextViewText(R.id.big_text, mBigText);
+ contentView.setTextViewText(R.id.big_text, mBuilder.processLegacyText(mBigText));
contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
contentView.setViewVisibility(R.id.text2, View.GONE);
@@ -2542,7 +2612,7 @@ public class Notification implements Parcelable
CharSequence str = mTexts.get(i);
if (str != null && !str.equals("")) {
contentView.setViewVisibility(rowIds[i], View.VISIBLE);
- contentView.setTextViewText(rowIds[i], str);
+ contentView.setTextViewText(rowIds[i], mBuilder.processLegacyText(str));
}
i++;
}
diff --git a/core/java/android/app/PackageInstallObserver.java b/core/java/android/app/PackageInstallObserver.java
new file mode 100644
index 0000000..dacffb4
--- /dev/null
+++ b/core/java/android/app/PackageInstallObserver.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.pm.IPackageInstallObserver2;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+/**
+ * @hide
+ *
+ * New-style observer for package installers to use.
+ */
+public class PackageInstallObserver {
+ IPackageInstallObserver2.Stub mObserver = new IPackageInstallObserver2.Stub() {
+ @Override
+ public void packageInstalled(String pkgName, Bundle extras, int result)
+ throws RemoteException {
+ PackageInstallObserver.this.packageInstalled(pkgName, extras, result);
+ }
+ };
+
+ /**
+ * This method will be called to report the result of the package installation attempt.
+ *
+ * @param pkgName Name of the package whose installation was attempted
+ * @param extras If non-null, this Bundle contains extras providing additional information
+ * about an install failure. See {@link android.content.pm.PackageManager} for
+ * documentation about which extras apply to various failures; in particular the
+ * strings named EXTRA_FAILURE_*.
+ * @param result The numeric success or failure code indicating the basic outcome
+ */
+ public void packageInstalled(String pkgName, Bundle extras, int result) {
+ }
+}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0175d62..102433b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2173,6 +2173,11 @@ public class Intent implements Parcelable, Cloneable {
/**
* Broadcast Action: Wired Headset plugged in or unplugged.
*
+ * You <em>cannot</em> receive this through components declared
+ * in manifests, only by explicitly registering for it with
+ * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+ * Context.registerReceiver()}.
+ *
* <p>The intent will have the following extra values:
* <ul>
* <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
diff --git a/core/java/android/content/pm/IPackageInstallObserver2.aidl b/core/java/android/content/pm/IPackageInstallObserver2.aidl
new file mode 100644
index 0000000..2602ab5
--- /dev/null
+++ b/core/java/android/content/pm/IPackageInstallObserver2.aidl
@@ -0,0 +1,45 @@
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+import android.os.Bundle;
+
+/**
+ * API for installation callbacks from the Package Manager. In certain result cases
+ * additional information will be provided.
+ * @hide
+ */
+oneway interface IPackageInstallObserver2 {
+ /**
+ * The install operation has completed. {@code returnCode} holds a numeric code
+ * indicating success or failure. In certain cases the {@code extras} Bundle will
+ * contain additional details:
+ *
+ * <p><table>
+ * <tr>
+ * <td>INSTALL_FAILED_DUPLICATE_PERMISSION</td>
+ * <td>Two strings are provided in the extras bundle: EXTRA_EXISTING_PERMISSION
+ * is the name of the permission that the app is attempting to define, and
+ * EXTRA_EXISTING_PACKAGE is the package name of the app which has already
+ * defined the permission.</td>
+ * </tr>
+ * </table>
+ */
+ void packageInstalled(in String packageName, in Bundle extras, int returnCode);
+}
+
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c9fb530..ae0899f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -25,6 +25,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.ContainerEncryptionParams;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageMoveObserver;
@@ -406,6 +407,21 @@ interface IPackageManager {
in VerificationParams verificationParams,
in ContainerEncryptionParams encryptionParams);
+ /** Expanded observer versions */
+ void installPackageEtc(in Uri packageURI, IPackageInstallObserver observer,
+ IPackageInstallObserver2 observer2, int flags, in String installerPackageName);
+
+ void installPackageWithVerificationEtc(in Uri packageURI,
+ in IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
+ int flags, in String installerPackageName, in Uri verificationURI,
+ in ManifestDigest manifestDigest, in ContainerEncryptionParams encryptionParams);
+
+ void installPackageWithVerificationAndEncryptionEtc(in Uri packageURI,
+ in IPackageInstallObserver observer, in IPackageInstallObserver2 observer2,
+ int flags, in String installerPackageName,
+ in VerificationParams verificationParams,
+ in ContainerEncryptionParams encryptionParams);
+
int installExistingPackageAsUser(String packageName, int userId);
void verifyPendingInstall(int id, int verificationCode);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e86833b..ceb7764 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -19,6 +19,7 @@ package android.content.pm;
import android.annotation.IntDef;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.app.PackageInstallObserver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -683,6 +684,20 @@ public abstract class PackageManager {
public static final int INSTALL_FAILED_USER_RESTRICTED = -111;
/**
+ * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the system failed to install the package because it is attempting to define a
+ * permission that is already defined by some existing package.
+ *
+ * <p>The package name of the app which has already defined the permission is passed to
+ * a {@link IPackageInstallObserver2}, if any, as the {@link #EXTRA_EXISTING_PACKAGE}
+ * string extra; and the name of the permission being redefined is passed in the
+ * {@link #EXTRA_EXISTING_PERMISSION} string extra.
+ * @hide
+ */
+ public static final int INSTALL_FAILED_DUPLICATE_PERMISSION = -112;
+
+ /**
* Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
* package's data directory.
*
@@ -1390,6 +1405,24 @@ public abstract class PackageManager {
= "android.content.pm.extra.PERMISSION_LIST";
/**
+ * String extra for {@link IPackageInstallObserver2} in the 'extras' Bundle in case of
+ * {@link #INSTALL_FAILED_DUPLICATE_PERMISSION}. This extra names the package which provides
+ * the existing definition for the permission.
+ * @hide
+ */
+ public static final String EXTRA_FAILURE_EXISTING_PACKAGE
+ = "android.content.pm.extra.FAILURE_EXISTING_PACKAGE";
+
+ /**
+ * String extra for {@link IPackageInstallObserver2} in the 'extras' Bundle in case of
+ * {@link #INSTALL_FAILED_DUPLICATE_PERMISSION}. This extra names the permission that is
+ * being redundantly defined by the package being installed.
+ * @hide
+ */
+ public static final String EXTRA_FAILURE_EXISTING_PERMISSION
+ = "android.content.pm.extra.FAILURE_EXISTING_PERMISSION";
+
+ /**
* Retrieve overall information about an application package that is
* installed on the system.
* <p>
@@ -2752,11 +2785,14 @@ public abstract class PackageManager {
* 'content:' URI.
* @param observer An observer callback to get notified when the package installation is
* complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
- * called when that happens. observer may be null to indicate that no callback is desired.
+ * called when that happens. This parameter must not be null.
* @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
* {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
* @param installerPackageName Optional package name of the application that is performing the
* installation. This identifies which market the package came from.
+ * @deprecated Use {@link #installPackage(Uri, IPackageInstallObserver2, int, String)}
+ * instead. This method will continue to be supported but the older observer interface
+ * will not get additional failure details.
*/
public abstract void installPackage(
Uri packageURI, IPackageInstallObserver observer, int flags,
@@ -2772,11 +2808,9 @@ public abstract class PackageManager {
* @param observer An observer callback to get notified when the package
* installation is complete.
* {@link IPackageInstallObserver#packageInstalled(String, int)}
- * will be called when that happens. observer may be null to
- * indicate that no callback is desired.
+ * will be called when that happens. This parameter must not be null.
* @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
- * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}
- * .
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
* @param installerPackageName Optional package name of the application that
* is performing the installation. This identifies which market
* the package came from.
@@ -2789,6 +2823,10 @@ public abstract class PackageManager {
* these parameters describing the encryption and authentication
* used. May be {@code null}.
* @hide
+ * @deprecated Use {@link #installPackageWithVerification(Uri, IPackageInstallObserver2,
+ * int, String, Uri, ManifestDigest, ContainerEncryptionParams)} instead. This method will
+ * continue to be supported but the older observer interface will not get additional failure
+ * details.
*/
public abstract void installPackageWithVerification(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
@@ -2805,11 +2843,9 @@ public abstract class PackageManager {
* @param observer An observer callback to get notified when the package
* installation is complete.
* {@link IPackageInstallObserver#packageInstalled(String, int)}
- * will be called when that happens. observer may be null to
- * indicate that no callback is desired.
+ * will be called when that happens. This parameter must not be null.
* @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
- * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}
- * .
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
* @param installerPackageName Optional package name of the application that
* is performing the installation. This identifies which market
* the package came from.
@@ -2820,12 +2856,101 @@ public abstract class PackageManager {
* used. May be {@code null}.
*
* @hide
+ * @deprecated Use {@link #installPackageWithVerificationAndEncryption(Uri,
+ * IPackageInstallObserver2, int, String, VerificationParams,
+ * ContainerEncryptionParams)} instead. This method will continue to be
+ * supported but the older observer interface will not get additional failure details.
*/
+ @Deprecated
public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams,
ContainerEncryptionParams encryptionParams);
+ // Package-install variants that take the new, expanded form of observer interface.
+ // Note that these *also* take the original observer type and will redundantly
+ // report the same information to that observer if supplied; but it is not required.
+
+ /**
+ * @hide
+ *
+ * Install a package. Since this may take a little while, the result will
+ * be posted back to the given observer. An installation will fail if the calling context
+ * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
+ * package named in the package file's manifest is already installed, or if there's no space
+ * available on the device.
+ *
+ * @param packageURI The location of the package file to install. This can be a 'file:' or a
+ * 'content:' URI.
+ * @param observer An observer callback to get notified when the package installation is
+ * complete. {@link PackageInstallObserver#packageInstalled(String, Bundle, int)} will be
+ * called when that happens. This parameter must not be null.
+ * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
+ * @param installerPackageName Optional package name of the application that is performing the
+ * installation. This identifies which market the package came from.
+ */
+ public abstract void installPackage(
+ Uri packageURI, PackageInstallObserver observer,
+ int flags, String installerPackageName);
+
+ /**
+ * Similar to
+ * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
+ * with an extra verification file provided.
+ *
+ * @param packageURI The location of the package file to install. This can
+ * be a 'file:' or a 'content:' URI.
+ * @param observer An observer callback to get notified when the package installation is
+ * complete. {@link PackageInstallObserver#packageInstalled(String, Bundle, int)} will be
+ * called when that happens. This parameter must not be null.
+ * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
+ * @param installerPackageName Optional package name of the application that
+ * is performing the installation. This identifies which market
+ * the package came from.
+ * @param verificationURI The location of the supplementary verification
+ * file. This can be a 'file:' or a 'content:' URI. May be
+ * {@code null}.
+ * @param manifestDigest an object that holds the digest of the package
+ * which can be used to verify ownership. May be {@code null}.
+ * @param encryptionParams if the package to be installed is encrypted,
+ * these parameters describing the encryption and authentication
+ * used. May be {@code null}.
+ * @hide
+ */
+ public abstract void installPackageWithVerification(Uri packageURI,
+ PackageInstallObserver observer, int flags, String installerPackageName,
+ Uri verificationURI, ManifestDigest manifestDigest,
+ ContainerEncryptionParams encryptionParams);
+
+ /**
+ * Similar to
+ * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
+ * with an extra verification information provided.
+ *
+ * @param packageURI The location of the package file to install. This can
+ * be a 'file:' or a 'content:' URI.
+ * @param observer An observer callback to get notified when the package installation is
+ * complete. {@link PackageInstallObserver#packageInstalled(String, Bundle, int)} will be
+ * called when that happens. This parameter must not be null.
+ * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
+ * @param installerPackageName Optional package name of the application that
+ * is performing the installation. This identifies which market
+ * the package came from.
+ * @param verificationParams an object that holds signal information to
+ * assist verification. May be {@code null}.
+ * @param encryptionParams if the package to be installed is encrypted,
+ * these parameters describing the encryption and authentication
+ * used. May be {@code null}.
+ *
+ * @hide
+ */
+ public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
+ PackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams);
+
/**
* If there is already an application with the given package name installed
* on the system for other users, also install it for the calling user.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index cf44ad8..8898beb 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1105,7 +1105,6 @@ public class PackageParser {
if (!parseUsesPermission(pkg, res, parser, attrs, outError)) {
return null;
}
-
} else if (tagName.equals("uses-configuration")) {
ConfigurationInfo cPref = new ConfigurationInfo();
sa = res.obtainAttributes(attrs,
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 419abf2..5674154 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -19,6 +19,7 @@ package android.content.res;
import android.graphics.Color;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -181,10 +182,9 @@ public class ColorStateList implements Parcelable {
final int innerDepth = parser.getDepth()+1;
int depth;
- int listAllocated = 20;
+ int[][] stateSpecList = ArrayUtils.newUnpaddedArray(int[].class, 20);
+ int[] colorList = new int[stateSpecList.length];
int listSize = 0;
- int[] colorList = new int[listAllocated];
- int[][] stateSpecList = new int[listAllocated][];
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& ((depth=parser.getDepth()) >= innerDepth
@@ -248,21 +248,8 @@ public class ColorStateList implements Parcelable {
mDefaultColor = color;
}
- if (listSize + 1 >= listAllocated) {
- listAllocated = ArrayUtils.idealIntArraySize(listSize + 1);
-
- int[] ncolor = new int[listAllocated];
- System.arraycopy(colorList, 0, ncolor, 0, listSize);
-
- int[][] nstate = new int[listAllocated][];
- System.arraycopy(stateSpecList, 0, nstate, 0, listSize);
-
- colorList = ncolor;
- stateSpecList = nstate;
- }
-
- colorList[listSize] = color;
- stateSpecList[listSize] = stateSpec;
+ colorList = GrowingArrayUtils.append(colorList, listSize, color);
+ stateSpecList = GrowingArrayUtils.append(stateSpecList, listSize, stateSpec);
listSize++;
}
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index d7199ff..9fb2846 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -793,10 +793,9 @@ public class TypedArray {
public int[] extractThemeAttrs() {
int[] attrs = null;
- final int N = getIndexCount();
+ final int N = length();
for (int i = 0; i < N; i++) {
- final int index = getIndex(i);
- final int attrId = getThemeAttributeId(index, 0);
+ final int attrId = getThemeAttributeId(i, 0);
if (attrId != 0) {
if (attrs == null) {
attrs = new int[N];
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index a28b5a7..d06355d 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -22,6 +22,8 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
@@ -74,13 +76,16 @@ public class CertificateChainValidator {
private CertificateChainValidator() {
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X.509");
+ tmf.init((KeyStore) null);
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509ExtendedTrustManager) {
mTrustManager = (X509ExtendedTrustManager) tm;
}
}
} catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("X.509 TrustManager factory must be available", e);
+ throw new RuntimeException("X.509 TrustManagerFactory must be available", e);
+ } catch (KeyStoreException e) {
+ throw new RuntimeException("X.509 TrustManagerFactory cannot be initialized", e);
}
if (mTrustManager == null) {
@@ -166,9 +171,13 @@ public class CertificateChainValidator {
TrustManagerFactory tmf;
try {
tmf = TrustManagerFactory.getInstance("X.509");
+ tmf.init((KeyStore) null);
} catch (NoSuchAlgorithmException e) {
Slog.w(TAG, "Couldn't find default X.509 TrustManagerFactory");
return;
+ } catch (KeyStoreException e) {
+ Slog.w(TAG, "Couldn't initialize default X.509 TrustManagerFactory", e);
+ return;
}
TrustManager[] tms = tmf.getTrustManagers();
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 4180860..b97734e 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -694,36 +694,6 @@ public interface IMountService extends IInterface {
return _result;
}
- public String getPassword() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getPassword, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public void clearPassword() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
public StorageVolume[] getVolumeList() throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -876,11 +846,7 @@ public interface IMountService extends IInterface {
static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34;
- static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 35;
-
- static final int TRANSACTION_getPassword = IBinder.FIRST_CALL_TRANSACTION + 36;
-
- static final int TRANSACTION_clearPassword = IBinder.FIRST_CALL_TRANSACTION + 37;
+ static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 36;
/**
* Cast an IBinder object into an IMountService interface, generating a
@@ -1242,19 +1208,6 @@ public interface IMountService extends IInterface {
reply.writeInt(result);
return true;
}
- case TRANSACTION_getPassword: {
- data.enforceInterface(DESCRIPTOR);
- String result = getPassword();
- reply.writeNoException();
- reply.writeString(result);
- return true;
- }
- case TRANSACTION_clearPassword: {
- data.enforceInterface(DESCRIPTOR);
- clearPassword();
- reply.writeNoException();
- return true;
- }
}
return super.onTransact(code, data, reply, flags);
}
@@ -1493,15 +1446,4 @@ public interface IMountService extends IInterface {
* @return PasswordType
*/
public int getPasswordType() throws RemoteException;
-
- /**
- * Get password from vold
- * @return password or empty string
- */
- public String getPassword() throws RemoteException;
-
- /**
- * Securely clear password from vold
- */
- public void clearPassword() throws RemoteException;
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index bd576af..ae24968 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -173,6 +173,10 @@ public final class MediaStore {
*/
public static final String EXTRA_MEDIA_GENRE = "android.intent.extra.genre";
/**
+ * The name of the Intent-extra used to define the playlist.
+ */
+ public static final String EXTRA_MEDIA_PLAYLIST = "android.intent.extra.playlist";
+ /**
* The name of the Intent-extra used to define the radio channel.
*/
public static final String EXTRA_MEDIA_RADIO_CHANNEL = "android.intent.extra.radio_channel";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7777334..7062933 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6098,21 +6098,18 @@ public final class Settings {
"lock_screen_show_notifications";
/**
- * Defines global zen mode. One of ZEN_MODE_OFF, ZEN_MODE_LIMITED, ZEN_MODE_FULL.
+ * Defines global zen mode. ZEN_MODE_OFF or ZEN_MODE_ON.
*
* @hide
*/
public static final String ZEN_MODE = "zen_mode";
/** @hide */ public static final int ZEN_MODE_OFF = 0;
- /** @hide */ public static final int ZEN_MODE_LIMITED = 1;
- /** @hide */ public static final int ZEN_MODE_FULL = 2;
+ /** @hide */ public static final int ZEN_MODE_ON = 1;
/** @hide */ public static String zenModeToString(int mode) {
if (mode == ZEN_MODE_OFF) return "ZEN_MODE_OFF";
- if (mode == ZEN_MODE_LIMITED) return "ZEN_MODE_LIMITED";
- if (mode == ZEN_MODE_FULL) return "ZEN_MODE_FULL";
- throw new IllegalArgumentException("Invalid zen mode: " + mode);
+ return "ZEN_MODE_ON";
}
/**
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 06935ae..77ef1da 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -21,6 +21,7 @@ import android.text.style.UpdateLayout;
import android.text.style.WrapTogetherSpan;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
import java.lang.ref.WeakReference;
@@ -401,7 +402,7 @@ public class DynamicLayout extends Layout
if (mBlockEndLines == null) {
// Initial creation of the array, no test on previous block ending line
- mBlockEndLines = new int[ArrayUtils.idealIntArraySize(1)];
+ mBlockEndLines = ArrayUtils.newUnpaddedIntArray(1);
mBlockEndLines[mNumberOfBlocks] = line;
mNumberOfBlocks++;
return;
@@ -409,13 +410,7 @@ public class DynamicLayout extends Layout
final int previousBlockEndLine = mBlockEndLines[mNumberOfBlocks - 1];
if (line > previousBlockEndLine) {
- if (mNumberOfBlocks == mBlockEndLines.length) {
- // Grow the array if needed
- int[] blockEndLines = new int[ArrayUtils.idealIntArraySize(mNumberOfBlocks + 1)];
- System.arraycopy(mBlockEndLines, 0, blockEndLines, 0, mNumberOfBlocks);
- mBlockEndLines = blockEndLines;
- }
- mBlockEndLines[mNumberOfBlocks] = line;
+ mBlockEndLines = GrowingArrayUtils.append(mBlockEndLines, mNumberOfBlocks, line);
mNumberOfBlocks++;
}
}
@@ -483,9 +478,9 @@ public class DynamicLayout extends Layout
}
if (newNumberOfBlocks > mBlockEndLines.length) {
- final int newSize = ArrayUtils.idealIntArraySize(newNumberOfBlocks);
- int[] blockEndLines = new int[newSize];
- int[] blockIndices = new int[newSize];
+ int[] blockEndLines = ArrayUtils.newUnpaddedIntArray(
+ Math.max(mBlockEndLines.length * 2, newNumberOfBlocks));
+ int[] blockIndices = new int[blockEndLines.length];
System.arraycopy(mBlockEndLines, 0, blockEndLines, 0, firstBlock);
System.arraycopy(mBlockIndices, 0, blockIndices, 0, firstBlock);
System.arraycopy(mBlockEndLines, lastBlock + 1,
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index c80321c..2fcc597 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -211,7 +211,7 @@ public class Html {
private static String getOpenParaTagWithDirection(Spanned text, int start, int end) {
final int len = end - start;
- final byte[] levels = new byte[ArrayUtils.idealByteArraySize(len)];
+ final byte[] levels = ArrayUtils.newUnpaddedByteArray(len);
final char[] buffer = TextUtils.obtain(len);
TextUtils.getChars(text, start, end, buffer, 0);
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 9dfd383..4bfcaff 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -31,6 +31,7 @@ import android.text.style.ReplacementSpan;
import android.text.style.TabStopSpan;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
import java.util.Arrays;
@@ -403,14 +404,9 @@ public abstract class Layout {
// construction
if (mLineBackgroundSpans.spanStarts[j] >= end ||
mLineBackgroundSpans.spanEnds[j] <= start) continue;
- if (spansLength == spans.length) {
- // The spans array needs to be expanded
- int newSize = ArrayUtils.idealObjectArraySize(2 * spansLength);
- ParagraphStyle[] newSpans = new ParagraphStyle[newSize];
- System.arraycopy(spans, 0, newSpans, 0, spansLength);
- spans = newSpans;
- }
- spans[spansLength++] = mLineBackgroundSpans.spans[j];
+ spans = GrowingArrayUtils.append(
+ spans, spansLength, mLineBackgroundSpans.spans[j]);
+ spansLength++;
}
}
}
diff --git a/core/java/android/text/MeasuredText.java b/core/java/android/text/MeasuredText.java
index 101d6a2..f8e3c83 100644
--- a/core/java/android/text/MeasuredText.java
+++ b/core/java/android/text/MeasuredText.java
@@ -98,10 +98,10 @@ class MeasuredText {
mPos = 0;
if (mWidths == null || mWidths.length < len) {
- mWidths = new float[ArrayUtils.idealFloatArraySize(len)];
+ mWidths = ArrayUtils.newUnpaddedFloatArray(len);
}
if (mChars == null || mChars.length < len) {
- mChars = new char[ArrayUtils.idealCharArraySize(len)];
+ mChars = ArrayUtils.newUnpaddedCharArray(len);
}
TextUtils.getChars(text, start, end, mChars, 0);
@@ -130,7 +130,7 @@ class MeasuredText {
mEasy = true;
} else {
if (mLevels == null || mLevels.length < len) {
- mLevels = new byte[ArrayUtils.idealByteArraySize(len)];
+ mLevels = ArrayUtils.newUnpaddedByteArray(len);
}
int bidiRequest;
if (textDir == TextDirectionHeuristics.LTR) {
diff --git a/core/java/android/text/PackedIntVector.java b/core/java/android/text/PackedIntVector.java
index d87f600..546ab44 100644
--- a/core/java/android/text/PackedIntVector.java
+++ b/core/java/android/text/PackedIntVector.java
@@ -17,6 +17,7 @@
package android.text;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
/**
@@ -252,9 +253,9 @@ class PackedIntVector {
*/
private final void growBuffer() {
final int columns = mColumns;
- int newsize = size() + 1;
- newsize = ArrayUtils.idealIntArraySize(newsize * columns) / columns;
- int[] newvalues = new int[newsize * columns];
+ int[] newvalues = ArrayUtils.newUnpaddedIntArray(
+ GrowingArrayUtils.growSize(size()) * columns);
+ int newsize = newvalues.length / columns;
final int[] valuegap = mValueGap;
final int rowgapstart = mRowGapStart;
diff --git a/core/java/android/text/PackedObjectVector.java b/core/java/android/text/PackedObjectVector.java
index a29df09..b777e16 100644
--- a/core/java/android/text/PackedObjectVector.java
+++ b/core/java/android/text/PackedObjectVector.java
@@ -17,6 +17,9 @@
package android.text;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
class PackedObjectVector<E>
{
@@ -32,12 +35,11 @@ class PackedObjectVector<E>
PackedObjectVector(int columns)
{
mColumns = columns;
- mRows = ArrayUtils.idealIntArraySize(0) / mColumns;
+ mValues = EmptyArray.OBJECT;
+ mRows = 0;
mRowGapStart = 0;
mRowGapLength = mRows;
-
- mValues = new Object[mRows * mColumns];
}
public E
@@ -109,10 +111,9 @@ class PackedObjectVector<E>
private void
growBuffer()
{
- int newsize = size() + 1;
- newsize = ArrayUtils.idealIntArraySize(newsize * mColumns) / mColumns;
- Object[] newvalues = new Object[newsize * mColumns];
-
+ Object[] newvalues = ArrayUtils.newUnpaddedObjectArray(
+ GrowingArrayUtils.growSize(size()) * mColumns);
+ int newsize = newvalues.length / mColumns;
int after = mRows - (mRowGapStart + mRowGapLength);
System.arraycopy(mValues, 0, newvalues, 0, mColumns * mRowGapStart);
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index b55cd6a..f440853 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -21,6 +21,9 @@ import android.graphics.Paint;
import android.util.Log;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
import java.lang.reflect.Array;
@@ -54,19 +57,17 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
if (srclen < 0) throw new StringIndexOutOfBoundsException();
- int len = ArrayUtils.idealCharArraySize(srclen + 1);
- mText = new char[len];
+ mText = ArrayUtils.newUnpaddedCharArray(GrowingArrayUtils.growSize(srclen));
mGapStart = srclen;
- mGapLength = len - srclen;
+ mGapLength = mText.length - srclen;
TextUtils.getChars(text, start, end, mText, 0);
mSpanCount = 0;
- int alloc = ArrayUtils.idealIntArraySize(0);
- mSpans = new Object[alloc];
- mSpanStarts = new int[alloc];
- mSpanEnds = new int[alloc];
- mSpanFlags = new int[alloc];
+ mSpans = EmptyArray.OBJECT;
+ mSpanStarts = EmptyArray.INT;
+ mSpanEnds = EmptyArray.INT;
+ mSpanFlags = EmptyArray.INT;
if (text instanceof Spanned) {
Spanned sp = (Spanned) text;
@@ -130,12 +131,14 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
private void resizeFor(int size) {
final int oldLength = mText.length;
- final int newLength = ArrayUtils.idealCharArraySize(size + 1);
- final int delta = newLength - oldLength;
- if (delta == 0) return;
+ if (size + 1 <= oldLength) {
+ return;
+ }
- char[] newText = new char[newLength];
+ char[] newText = ArrayUtils.newUnpaddedCharArray(GrowingArrayUtils.growSize(size));
System.arraycopy(mText, 0, newText, 0, mGapStart);
+ final int newLength = newText.length;
+ final int delta = newLength - oldLength;
final int after = oldLength - (mGapStart + mGapLength);
System.arraycopy(mText, oldLength - after, newText, newLength - after, after);
mText = newText;
@@ -679,28 +682,10 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
}
}
- if (mSpanCount + 1 >= mSpans.length) {
- int newsize = ArrayUtils.idealIntArraySize(mSpanCount + 1);
- Object[] newspans = new Object[newsize];
- int[] newspanstarts = new int[newsize];
- int[] newspanends = new int[newsize];
- int[] newspanflags = new int[newsize];
-
- System.arraycopy(mSpans, 0, newspans, 0, mSpanCount);
- System.arraycopy(mSpanStarts, 0, newspanstarts, 0, mSpanCount);
- System.arraycopy(mSpanEnds, 0, newspanends, 0, mSpanCount);
- System.arraycopy(mSpanFlags, 0, newspanflags, 0, mSpanCount);
-
- mSpans = newspans;
- mSpanStarts = newspanstarts;
- mSpanEnds = newspanends;
- mSpanFlags = newspanflags;
- }
-
- mSpans[mSpanCount] = what;
- mSpanStarts[mSpanCount] = start;
- mSpanEnds[mSpanCount] = end;
- mSpanFlags[mSpanCount] = flags;
+ mSpans = GrowingArrayUtils.append(mSpans, mSpanCount, what);
+ mSpanStarts = GrowingArrayUtils.append(mSpanStarts, mSpanCount, start);
+ mSpanEnds = GrowingArrayUtils.append(mSpanEnds, mSpanCount, end);
+ mSpanFlags = GrowingArrayUtils.append(mSpanFlags, mSpanCount, flags);
mSpanCount++;
if (send) sendSpanAdded(what, nstart, nend);
diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java
index 456a3e5..d114d32 100644
--- a/core/java/android/text/SpannableStringInternal.java
+++ b/core/java/android/text/SpannableStringInternal.java
@@ -17,6 +17,9 @@
package android.text;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
import java.lang.reflect.Array;
@@ -29,9 +32,8 @@ import java.lang.reflect.Array;
else
mText = source.toString().substring(start, end);
- int initial = ArrayUtils.idealIntArraySize(0);
- mSpans = new Object[initial];
- mSpanData = new int[initial * 3];
+ mSpans = EmptyArray.OBJECT;
+ mSpanData = EmptyArray.INT;
if (source instanceof Spanned) {
Spanned sp = (Spanned) source;
@@ -115,9 +117,9 @@ import java.lang.reflect.Array;
}
if (mSpanCount + 1 >= mSpans.length) {
- int newsize = ArrayUtils.idealIntArraySize(mSpanCount + 1);
- Object[] newtags = new Object[newsize];
- int[] newdata = new int[newsize * 3];
+ Object[] newtags = ArrayUtils.newUnpaddedObjectArray(
+ GrowingArrayUtils.growSize(mSpanCount));
+ int[] newdata = new int[newtags.length * 3];
System.arraycopy(mSpans, 0, newtags, 0, mSpanCount);
System.arraycopy(mSpanData, 0, newdata, 0, mSpanCount * 3);
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index e7d6fda..535eee1 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -26,6 +26,7 @@ import android.text.style.TabStopSpan;
import android.util.Log;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
/**
* StaticLayout is a Layout for text that will not be edited after it
@@ -130,9 +131,8 @@ public class StaticLayout extends Layout {
mEllipsizedWidth = outerwidth;
}
- mLines = new int[ArrayUtils.idealIntArraySize(2 * mColumns)];
- mLineDirections = new Directions[
- ArrayUtils.idealIntArraySize(2 * mColumns)];
+ mLineDirections = ArrayUtils.newUnpaddedArray(Directions.class, 2 * mColumns);
+ mLines = new int[mLineDirections.length];
mMaximumVisibleLineCount = maxLines;
mMeasured = MeasuredText.obtain();
@@ -149,8 +149,8 @@ public class StaticLayout extends Layout {
super(text, null, 0, null, 0, 0);
mColumns = COLUMNS_ELLIPSIZE;
- mLines = new int[ArrayUtils.idealIntArraySize(2 * mColumns)];
- mLineDirections = new Directions[ArrayUtils.idealIntArraySize(2 * mColumns)];
+ mLineDirections = ArrayUtils.newUnpaddedArray(Directions.class, 2 * mColumns);
+ mLines = new int[mLineDirections.length];
// FIXME This is never recycled
mMeasured = MeasuredText.obtain();
}
@@ -215,8 +215,7 @@ public class StaticLayout extends Layout {
if (chooseHt.length != 0) {
if (chooseHtv == null ||
chooseHtv.length < chooseHt.length) {
- chooseHtv = new int[ArrayUtils.idealIntArraySize(
- chooseHt.length)];
+ chooseHtv = ArrayUtils.newUnpaddedIntArray(chooseHt.length);
}
for (int i = 0; i < chooseHt.length; i++) {
@@ -599,16 +598,16 @@ public class StaticLayout extends Layout {
int[] lines = mLines;
if (want >= lines.length) {
- int nlen = ArrayUtils.idealIntArraySize(want + 1);
- int[] grow = new int[nlen];
- System.arraycopy(lines, 0, grow, 0, lines.length);
- mLines = grow;
- lines = grow;
-
- Directions[] grow2 = new Directions[nlen];
+ Directions[] grow2 = ArrayUtils.newUnpaddedArray(
+ Directions.class, GrowingArrayUtils.growSize(want));
System.arraycopy(mLineDirections, 0, grow2, 0,
mLineDirections.length);
mLineDirections = grow2;
+
+ int[] grow = new int[grow2.length];
+ System.arraycopy(lines, 0, grow, 0, lines.length);
+ mLines = grow;
+ lines = grow;
}
if (chooseHt != null) {
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 1fecf81..d892f19 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -153,7 +153,7 @@ class TextLine {
if (mCharsValid) {
if (mChars == null || mChars.length < mLen) {
- mChars = new char[ArrayUtils.idealCharArraySize(mLen)];
+ mChars = ArrayUtils.newUnpaddedCharArray(mLen);
}
TextUtils.getChars(text, start, limit, mChars, 0);
if (hasReplacement) {
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 596ca8c..f06ae71 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -1321,7 +1321,7 @@ public class TextUtils {
}
if (buf == null || buf.length < len)
- buf = new char[ArrayUtils.idealCharArraySize(len)];
+ buf = ArrayUtils.newUnpaddedCharArray(len);
return buf;
}
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index df1d4cd..9a0b7fc 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -16,6 +16,8 @@
package android.util;
+import libcore.util.EmptyArray;
+
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@@ -234,8 +236,8 @@ public final class ArrayMap<K, V> implements Map<K, V> {
* will grow once items are added to it.
*/
public ArrayMap() {
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
mSize = 0;
}
@@ -244,8 +246,8 @@ public final class ArrayMap<K, V> implements Map<K, V> {
*/
public ArrayMap(int capacity) {
if (capacity == 0) {
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
} else {
allocArrays(capacity);
}
@@ -253,8 +255,8 @@ public final class ArrayMap<K, V> implements Map<K, V> {
}
private ArrayMap(boolean immutable) {
- mHashes = EMPTY_IMMUTABLE_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
mSize = 0;
}
@@ -275,8 +277,8 @@ public final class ArrayMap<K, V> implements Map<K, V> {
public void clear() {
if (mSize > 0) {
freeArrays(mHashes, mArray, mSize);
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
mSize = 0;
}
}
@@ -540,8 +542,8 @@ public final class ArrayMap<K, V> implements Map<K, V> {
// Now empty.
if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to 0");
freeArrays(mHashes, mArray, mSize);
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
mSize = 0;
} else {
if (mHashes.length > (BASE_SIZE*2) && mSize < mHashes.length/3) {
diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java
index 3c695e9..9d4b720 100644
--- a/core/java/android/util/ArraySet.java
+++ b/core/java/android/util/ArraySet.java
@@ -16,6 +16,8 @@
package android.util;
+import libcore.util.EmptyArray;
+
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
@@ -222,8 +224,8 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
* will grow once items are added to it.
*/
public ArraySet() {
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
mSize = 0;
}
@@ -232,8 +234,8 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
*/
public ArraySet(int capacity) {
if (capacity == 0) {
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
} else {
allocArrays(capacity);
}
@@ -258,8 +260,8 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
public void clear() {
if (mSize != 0) {
freeArrays(mHashes, mArray, mSize);
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
mSize = 0;
}
}
@@ -413,8 +415,8 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
// Now empty.
if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to 0");
freeArrays(mHashes, mArray, mSize);
- mHashes = ContainerHelpers.EMPTY_INTS;
- mArray = ContainerHelpers.EMPTY_OBJECTS;
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
mSize = 0;
} else {
if (mHashes.length > (BASE_SIZE*2) && mSize < mHashes.length/3) {
diff --git a/core/java/android/util/ContainerHelpers.java b/core/java/android/util/ContainerHelpers.java
index 624c4bd..4e5fefb 100644
--- a/core/java/android/util/ContainerHelpers.java
+++ b/core/java/android/util/ContainerHelpers.java
@@ -17,10 +17,6 @@
package android.util;
class ContainerHelpers {
- static final boolean[] EMPTY_BOOLEANS = new boolean[0];
- static final int[] EMPTY_INTS = new int[0];
- static final long[] EMPTY_LONGS = new long[0];
- static final Object[] EMPTY_OBJECTS = new Object[0];
// This is Arrays.binarySearch(), but doesn't do any argument validation.
static int binarySearch(int[] array, int size, int value) {
diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java
index d5f15f0..54a6882 100644
--- a/core/java/android/util/LongArray.java
+++ b/core/java/android/util/LongArray.java
@@ -17,6 +17,7 @@
package android.util;
import com.android.internal.util.ArrayUtils;
+import libcore.util.EmptyArray;
/**
* Implements a growing array of long primitives.
@@ -41,10 +42,9 @@ public class LongArray implements Cloneable {
*/
public LongArray(int initialCapacity) {
if (initialCapacity == 0) {
- mValues = ContainerHelpers.EMPTY_LONGS;
+ mValues = EmptyArray.LONG;
} else {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
- mValues = new long[initialCapacity];
+ mValues = ArrayUtils.newUnpaddedLongArray(initialCapacity);
}
mSize = 0;
}
@@ -97,7 +97,7 @@ public class LongArray implements Cloneable {
final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : currentSize >> 1);
final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
- final long[] newValues = new long[ArrayUtils.idealLongArraySize(newCapacity)];
+ final long[] newValues = ArrayUtils.newUnpaddedLongArray(newCapacity);
System.arraycopy(mValues, 0, newValues, 0, currentSize);
mValues = newValues;
}
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index dab853a..6b45ff4 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -17,6 +17,9 @@
package android.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
/**
* SparseArray mapping longs to Objects. Unlike a normal array of Objects,
@@ -70,12 +73,11 @@ public class LongSparseArray<E> implements Cloneable {
*/
public LongSparseArray(int initialCapacity) {
if (initialCapacity == 0) {
- mKeys = ContainerHelpers.EMPTY_LONGS;
- mValues = ContainerHelpers.EMPTY_OBJECTS;
+ mKeys = EmptyArray.LONG;
+ mValues = EmptyArray.OBJECT;
} else {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
- mKeys = new long[initialCapacity];
- mValues = new Object[initialCapacity];
+ mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
+ mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
}
mSize = 0;
}
@@ -202,28 +204,8 @@ public class LongSparseArray<E> implements Cloneable {
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
}
- if (mSize >= mKeys.length) {
- int n = ArrayUtils.idealLongArraySize(mSize + 1);
-
- long[] nkeys = new long[n];
- Object[] nvalues = new Object[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- if (mSize - i != 0) {
- // Log.e("SparseArray", "move " + (mSize - i));
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = value;
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
@@ -353,24 +335,9 @@ public class LongSparseArray<E> implements Cloneable {
gc();
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- int n = ArrayUtils.idealLongArraySize(pos + 1);
-
- long[] nkeys = new long[n];
- Object[] nvalues = new Object[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- mKeys[pos] = key;
- mValues[pos] = value;
- mSize = pos + 1;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, value);
+ mSize++;
}
/**
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index b8073dd..a361457 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -17,6 +17,9 @@
package android.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
/**
* Map of {@code long} to {@code long}. Unlike a normal array of longs, there
@@ -62,12 +65,11 @@ public class LongSparseLongArray implements Cloneable {
*/
public LongSparseLongArray(int initialCapacity) {
if (initialCapacity == 0) {
- mKeys = ContainerHelpers.EMPTY_LONGS;
- mValues = ContainerHelpers.EMPTY_LONGS;
+ mKeys = EmptyArray.LONG;
+ mValues = EmptyArray.LONG;
} else {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
- mKeys = new long[initialCapacity];
- mValues = new long[initialCapacity];
+ mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
+ mValues = new long[mKeys.length];
}
mSize = 0;
}
@@ -140,17 +142,8 @@ public class LongSparseLongArray implements Cloneable {
} else {
i = ~i;
- if (mSize >= mKeys.length) {
- growKeyAndValueArrays(mSize + 1);
- }
-
- if (mSize - i != 0) {
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = value;
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
@@ -234,27 +227,9 @@ public class LongSparseLongArray implements Cloneable {
return;
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- growKeyAndValueArrays(pos + 1);
- }
-
- mKeys[pos] = key;
- mValues[pos] = value;
- mSize = pos + 1;
- }
-
- private void growKeyAndValueArrays(int minNeededSize) {
- int n = ArrayUtils.idealLongArraySize(minNeededSize);
-
- long[] nkeys = new long[n];
- long[] nvalues = new long[n];
-
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, value);
+ mSize++;
}
/**
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 46d9d45..92e874f 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -17,6 +17,9 @@
package android.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
/**
* SparseArrays map integers to Objects. Unlike a normal array of Objects,
@@ -70,12 +73,11 @@ public class SparseArray<E> implements Cloneable {
*/
public SparseArray(int initialCapacity) {
if (initialCapacity == 0) {
- mKeys = ContainerHelpers.EMPTY_INTS;
- mValues = ContainerHelpers.EMPTY_OBJECTS;
+ mKeys = EmptyArray.INT;
+ mValues = EmptyArray.OBJECT;
} else {
- initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
- mKeys = new int[initialCapacity];
- mValues = new Object[initialCapacity];
+ mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
+ mKeys = new int[mValues.length];
}
mSize = 0;
}
@@ -215,28 +217,8 @@ public class SparseArray<E> implements Cloneable {
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
}
- if (mSize >= mKeys.length) {
- int n = ArrayUtils.idealIntArraySize(mSize + 1);
-
- int[] nkeys = new int[n];
- Object[] nvalues = new Object[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- if (mSize - i != 0) {
- // Log.e("SparseArray", "move " + (mSize - i));
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = value;
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
@@ -368,24 +350,9 @@ public class SparseArray<E> implements Cloneable {
gc();
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- int n = ArrayUtils.idealIntArraySize(pos + 1);
-
- int[] nkeys = new int[n];
- Object[] nvalues = new Object[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- mKeys[pos] = key;
- mValues[pos] = value;
- mSize = pos + 1;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, value);
+ mSize++;
}
/**
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index f59ef0f6d..e293b1f 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -17,6 +17,9 @@
package android.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
/**
* SparseBooleanArrays map integers to booleans.
@@ -57,12 +60,11 @@ public class SparseBooleanArray implements Cloneable {
*/
public SparseBooleanArray(int initialCapacity) {
if (initialCapacity == 0) {
- mKeys = ContainerHelpers.EMPTY_INTS;
- mValues = ContainerHelpers.EMPTY_BOOLEANS;
+ mKeys = EmptyArray.INT;
+ mValues = EmptyArray.BOOLEAN;
} else {
- initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
- mKeys = new int[initialCapacity];
- mValues = new boolean[initialCapacity];
+ mKeys = ArrayUtils.newUnpaddedIntArray(initialCapacity);
+ mValues = new boolean[mKeys.length];
}
mSize = 0;
}
@@ -135,28 +137,8 @@ public class SparseBooleanArray implements Cloneable {
} else {
i = ~i;
- if (mSize >= mKeys.length) {
- int n = ArrayUtils.idealIntArraySize(mSize + 1);
-
- int[] nkeys = new int[n];
- boolean[] nvalues = new boolean[n];
-
- // Log.e("SparseBooleanArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- if (mSize - i != 0) {
- // Log.e("SparseBooleanArray", "move " + (mSize - i));
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = value;
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
@@ -245,24 +227,9 @@ public class SparseBooleanArray implements Cloneable {
return;
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- int n = ArrayUtils.idealIntArraySize(pos + 1);
-
- int[] nkeys = new int[n];
- boolean[] nvalues = new boolean[n];
-
- // Log.e("SparseBooleanArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- mKeys[pos] = key;
- mValues[pos] = value;
- mSize = pos + 1;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, value);
+ mSize++;
}
/**
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 4f5ca07..2b85a21 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -17,6 +17,9 @@
package android.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
/**
* SparseIntArrays map integers to integers. Unlike a normal array of integers,
@@ -60,12 +63,11 @@ public class SparseIntArray implements Cloneable {
*/
public SparseIntArray(int initialCapacity) {
if (initialCapacity == 0) {
- mKeys = ContainerHelpers.EMPTY_INTS;
- mValues = ContainerHelpers.EMPTY_INTS;
+ mKeys = EmptyArray.INT;
+ mValues = EmptyArray.INT;
} else {
- initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
- mKeys = new int[initialCapacity];
- mValues = new int[initialCapacity];
+ mKeys = ArrayUtils.newUnpaddedIntArray(initialCapacity);
+ mValues = new int[mKeys.length];
}
mSize = 0;
}
@@ -138,28 +140,8 @@ public class SparseIntArray implements Cloneable {
} else {
i = ~i;
- if (mSize >= mKeys.length) {
- int n = ArrayUtils.idealIntArraySize(mSize + 1);
-
- int[] nkeys = new int[n];
- int[] nvalues = new int[n];
-
- // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- if (mSize - i != 0) {
- // Log.e("SparseIntArray", "move " + (mSize - i));
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = value;
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
@@ -243,24 +225,9 @@ public class SparseIntArray implements Cloneable {
return;
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- int n = ArrayUtils.idealIntArraySize(pos + 1);
-
- int[] nkeys = new int[n];
- int[] nvalues = new int[n];
-
- // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- mKeys[pos] = key;
- mValues[pos] = value;
- mSize = pos + 1;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, value);
+ mSize++;
}
/**
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 39fc8a3..0166c4a 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -17,6 +17,9 @@
package android.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
+
+import libcore.util.EmptyArray;
/**
* SparseLongArrays map integers to longs. Unlike a normal array of longs,
@@ -60,12 +63,11 @@ public class SparseLongArray implements Cloneable {
*/
public SparseLongArray(int initialCapacity) {
if (initialCapacity == 0) {
- mKeys = ContainerHelpers.EMPTY_INTS;
- mValues = ContainerHelpers.EMPTY_LONGS;
+ mKeys = EmptyArray.INT;
+ mValues = EmptyArray.LONG;
} else {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
- mKeys = new int[initialCapacity];
- mValues = new long[initialCapacity];
+ mValues = ArrayUtils.newUnpaddedLongArray(initialCapacity);
+ mKeys = new int[mValues.length];
}
mSize = 0;
}
@@ -138,17 +140,8 @@ public class SparseLongArray implements Cloneable {
} else {
i = ~i;
- if (mSize >= mKeys.length) {
- growKeyAndValueArrays(mSize + 1);
- }
-
- if (mSize - i != 0) {
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = value;
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
@@ -232,27 +225,9 @@ public class SparseLongArray implements Cloneable {
return;
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- growKeyAndValueArrays(pos + 1);
- }
-
- mKeys[pos] = key;
- mValues[pos] = value;
- mSize = pos + 1;
- }
-
- private void growKeyAndValueArrays(int minNeededSize) {
- int n = ArrayUtils.idealLongArraySize(minNeededSize);
-
- int[] nkeys = new int[n];
- long[] nvalues = new long[n];
-
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, value);
+ mSize++;
}
/**
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 60fb7ac..6c8c3c7 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -361,6 +361,14 @@ public class RenderNode {
}
/**
+ * Controls the RenderNode's circular reveal clip.
+ */
+ public void setRevealClip(boolean shouldClip, boolean inverseClip,
+ float x, float y, float radius) {
+ nSetRevealClip(mNativeDisplayList, shouldClip, inverseClip, x, y, radius);
+ }
+
+ /**
* Set the static matrix on the display list. The specified matrix is combined with other
* transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
*
@@ -856,6 +864,8 @@ public class RenderNode {
private static native void nSetOutlineConvexPath(long displayList, long nativePath);
private static native void nSetOutlineEmpty(long displayList);
private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
+ private static native void nSetRevealClip(long displayList,
+ boolean shouldClip, boolean inverseClip, float x, float y, float radius);
private static native void nSetAlpha(long displayList, float alpha);
private static native void nSetHasOverlappingRendering(long displayList,
boolean hasOverlappingRendering);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6ee99ec..f2b9b96 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -33,7 +33,6 @@ import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
-import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
@@ -10884,6 +10883,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Private API to be used for reveal animation
+ *
+ * @hide
+ */
+ public void setRevealClip(boolean shouldClip, boolean inverseClip,
+ float x, float y, float radius) {
+ if (mDisplayList != null) {
+ mDisplayList.setRevealClip(shouldClip, inverseClip, x, y, radius);
+ }
+ }
+
+ /**
* Hit rectangle in parent's coordinates
*
* @param outRect The hit rectangle of the view.
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 333e631..14e7951 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -25,6 +25,7 @@ import android.text.InputFilter;
import android.text.SpannableString;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
import com.android.internal.widget.EditableInputConnection;
import android.R;
@@ -1341,7 +1342,7 @@ public class Editor {
if (layout instanceof DynamicLayout) {
if (mTextDisplayLists == null) {
- mTextDisplayLists = new TextDisplayList[ArrayUtils.idealObjectArraySize(0)];
+ mTextDisplayLists = ArrayUtils.emptyArray(TextDisplayList.class);
}
DynamicLayout dynamicLayout = (DynamicLayout) layout;
@@ -1441,10 +1442,7 @@ public class Editor {
}
// No available index found, the pool has to grow
- int newSize = ArrayUtils.idealIntArraySize(length + 1);
- TextDisplayList[] displayLists = new TextDisplayList[newSize];
- System.arraycopy(mTextDisplayLists, 0, displayLists, 0, length);
- mTextDisplayLists = displayLists;
+ mTextDisplayLists = GrowingArrayUtils.append(mTextDisplayLists, length, null);
return length;
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 0d3df51..f7d20b53 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1516,6 +1516,75 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Helper action to set a color filter on a compound drawable on a TextView. Supports relative
+ * (s/t/e/b) or cardinal (l/t/r/b) arrangement.
+ */
+ private class TextViewDrawableColorFilterAction extends Action {
+ public TextViewDrawableColorFilterAction(int viewId, boolean isRelative, int index,
+ int color, PorterDuff.Mode mode) {
+ this.viewId = viewId;
+ this.isRelative = isRelative;
+ this.index = index;
+ this.color = color;
+ this.mode = mode;
+ }
+
+ public TextViewDrawableColorFilterAction(Parcel parcel) {
+ viewId = parcel.readInt();
+ isRelative = (parcel.readInt() != 0);
+ index = parcel.readInt();
+ color = parcel.readInt();
+ mode = readPorterDuffMode(parcel);
+ }
+
+ private PorterDuff.Mode readPorterDuffMode(Parcel parcel) {
+ int mode = parcel.readInt();
+ if (mode >= 0 && mode < PorterDuff.Mode.values().length) {
+ return PorterDuff.Mode.values()[mode];
+ } else {
+ return PorterDuff.Mode.CLEAR;
+ }
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(TAG);
+ dest.writeInt(viewId);
+ dest.writeInt(isRelative ? 1 : 0);
+ dest.writeInt(index);
+ dest.writeInt(color);
+ dest.writeInt(mode.ordinal());
+ }
+
+ @Override
+ public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
+ final TextView target = (TextView) root.findViewById(viewId);
+ if (target == null) return;
+ Drawable[] drawables = isRelative
+ ? target.getCompoundDrawablesRelative()
+ : target.getCompoundDrawables();
+ if (index < 0 || index >= 4) {
+ throw new IllegalStateException("index must be in range [0, 3].");
+ }
+ Drawable d = drawables[index];
+ if (d != null) {
+ d.mutate();
+ d.setColorFilter(color, mode);
+ }
+ }
+
+ public String getActionName() {
+ return "TextViewDrawableColorFilterAction";
+ }
+
+ final boolean isRelative;
+ final int index;
+ final int color;
+ final PorterDuff.Mode mode;
+
+ public final static int TAG = 17;
+ }
+
+ /**
* Simple class used to keep track of memory usage in a RemoteViews.
*
*/
@@ -1686,6 +1755,9 @@ public class RemoteViews implements Parcelable, Filter {
case SetRemoteViewsAdapterList.TAG:
mActions.add(new SetRemoteViewsAdapterList(parcel));
break;
+ case TextViewDrawableColorFilterAction.TAG:
+ mActions.add(new TextViewDrawableColorFilterAction(parcel));
+ break;
default:
throw new ActionException("Tag " + tag + " not found");
}
@@ -1921,6 +1993,28 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Equivalent to applying a color filter on one of the drawables in
+ * {@link android.widget.TextView#getCompoundDrawablesRelative()}.
+ *
+ * @param viewId The id of the view whose text should change.
+ * @param index The index of the drawable in the array of
+ * {@link android.widget.TextView#getCompoundDrawablesRelative()} to set the color
+ * filter on. Must be in [0, 3].
+ * @param color The color of the color filter. See
+ * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)}.
+ * @param mode The mode of the color filter. See
+ * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)}.
+ * @hide
+ */
+ public void setTextViewCompoundDrawablesRelativeColorFilter(int viewId,
+ int index, int color, PorterDuff.Mode mode) {
+ if (index < 0 || index >= 4) {
+ throw new IllegalArgumentException("index must be in range [0, 3].");
+ }
+ addAction(new TextViewDrawableColorFilterAction(viewId, true, index, color, mode));
+ }
+
+ /**
* Equivalent to calling ImageView.setImageResource
*
* @param viewId The id of the view whose drawable should change
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 1cda631..595f023 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -35,6 +35,7 @@ import android.view.textservice.TextInfo;
import android.view.textservice.TextServicesManager;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
import java.text.BreakIterator;
import java.util.Locale;
@@ -105,9 +106,9 @@ public class SpellChecker implements SpellCheckerSessionListener {
mTextView = textView;
// Arbitrary: these arrays will automatically double their sizes on demand
- final int size = ArrayUtils.idealObjectArraySize(1);
- mIds = new int[size];
- mSpellCheckSpans = new SpellCheckSpan[size];
+ final int size = 1;
+ mIds = ArrayUtils.newUnpaddedIntArray(size);
+ mSpellCheckSpans = new SpellCheckSpan[mIds.length];
setLocale(mTextView.getSpellCheckerLocale());
@@ -184,17 +185,9 @@ public class SpellChecker implements SpellCheckerSessionListener {
if (mIds[i] < 0) return i;
}
- if (mLength == mSpellCheckSpans.length) {
- final int newSize = mLength * 2;
- int[] newIds = new int[newSize];
- SpellCheckSpan[] newSpellCheckSpans = new SpellCheckSpan[newSize];
- System.arraycopy(mIds, 0, newIds, 0, mLength);
- System.arraycopy(mSpellCheckSpans, 0, newSpellCheckSpans, 0, mLength);
- mIds = newIds;
- mSpellCheckSpans = newSpellCheckSpans;
- }
-
- mSpellCheckSpans[mLength] = new SpellCheckSpan();
+ mIds = GrowingArrayUtils.append(mIds, mLength, 0);
+ mSpellCheckSpans = GrowingArrayUtils.append(
+ mSpellCheckSpans, mLength, new SpellCheckSpan());
mLength++;
return mLength - 1;
}
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index b1535e3..882bec9 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -29,8 +29,11 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
import android.webkit.WebViewFactory;
-import com.android.internal.util.ArrayUtils;
+
+import com.android.internal.util.GrowingArrayUtils;
+
import dalvik.system.VMRuntime;
+import libcore.util.EmptyArray;
import java.io.IOException;
import java.io.InputStream;
@@ -1621,21 +1624,10 @@ public final class ProcessStats implements Parcelable {
}
int addLongData(int index, int type, int num) {
- int tableLen = mAddLongTable != null ? mAddLongTable.length : 0;
- if (mAddLongTableSize >= tableLen) {
- int newSize = ArrayUtils.idealIntArraySize(tableLen + 1);
- int[] newTable = new int[newSize];
- if (tableLen > 0) {
- System.arraycopy(mAddLongTable, 0, newTable, 0, tableLen);
- }
- mAddLongTable = newTable;
- }
- if (mAddLongTableSize > 0 && mAddLongTableSize - index != 0) {
- System.arraycopy(mAddLongTable, index, mAddLongTable, index + 1,
- mAddLongTableSize - index);
- }
int off = allocLongData(num);
- mAddLongTable[index] = type | off;
+ mAddLongTable = GrowingArrayUtils.insert(
+ mAddLongTable != null ? mAddLongTable : EmptyArray.INT,
+ mAddLongTableSize, index, type | off);
mAddLongTableSize++;
return off;
}
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 9137d3c..d177410 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -16,11 +16,10 @@
package com.android.internal.util;
-import java.lang.reflect.Array;
+import dalvik.system.VMRuntime;
+import libcore.util.EmptyArray;
-// XXX these should be changed to reflect the actual memory allocator we use.
-// it looks like right now objects want to be powers of 2 minus 8
-// and the array size eats another 4 bytes
+import java.lang.reflect.Array;
/**
* ArrayUtils contains some methods that you can call to find out
@@ -28,46 +27,42 @@ import java.lang.reflect.Array;
*/
public class ArrayUtils
{
- private static Object[] EMPTY = new Object[0];
private static final int CACHE_SIZE = 73;
private static Object[] sCache = new Object[CACHE_SIZE];
private ArrayUtils() { /* cannot be instantiated */ }
- public static int idealByteArraySize(int need) {
- for (int i = 4; i < 32; i++)
- if (need <= (1 << i) - 12)
- return (1 << i) - 12;
-
- return need;
+ public static byte[] newUnpaddedByteArray(int minLen) {
+ return (byte[])VMRuntime.getRuntime().newUnpaddedArray(byte.class, minLen);
}
- public static int idealBooleanArraySize(int need) {
- return idealByteArraySize(need);
+ public static char[] newUnpaddedCharArray(int minLen) {
+ return (char[])VMRuntime.getRuntime().newUnpaddedArray(char.class, minLen);
}
- public static int idealShortArraySize(int need) {
- return idealByteArraySize(need * 2) / 2;
+ public static int[] newUnpaddedIntArray(int minLen) {
+ return (int[])VMRuntime.getRuntime().newUnpaddedArray(int.class, minLen);
}
- public static int idealCharArraySize(int need) {
- return idealByteArraySize(need * 2) / 2;
+ public static boolean[] newUnpaddedBooleanArray(int minLen) {
+ return (boolean[])VMRuntime.getRuntime().newUnpaddedArray(boolean.class, minLen);
}
- public static int idealIntArraySize(int need) {
- return idealByteArraySize(need * 4) / 4;
+ public static long[] newUnpaddedLongArray(int minLen) {
+ return (long[])VMRuntime.getRuntime().newUnpaddedArray(long.class, minLen);
}
- public static int idealFloatArraySize(int need) {
- return idealByteArraySize(need * 4) / 4;
+ public static float[] newUnpaddedFloatArray(int minLen) {
+ return (float[])VMRuntime.getRuntime().newUnpaddedArray(float.class, minLen);
}
- public static int idealObjectArraySize(int need) {
- return idealByteArraySize(need * 4) / 4;
+ public static Object[] newUnpaddedObjectArray(int minLen) {
+ return (Object[])VMRuntime.getRuntime().newUnpaddedArray(Object.class, minLen);
}
- public static int idealLongArraySize(int need) {
- return idealByteArraySize(need * 8) / 8;
+ @SuppressWarnings("unchecked")
+ public static <T> T[] newUnpaddedArray(Class<T> clazz, int minLen) {
+ return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen);
}
/**
@@ -102,9 +97,10 @@ public class ArrayUtils
* it will return the same empty array every time to avoid reallocation,
* although this is not guaranteed.
*/
+ @SuppressWarnings("unchecked")
public static <T> T[] emptyArray(Class<T> kind) {
if (kind == Object.class) {
- return (T[]) EMPTY;
+ return (T[]) EmptyArray.OBJECT;
}
int bucket = ((System.identityHashCode(kind) / 8) & 0x7FFFFFFF) % CACHE_SIZE;
diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java
new file mode 100644
index 0000000..b4d2d730
--- /dev/null
+++ b/core/java/com/android/internal/util/GrowingArrayUtils.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+/**
+ * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive
+ * arrays. Common array operations are implemented for efficient use in dynamic containers.
+ *
+ * All methods in this class assume that the length of an array is equivalent to its capacity and
+ * NOT the number of elements in the array. The current size of the array is always passed in as a
+ * parameter.
+ *
+ * @hide
+ */
+public final class GrowingArrayUtils {
+
+ /**
+ * Appends an element to the end of the array, growing the array if there is no more room.
+ * @param array The array to which to append the element. This must NOT be null.
+ * @param currentSize The number of elements in the array. Must be less than or equal to
+ * array.length.
+ * @param element The element to append.
+ * @return the array to which the element was appended. This may be different than the given
+ * array.
+ */
+ public static <T> T[] append(T[] array, int currentSize, T element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 > array.length) {
+ @SuppressWarnings("unchecked")
+ T[] newArray = ArrayUtils.newUnpaddedArray(
+ (Class<T>) array.getClass().getComponentType(), growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, currentSize);
+ array = newArray;
+ }
+ array[currentSize] = element;
+ return array;
+ }
+
+ /**
+ * Primitive int version of {@link #append(Object[], int, Object)}.
+ */
+ public static int[] append(int[] array, int currentSize, int element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 > array.length) {
+ int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, currentSize);
+ array = newArray;
+ }
+ array[currentSize] = element;
+ return array;
+ }
+
+ /**
+ * Primitive long version of {@link #append(Object[], int, Object)}.
+ */
+ public static long[] append(long[] array, int currentSize, long element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 > array.length) {
+ long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, currentSize);
+ array = newArray;
+ }
+ array[currentSize] = element;
+ return array;
+ }
+
+ /**
+ * Primitive boolean version of {@link #append(Object[], int, Object)}.
+ */
+ public static boolean[] append(boolean[] array, int currentSize, boolean element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 > array.length) {
+ boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, currentSize);
+ array = newArray;
+ }
+ array[currentSize] = element;
+ return array;
+ }
+
+ /**
+ * Inserts an element into the array at the specified index, growing the array if there is no
+ * more room.
+ *
+ * @param array The array to which to append the element. Must NOT be null.
+ * @param currentSize The number of elements in the array. Must be less than or equal to
+ * array.length.
+ * @param element The element to insert.
+ * @return the array to which the element was appended. This may be different than the given
+ * array.
+ */
+ public static <T> T[] insert(T[] array, int currentSize, int index, T element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 <= array.length) {
+ System.arraycopy(array, index, array, index + 1, currentSize - index);
+ array[index] = element;
+ return array;
+ }
+
+ @SuppressWarnings("unchecked")
+ T[] newArray = ArrayUtils.newUnpaddedArray((Class<T>)array.getClass().getComponentType(),
+ growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, index);
+ newArray[index] = element;
+ System.arraycopy(array, index, newArray, index + 1, array.length - index);
+ return newArray;
+ }
+
+ /**
+ * Primitive int version of {@link #insert(Object[], int, int, Object)}.
+ */
+ public static int[] insert(int[] array, int currentSize, int index, int element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 <= array.length) {
+ System.arraycopy(array, index, array, index + 1, currentSize - index);
+ array[index] = element;
+ return array;
+ }
+
+ int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, index);
+ newArray[index] = element;
+ System.arraycopy(array, index, newArray, index + 1, array.length - index);
+ return newArray;
+ }
+
+ /**
+ * Primitive long version of {@link #insert(Object[], int, int, Object)}.
+ */
+ public static long[] insert(long[] array, int currentSize, int index, long element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 <= array.length) {
+ System.arraycopy(array, index, array, index + 1, currentSize - index);
+ array[index] = element;
+ return array;
+ }
+
+ long[] newArray = ArrayUtils.newUnpaddedLongArray(growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, index);
+ newArray[index] = element;
+ System.arraycopy(array, index, newArray, index + 1, array.length - index);
+ return newArray;
+ }
+
+ /**
+ * Primitive boolean version of {@link #insert(Object[], int, int, Object)}.
+ */
+ public static boolean[] insert(boolean[] array, int currentSize, int index, boolean element) {
+ assert currentSize <= array.length;
+
+ if (currentSize + 1 <= array.length) {
+ System.arraycopy(array, index, array, index + 1, currentSize - index);
+ array[index] = element;
+ return array;
+ }
+
+ boolean[] newArray = ArrayUtils.newUnpaddedBooleanArray(growSize(currentSize));
+ System.arraycopy(array, 0, newArray, 0, index);
+ newArray[index] = element;
+ System.arraycopy(array, index, newArray, index + 1, array.length - index);
+ return newArray;
+ }
+
+ /**
+ * Given the current size of an array, returns an ideal size to which the array should grow.
+ * This is typically double the given size, but should not be relied upon to do so in the
+ * future.
+ */
+ public static int growSize(int currentSize) {
+ return currentSize <= 4 ? 8 : currentSize * 2;
+ }
+
+ // Uninstantiable
+ private GrowingArrayUtils() {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageUtils.java b/core/java/com/android/internal/util/ImageUtils.java
index 540ba20..a5ce6e0 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageUtils.java
+++ b/core/java/com/android/internal/util/ImageUtils.java
@@ -14,12 +14,14 @@
* limitations under the License
*/
-package com.android.systemui;
+package com.android.internal.util;
import android.graphics.Bitmap;
/**
* Utility class for image analysis and processing.
+ *
+ * @hide
*/
public class ImageUtils {
@@ -65,7 +67,7 @@ public class ImageUtils {
*
* Note that really transparent colors are always grayscale.
*/
- public boolean isGrayscale(int color) {
+ public static boolean isGrayscale(int color) {
int alpha = 0xFF & (color >> 24);
if (alpha < ALPHA_TOLERANCE) {
return true;
diff --git a/core/java/com/android/internal/util/LegacyNotificationUtil.java b/core/java/com/android/internal/util/LegacyNotificationUtil.java
new file mode 100644
index 0000000..0394bbc
--- /dev/null
+++ b/core/java/com/android/internal/util/LegacyNotificationUtil.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.util;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.TextAppearanceSpan;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.Arrays;
+import java.util.WeakHashMap;
+
+/**
+ * Helper class to process legacy (Holo) notifications to make them look like quantum notifications.
+ *
+ * @hide
+ */
+public class LegacyNotificationUtil {
+
+ private static final String TAG = "LegacyNotificationUtil";
+
+ private static final Object sLock = new Object();
+ private static LegacyNotificationUtil sInstance;
+
+ private final ImageUtils mImageUtils = new ImageUtils();
+ private final WeakHashMap<Bitmap, Pair<Boolean, Integer>> mGrayscaleBitmapCache =
+ new WeakHashMap<Bitmap, Pair<Boolean, Integer>>();
+
+ public static LegacyNotificationUtil getInstance() {
+ synchronized (sLock) {
+ if (sInstance == null) {
+ sInstance = new LegacyNotificationUtil();
+ }
+ return sInstance;
+ }
+ }
+
+ /**
+ * Checks whether a bitmap is grayscale. Grayscale here means "very close to a perfect
+ * gray".
+ *
+ * @param bitmap The bitmap to test.
+ * @return Whether the bitmap is grayscale.
+ */
+ public boolean isGrayscale(Bitmap bitmap) {
+ synchronized (sLock) {
+ Pair<Boolean, Integer> cached = mGrayscaleBitmapCache.get(bitmap);
+ if (cached != null) {
+ if (cached.second == bitmap.getGenerationId()) {
+ return cached.first;
+ }
+ }
+ }
+ boolean result;
+ int generationId;
+ synchronized (mImageUtils) {
+ result = mImageUtils.isGrayscale(bitmap);
+
+ // generationId and the check whether the Bitmap is grayscale can't be read atomically
+ // here. However, since the thread is in the process of posting the notification, we can
+ // assume that it doesn't modify the bitmap while we are checking the pixels.
+ generationId = bitmap.getGenerationId();
+ }
+ synchronized (sLock) {
+ mGrayscaleBitmapCache.put(bitmap, Pair.create(result, generationId));
+ }
+ return result;
+ }
+
+ /**
+ * Checks whether a drawable is grayscale. Grayscale here means "very close to a perfect
+ * gray".
+ *
+ * @param d The drawable to test.
+ * @return Whether the drawable is grayscale.
+ */
+ public boolean isGrayscale(Drawable d) {
+ if (d == null) {
+ return false;
+ } else if (d instanceof BitmapDrawable) {
+ BitmapDrawable bd = (BitmapDrawable) d;
+ return bd.getBitmap() != null && isGrayscale(bd.getBitmap());
+ } else if (d instanceof AnimationDrawable) {
+ AnimationDrawable ad = (AnimationDrawable) d;
+ int count = ad.getNumberOfFrames();
+ return count > 0 && isGrayscale(ad.getFrame(0));
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Checks whether a drawable with a resoure id is grayscale. Grayscale here means "very close
+ * to a perfect gray".
+ *
+ * @param context The context to load the drawable from.
+ * @return Whether the drawable is grayscale.
+ */
+ public boolean isGrayscale(Context context, int drawableResId) {
+ if (drawableResId != 0) {
+ try {
+ return isGrayscale(context.getDrawable(drawableResId));
+ } catch (Resources.NotFoundException ex) {
+ Log.e(TAG, "Drawable not found: " + drawableResId);
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Inverts all the grayscale colors set by {@link android.text.style.TextAppearanceSpan}s on
+ * the text.
+ *
+ * @param charSequence The text to process.
+ * @return The color inverted text.
+ */
+ public CharSequence invertCharSequenceColors(CharSequence charSequence) {
+ if (charSequence instanceof Spanned) {
+ Spanned ss = (Spanned) charSequence;
+ Object[] spans = ss.getSpans(0, ss.length(), Object.class);
+ SpannableStringBuilder builder = new SpannableStringBuilder(ss.toString());
+ for (Object span : spans) {
+ Object resultSpan = span;
+ if (span instanceof TextAppearanceSpan) {
+ resultSpan = processTextAppearanceSpan((TextAppearanceSpan) span);
+ }
+ builder.setSpan(resultSpan, ss.getSpanStart(span), ss.getSpanEnd(span),
+ ss.getSpanFlags(span));
+ }
+ return builder;
+ }
+ return charSequence;
+ }
+
+ private TextAppearanceSpan processTextAppearanceSpan(TextAppearanceSpan span) {
+ ColorStateList colorStateList = span.getTextColor();
+ if (colorStateList != null) {
+ int[] colors = colorStateList.getColors();
+ boolean changed = false;
+ for (int i = 0; i < colors.length; i++) {
+ if (ImageUtils.isGrayscale(colors[i])) {
+
+ // Allocate a new array so we don't change the colors in the old color state
+ // list.
+ if (!changed) {
+ colors = Arrays.copyOf(colors, colors.length);
+ }
+ colors[i] = processColor(colors[i]);
+ changed = true;
+ }
+ }
+ if (changed) {
+ return new TextAppearanceSpan(
+ span.getFamily(), span.getTextStyle(), span.getTextSize(),
+ new ColorStateList(colorStateList.getStates(), colors),
+ span.getLinkTextColor());
+ }
+ }
+ return span;
+ }
+
+ private int processColor(int color) {
+ return Color.argb(Color.alpha(color),
+ 255 - Color.red(color),
+ 255 - Color.green(color),
+ 255 - Color.blue(color));
+ }
+}
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 9501f92..91056f1 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -28,7 +28,6 @@ interface ILockSettings {
boolean checkPattern(in String pattern, int userId);
void setLockPassword(in String password, int userId);
boolean checkPassword(in String password, int userId);
- boolean checkVoldPassword(int userId);
boolean havePattern(int userId);
boolean havePassword(int userId);
void removeUser(int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e5aaf7e..2d79491 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -313,20 +313,6 @@ public class LockPatternUtils {
}
/**
- * Check to see if vold already has the password.
- * Note that this also clears vold's copy of the password.
- * @return Whether the vold password matches or not.
- */
- public boolean checkVoldPassword() {
- final int userId = getCurrentOrCallingUserId();
- try {
- return getLockSettings().checkVoldPassword(userId);
- } catch (RemoteException re) {
- return false;
- }
- }
-
- /**
* Check to see if a password matches any of the passwords stored in the
* password history.
*
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 2b9a5c4..b89dced 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -7,6 +7,7 @@
#include "SkImageDecoder.h"
#include "SkImageRef_ashmem.h"
#include "SkImageRef_GlobalPool.h"
+#include "SkMath.h"
#include "SkPixelRef.h"
#include "SkStream.h"
#include "SkTemplates.h"
@@ -146,15 +147,15 @@ static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
return pr;
}
-static SkBitmap::Config configForScaledOutput(SkBitmap::Config config) {
- switch (config) {
- case SkBitmap::kNo_Config:
- case SkBitmap::kIndex8_Config:
- return SkBitmap::kARGB_8888_Config;
+static SkColorType colorTypeForScaledOutput(SkColorType colorType) {
+ switch (colorType) {
+ case kUnknown_SkColorType:
+ case kIndex_8_SkColorType:
+ return kPMColor_SkColorType;
default:
break;
}
- return config;
+ return colorType;
}
class ScaleCheckingAllocator : public SkBitmap::HeapAllocator {
@@ -165,8 +166,8 @@ public:
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
// accounts for scale in final allocation, using eventual size and config
- const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
- configForScaledOutput(bitmap->config()));
+ const int bytesPerPixel = SkColorTypeBytesPerPixel(
+ colorTypeForScaledOutput(bitmap->colorType()));
const int requestedSize = bytesPerPixel *
int(bitmap->width() * mScale + 0.5f) *
int(bitmap->height() * mScale + 0.5f);
@@ -194,21 +195,28 @@ public:
}
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
- if (!bitmap->getSize64().is32() || bitmap->getSize() > mSize) {
- ALOGW("bitmap marked for reuse (%d bytes) can't fit new bitmap (%d bytes)",
- mSize, bitmap->getSize());
+ const SkImageInfo& info = bitmap->info();
+ if (info.fColorType == kUnknown_SkColorType) {
+ ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration");
return false;
}
- SkImageInfo bitmapInfo;
- if (!bitmap->asImageInfo(&bitmapInfo)) {
- ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration");
+ const int64_t size64 = info.getSafeSize64(bitmap->rowBytes());
+ if (!sk_64_isS32(size64)) {
+ ALOGW("bitmap is too large");
+ return false;
+ }
+
+ const size_t size = sk_64_asS32(size64);
+ if (size > mSize) {
+ ALOGW("bitmap marked for reuse (%d bytes) can't fit new bitmap (%d bytes)",
+ mSize, size);
return false;
}
// Create a new pixelref with the new ctable that wraps the previous pixelref
SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef),
- bitmapInfo, bitmap->rowBytes(), ctable);
+ info, bitmap->rowBytes(), ctable);
bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
@@ -416,12 +424,12 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
const float sy = scaledHeight / float(decodingBitmap.height());
// TODO: avoid copying when scaled size equals decodingBitmap size
- SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
+ SkColorType colorType = colorTypeForScaledOutput(decodingBitmap.colorType());
// FIXME: If the alphaType is kUnpremul and the image has alpha, the
// colors may not be correct, since Skia does not yet support drawing
// to/from unpremultiplied bitmaps.
- outputBitmap->setConfig(config, scaledWidth, scaledHeight, 0,
- decodingBitmap.alphaType());
+ outputBitmap->setConfig(SkImageInfo::Make(scaledWidth, scaledHeight,
+ colorType, decodingBitmap.alphaType()));
if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
return nullObjectReturn("allocation failed for scaled bitmap");
}
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 7420055..946b898 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -680,9 +680,6 @@ public:
indices [ptCount * sizeof(uint16_t)]
*/
ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[]
-#ifdef SK_SCALAR_IS_FIXED
- storageSize += ptCount * sizeof(SkPoint); // storage for verts
-#endif
storageSize += indexCount * sizeof(uint16_t); // indices[]
SkAutoMalloc storage(storageSize);
@@ -693,16 +690,7 @@ public:
verts = (SkPoint*)(vertA.ptr() + vertIndex);
indices = (uint16_t*)(texs + ptCount);
#else
- verts = texs + ptCount;
- indices = (uint16_t*)(verts + ptCount);
- // convert floats to fixed
- {
- const float* src = vertA.ptr() + vertIndex;
- for (int i = 0; i < ptCount; i++) {
- verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
- src += 2;
- }
- }
+ SkASSERT(false);
#endif
// cons up texture coordinates and indices
@@ -804,25 +792,7 @@ public:
texs = (SkPoint*)(texA.ptr() + texIndex);
}
#else
- int count = ptCount; // for verts
- if (jtexs != NULL) {
- count += ptCount; // += for texs
- }
- SkAutoMalloc storage(count * sizeof(SkPoint));
- verts = (SkPoint*)storage.get();
- const float* src = vertA.ptr() + vertIndex;
- for (int i = 0; i < ptCount; i++) {
- verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
- src += 2;
- }
- if (jtexs != NULL) {
- texs = verts + ptCount;
- src = texA.ptr() + texIndex;
- for (int i = 0; i < ptCount; i++) {
- texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
- src += 2;
- }
- }
+ SkASSERT(false);
#endif
const SkColor* colors = NULL;
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 09589bd..a59ed19 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -50,14 +50,10 @@ public:
AutoJavaFloatArray autoArray(env, jarray, 20);
const float* src = autoArray.ptr();
-#ifdef SK_SCALAR_IS_FIXED
- SkFixed array[20];
- for (int i = 0; i < 20; i++) {
- array[i] = SkFloatToScalar(src[i]);
- }
- return reinterpret_cast<jlong>(new SkColorMatrixFilter(array));
-#else
+#ifdef SK_SCALAR_IS_FLOAT
return reinterpret_cast<jlong>(new SkColorMatrixFilter(src));
+#else
+ SkASSERT(false);
#endif
}
};
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 98edbdb..2883be9 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -6,6 +6,7 @@
#include "SkCanvas.h"
#include "SkDevice.h"
+#include "SkMath.h"
#include "SkPicture.h"
#include "SkRegion.h"
#include <android_runtime/AndroidRuntime.h>
@@ -564,21 +565,20 @@ void AndroidPixelRef::globalUnref() {
jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
SkColorTable* ctable) {
- Sk64 size64 = bitmap->getSize64();
- if (size64.isNeg() || !size64.is32()) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "bitmap size exceeds 32bits");
+ const SkImageInfo& info = bitmap->info();
+ if (info.fColorType == kUnknown_SkColorType) {
+ doThrowIAE(env, "unknown bitmap configuration");
return NULL;
}
- SkImageInfo bitmapInfo;
- if (!bitmap->asImageInfo(&bitmapInfo)) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "unknown bitmap configuration");
+ const int64_t size64 = info.getSafeSize64(bitmap->rowBytes());
+ if (!sk_64_isS32(size64)) {
+ doThrowIAE(env, "bitmap size exceeds 32bits");
return NULL;
}
+ const size_t size = sk_64_asS32(size64);
+ SkASSERT(size == info.getSafeSize(bitmap->rowBytes()));
- size_t size = size64.get32();
jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
gVMRuntime_newNonMovableArray,
gByte_class, size);
@@ -591,7 +591,7 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
return NULL;
}
SkASSERT(addr);
- SkPixelRef* pr = new AndroidPixelRef(env, bitmapInfo, (void*) addr,
+ SkPixelRef* pr = new AndroidPixelRef(env, info, (void*) addr,
bitmap->rowBytes(), arrayObj, ctable);
bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
diff --git a/core/jni/android/graphics/Matrix.cpp b/core/jni/android/graphics/Matrix.cpp
index 6ae9fea..c400c57 100644
--- a/core/jni/android/graphics/Matrix.cpp
+++ b/core/jni/android/graphics/Matrix.cpp
@@ -272,18 +272,11 @@ public:
float* dst = autoDst.ptr() + dstIndex;
bool result;
-#ifdef SK_SCALAR_IS_FIXED
- SkPoint srcPt[4], dstPt[4];
- for (int i = 0; i < ptCount; i++) {
- int x = i << 1;
- int y = x + 1;
- srcPt[i].set(SkFloatToScalar(src[x]), SkFloatToScalar(src[y]));
- dstPt[i].set(SkFloatToScalar(dst[x]), SkFloatToScalar(dst[y]));
- }
- result = matrix->setPolyToPoly(srcPt, dstPt, ptCount);
-#else
+#ifdef SK_SCALAR_IS_FLOAT
result = matrix->setPolyToPoly((const SkPoint*)src, (const SkPoint*)dst,
ptCount);
+#else
+ SkASSERT(false);
#endif
return result ? JNI_TRUE : JNI_FALSE;
}
@@ -304,36 +297,15 @@ public:
AutoJavaFloatArray autoDst(env, dst, dstIndex + (ptCount << 1), kRW_JNIAccess);
float* srcArray = autoSrc.ptr() + srcIndex;
float* dstArray = autoDst.ptr() + dstIndex;
-
-#ifdef SK_SCALAR_IS_FIXED
- // we allocate twice the count, 1 set for src, 1 for dst
- SkAutoSTMalloc<32, SkPoint> storage(ptCount * 2);
- SkPoint* pts = storage.get();
- SkPoint* srcPt = pts;
- SkPoint* dstPt = pts + ptCount;
-
- int i;
- for (i = 0; i < ptCount; i++) {
- srcPt[i].set(SkFloatToScalar(srcArray[i << 1]),
- SkFloatToScalar(srcArray[(i << 1) + 1]));
- }
-
- if (isPts)
- matrix->mapPoints(dstPt, srcPt, ptCount);
- else
- matrix->mapVectors(dstPt, srcPt, ptCount);
-
- for (i = 0; i < ptCount; i++) {
- dstArray[i << 1] = SkScalarToFloat(dstPt[i].fX);
- dstArray[(i << 1) + 1] = SkScalarToFloat(dstPt[i].fY);
- }
-#else
+#ifdef SK_SCALAR_IS_FLOAT
if (isPts)
matrix->mapPoints((SkPoint*)dstArray, (const SkPoint*)srcArray,
ptCount);
else
matrix->mapVectors((SkVector*)dstArray, (const SkVector*)srcArray,
ptCount);
+#else
+ SkASSERT(false);
#endif
}
@@ -356,18 +328,12 @@ public:
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
AutoJavaFloatArray autoValues(env, values, 9, kRW_JNIAccess);
float* dst = autoValues.ptr();
-
-#ifdef SK_SCALAR_IS_FIXED
- for (int i = 0; i < 6; i++) {
- dst[i] = SkFixedToFloat(matrix->get(i));
- }
- for (int j = 6; j < 9; j++) {
- dst[j] = SkFractToFloat(matrix->get(j));
- }
-#else
+#ifdef SK_SCALAR_IS_FLOAT
for (int i = 0; i < 9; i++) {
dst[i] = matrix->get(i);
}
+#else
+ SkASSERT(false);
#endif
}
@@ -376,17 +342,12 @@ public:
AutoJavaFloatArray autoValues(env, values, 9, kRO_JNIAccess);
const float* src = autoValues.ptr();
-#ifdef SK_SCALAR_IS_FIXED
- for (int i = 0; i < 6; i++) {
- matrix->set(i, SkFloatToFixed(src[i]));
- }
- for (int j = 6; j < 9; j++) {
- matrix->set(j, SkFloatToFract(src[j]));
- }
-#else
+#ifdef SK_SCALAR_IS_FLOAT
for (int i = 0; i < 9; i++) {
matrix->set(i, src[i]);
}
+#else
+ SkASSERT(false);
#endif
}
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 51990d5..1167bfe 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -422,16 +422,16 @@ public:
SkPaint::FontMetrics metrics;
GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
- int ascent = SkScalarRound(metrics.fAscent);
- int descent = SkScalarRound(metrics.fDescent);
- int leading = SkScalarRound(metrics.fLeading);
+ int ascent = SkScalarRoundToInt(metrics.fAscent);
+ int descent = SkScalarRoundToInt(metrics.fDescent);
+ int leading = SkScalarRoundToInt(metrics.fLeading);
if (metricsObj) {
SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
- env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloor(metrics.fTop));
+ env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop));
env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
- env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeil(metrics.fBottom));
+ env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom));
env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
}
return descent - ascent + leading;
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 144ac39..9279758 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -70,7 +70,7 @@ void TextLayoutCache::operator()(TextLayoutCacheKey& text, sp<TextLayoutValue>&
size_t totalSizeToDelete = text.getSize() + desc->getSize();
mSize -= totalSizeToDelete;
if (mDebugEnabled) {
- ALOGD("Cache value %p deleted, size = %d", desc.get(), totalSizeToDelete);
+ ALOGD("Cache value %p deleted, size = %zu", desc.get(), totalSizeToDelete);
}
}
@@ -130,7 +130,7 @@ sp<TextLayoutValue> TextLayoutCache::getValue(const SkPaint* paint,
bool removedOne = mCache.removeOldest();
LOG_ALWAYS_FATAL_IF(!removedOne, "The cache is non-empty but we "
"failed to remove the oldest entry. "
- "mSize = %u, size = %u, mMaxSize = %u, mCache.size() = %u",
+ "mSize = %u, size = %zu, mMaxSize = %u, mCache.size() = %zu",
mSize, size, mMaxSize, mCache.size());
}
}
@@ -149,7 +149,7 @@ sp<TextLayoutValue> TextLayoutCache::getValue(const SkPaint* paint,
nsecs_t totalTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
ALOGD("CACHE MISS: Added entry %p "
"with start = %d, count = %d, contextCount = %d, "
- "entry size %d bytes, remaining space %d bytes"
+ "entry size %zu bytes, remaining space %d bytes"
" - Compute time %0.6f ms - Put time %0.6f ms - Text = '%s'",
value.get(), start, count, contextCount, size, mMaxSize - mSize,
value->getElapsedTime() * 0.000001f,
@@ -160,7 +160,7 @@ sp<TextLayoutValue> TextLayoutCache::getValue(const SkPaint* paint,
if (mDebugEnabled) {
ALOGD("CACHE MISS: Calculated but not storing entry because it is too big "
"with start = %d, count = %d, contextCount = %d, "
- "entry size %d bytes, remaining space %d bytes"
+ "entry size %zu bytes, remaining space %d bytes"
" - Compute time %0.6f ms - Text = '%s'",
start, count, contextCount, size, mMaxSize - mSize,
value->getElapsedTime() * 0.000001f,
@@ -205,7 +205,7 @@ void TextLayoutCache::dumpCacheStats() {
ALOGD("------------------------------------------------");
ALOGD("pid : %d", getpid());
ALOGD("running : %.0f seconds", timeRunningInSec);
- ALOGD("entries : %d", cacheSize);
+ ALOGD("entries : %zu", cacheSize);
ALOGD("max size : %d bytes", mMaxSize);
ALOGD("used : %d bytes according to mSize", mSize);
ALOGD("remaining : %d bytes or %2.2f percent", mMaxSize - mSize, remainingPercent);
@@ -492,7 +492,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
(((ucs) & 0xfc00) == 0xdc00)
#ifndef HB_SurrogateToUcs4
-#define HB_SurrogateToUcs4_(high, low) \
+#define HB_SurrogateToUcs4(high, low) \
(((hb_codepoint_t)(high))<<10) + (low) - 0x35fdc00;
#endif
@@ -784,7 +784,7 @@ SkTypeface* TextLayoutShaper::typefaceForScript(const SkPaint* paint, SkTypeface
if (typeface) {
currentStyle = typeface->style();
}
- typeface = SkCreateTypefaceForScriptNG(script, currentStyle);
+ typeface = SkCreateTypefaceForScript(script, currentStyle);
#if DEBUG_GLYPHS
ALOGD("Using Harfbuzz Script %c%c%c%c, Style %d", HB_UNTAG(script), currentStyle);
#endif
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index 9f79f74..98f4bed 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -111,7 +111,7 @@ socket_bind_local (JNIEnv *env, jobject object, jobject fileDescriptor,
/* private native void listen_native(int fd, int backlog) throws IOException; */
static void
-socket_listen (JNIEnv *env, jobject object, jobject fileDescriptor, int backlog)
+socket_listen (JNIEnv *env, jobject object, jobject fileDescriptor, jint backlog)
{
int ret;
int fd;
@@ -231,7 +231,7 @@ java_opt_to_real(int optID, int* opt, int* level)
}
static jint
-socket_getOption(JNIEnv *env, jobject object, jobject fileDescriptor, int optID)
+socket_getOption(JNIEnv *env, jobject object, jobject fileDescriptor, jint optID)
{
int ret, value;
int opt, level;
@@ -279,7 +279,7 @@ socket_getOption(JNIEnv *env, jobject object, jobject fileDescriptor, int optID)
}
static void socket_setOption(
- JNIEnv *env, jobject object, jobject fileDescriptor, int optID,
+ JNIEnv *env, jobject object, jobject fileDescriptor, jint optID,
jint boolValue, jint intValue) {
int ret;
int optname;
diff --git a/core/jni/android_nio_utils.cpp b/core/jni/android_nio_utils.cpp
index 7cbbe12..59d6e41 100644
--- a/core/jni/android_nio_utils.cpp
+++ b/core/jni/android_nio_utils.cpp
@@ -37,7 +37,7 @@ void* android::nio_getPointer(JNIEnv *_env, jobject buffer, jarray *array) {
gNioJNI.getBasePointerID, buffer);
if (pointer != 0L) {
*array = NULL;
- return (void *) (jint) pointer;
+ return reinterpret_cast<void *>(pointer);
}
*array = (jarray) _env->CallStaticObjectMethod(gNioJNI.nioAccessClass,
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index a041693..d4873d6 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -800,7 +800,7 @@ static void dumpNativeHeap(FILE* fp)
fprintf(fp, "Total memory: %zu\n", totalMemory);
fprintf(fp, "Allocation records: %zd\n", recordCount);
if (backtraceSize != BACKTRACE_SIZE) {
- fprintf(fp, "WARNING: mismatched backtrace sizes (%d vs. %d)\n",
+ fprintf(fp, "WARNING: mismatched backtrace sizes (%zu vs. %d)\n",
backtraceSize, BACKTRACE_SIZE);
}
fprintf(fp, "\n");
@@ -823,7 +823,11 @@ static void dumpNativeHeap(FILE* fp)
if (backtrace[bt] == 0) {
break;
} else {
+#ifdef __LP64__
+ fprintf(fp, " %016x", backtrace[bt]);
+#else
fprintf(fp, " %08x", backtrace[bt]);
+#endif
}
}
fprintf(fp, "\n");
diff --git a/core/jni/android_server_NetworkManagementSocketTagger.cpp b/core/jni/android_server_NetworkManagementSocketTagger.cpp
index 12beff7..7e12b1e 100644
--- a/core/jni/android_server_NetworkManagementSocketTagger.cpp
+++ b/core/jni/android_server_NetworkManagementSocketTagger.cpp
@@ -47,8 +47,8 @@ static jint QTagUid_tagSocketFd(JNIEnv* env, jclass,
return (jint)res;
}
-static int QTagUid_untagSocketFd(JNIEnv* env, jclass,
- jobject fileDescriptor) {
+static jint QTagUid_untagSocketFd(JNIEnv* env, jclass,
+ jobject fileDescriptor) {
int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
if (env->ExceptionOccurred() != NULL) {
diff --git a/core/jni/android_text_AndroidBidi.cpp b/core/jni/android_text_AndroidBidi.cpp
index d50a69f..6f7ee49 100644
--- a/core/jni/android_text_AndroidBidi.cpp
+++ b/core/jni/android_text_AndroidBidi.cpp
@@ -26,7 +26,7 @@
namespace android {
static jint runBidi(JNIEnv* env, jobject obj, jint dir, jcharArray chsArray,
- jbyteArray infoArray, int n, jboolean haveInfo)
+ jbyteArray infoArray, jint n, jboolean haveInfo)
{
// Parameters are checked on java side
// Failures from GetXXXArrayElements indicate a serious out-of-memory condition
diff --git a/core/jni/android_text_AndroidCharacter.cpp b/core/jni/android_text_AndroidCharacter.cpp
index 8b85a7b7..94bd40f 100644
--- a/core/jni/android_text_AndroidCharacter.cpp
+++ b/core/jni/android_text_AndroidCharacter.cpp
@@ -51,7 +51,8 @@ static int directionality_map[U_CHAR_DIRECTION_COUNT] = {
namespace android {
-static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray, jbyteArray destArray, int count)
+static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray,
+ jbyteArray destArray, jint count)
{
ScopedCharArrayRO src(env, srcArray);
if (src.get() == NULL) {
@@ -102,7 +103,7 @@ static jint getEastAsianWidth(JNIEnv* env, jobject obj, jchar input)
}
static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
- int start, int count, jbyteArray destArray)
+ jint start, jint count, jbyteArray destArray)
{
ScopedCharArrayRO src(env, srcArray);
if (src.get() == NULL) {
@@ -144,20 +145,20 @@ static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
}
}
-static jboolean mirror(JNIEnv* env, jobject obj, jcharArray charArray, int start, int count)
+static jboolean mirror(JNIEnv* env, jobject obj, jcharArray charArray, jint start, jint count)
{
ScopedCharArrayRW data(env, charArray);
if (data.get() == NULL) {
- return false;
+ return JNI_FALSE;
}
if (start < 0 || start > start + count
|| env->GetArrayLength(charArray) < start + count) {
jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
- return false;
+ return JNI_FALSE;
}
- bool ret = false;
+ jboolean ret = JNI_FALSE;
for (int i = start; i < start + count; i++) {
// XXX this thinks it knows that surrogates are never mirrored
@@ -166,7 +167,7 @@ static jboolean mirror(JNIEnv* env, jobject obj, jcharArray charArray, int start
if (c1 != c2) {
data[i] = c2;
- ret = true;
+ ret = JNI_TRUE;
}
}
return ret;
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index aa2c5f39..28a8a5d 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -117,7 +117,7 @@ static jlong android_text_format_Time_normalize(JNIEnv* env, jobject This,
time2java(env, This, t);
RELEASE_TIMEZONE(This, t)
- return result;
+ return static_cast<jlong>(result);
}
static void android_text_format_Time_switchTimezone(JNIEnv* env, jobject This,
@@ -155,7 +155,7 @@ static jint android_text_format_Time_compare(JNIEnv* env, jobject clazz,
RELEASE_TIMEZONE(aObject, a)
RELEASE_TIMEZONE(bObject, b)
- return result;
+ return static_cast<jint>(result);
}
static jstring android_text_format_Time_format2445(JNIEnv* env, jobject This)
@@ -346,7 +346,7 @@ static jlong android_text_format_Time_toMillis(JNIEnv* env, jobject This,
RELEASE_TIMEZONE(This, t)
- return result;
+ return static_cast<jlong>(result);
}
static void android_text_format_Time_set(JNIEnv* env, jobject This, jlong millis)
@@ -400,10 +400,10 @@ static jboolean android_text_format_Time_parse(JNIEnv* env, jobject This, jstrin
if (len < 8) {
jniThrowException(env, "android/util/TimeFormatException",
"String too short -- expected at least 8 characters.");
- return false;
+ return JNI_FALSE;
}
- jboolean inUtc = false;
+ jboolean inUtc = JNI_FALSE;
ScopedStringChars s(env, strObj);
@@ -414,49 +414,49 @@ static jboolean android_text_format_Time_parse(JNIEnv* env, jobject This, jstrin
n += get_char(env, s, 1, 100, &thrown);
n += get_char(env, s, 2, 10, &thrown);
n += get_char(env, s, 3, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_yearField, n);
// month
n = get_char(env, s, 4, 10, &thrown);
n += get_char(env, s, 5, 1, &thrown);
n--;
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_monField, n);
// day of month
n = get_char(env, s, 6, 10, &thrown);
n += get_char(env, s, 7, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_mdayField, n);
if (len > 8) {
// T
- if (!check_char(env, s, 8, 'T')) return false;
+ if (!check_char(env, s, 8, 'T')) return JNI_FALSE;
env->SetBooleanField(This, g_allDayField, JNI_FALSE);
// hour
n = get_char(env, s, 9, 10, &thrown);
n += get_char(env, s, 10, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_hourField, n);
// min
n = get_char(env, s, 11, 10, &thrown);
n += get_char(env, s, 12, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_minField, n);
// sec
n = get_char(env, s, 13, 10, &thrown);
n += get_char(env, s, 14, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_secField, n);
if (len > 15) {
// Z
- if (!check_char(env, s, 15, 'Z')) return false;
- inUtc = true;
+ if (!check_char(env, s, 15, 'Z')) return JNI_FALSE;
+ inUtc = JNI_TRUE;
}
} else {
env->SetBooleanField(This, g_allDayField, JNI_TRUE);
@@ -481,10 +481,10 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
if (len < 10) {
jniThrowException(env, "android/util/TimeFormatException",
"String too short --- expected at least 10 characters.");
- return false;
+ return JNI_FALSE;
}
- jboolean inUtc = false;
+ jboolean inUtc = JNI_FALSE;
ScopedStringChars s(env, strObj);
@@ -495,57 +495,57 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
n += get_char(env, s, 1, 100, &thrown);
n += get_char(env, s, 2, 10, &thrown);
n += get_char(env, s, 3, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_yearField, n);
// -
- if (!check_char(env, s, 4, '-')) return false;
+ if (!check_char(env, s, 4, '-')) return JNI_FALSE;
// month
n = get_char(env, s, 5, 10, &thrown);
n += get_char(env, s, 6, 1, &thrown);
--n;
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_monField, n);
// -
- if (!check_char(env, s, 7, '-')) return false;
+ if (!check_char(env, s, 7, '-')) return JNI_FALSE;
// day
n = get_char(env, s, 8, 10, &thrown);
n += get_char(env, s, 9, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_mdayField, n);
if (len >= 19) {
// T
- if (!check_char(env, s, 10, 'T')) return false;
+ if (!check_char(env, s, 10, 'T')) return JNI_FALSE;
env->SetBooleanField(This, g_allDayField, JNI_FALSE);
// hour
n = get_char(env, s, 11, 10, &thrown);
n += get_char(env, s, 12, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
int hour = n;
// env->SetIntField(This, g_hourField, n);
// :
- if (!check_char(env, s, 13, ':')) return false;
+ if (!check_char(env, s, 13, ':')) return JNI_FALSE;
// minute
n = get_char(env, s, 14, 10, &thrown);
n += get_char(env, s, 15, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
int minute = n;
// env->SetIntField(This, g_minField, n);
// :
- if (!check_char(env, s, 16, ':')) return false;
+ if (!check_char(env, s, 16, ':')) return JNI_FALSE;
// second
n = get_char(env, s, 17, 10, &thrown);
n += get_char(env, s, 18, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
env->SetIntField(This, g_secField, n);
// skip the '.XYZ' -- we don't care about subsecond precision.
@@ -579,32 +579,32 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
jniThrowExceptionFmt(env, "android/util/TimeFormatException",
"Unexpected character 0x%02x at position %d. Expected + or -",
c, tz_index);
- return false;
+ return JNI_FALSE;
}
- inUtc = true;
+ inUtc = JNI_TRUE;
if (offset != 0) {
if (len < tz_index + 6) {
jniThrowExceptionFmt(env, "android/util/TimeFormatException",
"Unexpected length; should be %d characters",
tz_index + 6);
- return false;
+ return JNI_FALSE;
}
// hour
n = get_char(env, s, tz_index + 1, 10, &thrown);
n += get_char(env, s, tz_index + 2, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
n *= offset;
hour += n;
// :
- if (!check_char(env, s, tz_index + 3, ':')) return false;
+ if (!check_char(env, s, tz_index + 3, ':')) return JNI_FALSE;
// minute
n = get_char(env, s, tz_index + 4, 10, &thrown);
n += get_char(env, s, tz_index + 5, 1, &thrown);
- if (thrown) return false;
+ if (thrown) return JNI_FALSE;
n *= offset;
minute += n;
}
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index 536a582..93dcbef 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -85,7 +85,7 @@ static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring
jboolean result = false;
if ((strlen(chars)+sizeof(LOG_NAMESPACE)) > PROPERTY_KEY_MAX) {
char buf2[200];
- snprintf(buf2, sizeof(buf2), "Log tag \"%s\" exceeds limit of %d characters\n",
+ snprintf(buf2, sizeof(buf2), "Log tag \"%s\" exceeds limit of %zu characters\n",
chars, PROPERTY_KEY_MAX - sizeof(LOG_NAMESPACE));
jniThrowException(env, "java/lang/IllegalArgumentException", buf2);
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 5c7e773..3e359d4 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -115,23 +115,38 @@ static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
jint right, jint bottom, jfloat radius) {
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom, radius);
+ displayList->mutateStagingProperties().updateClipPath();
}
+
static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
displayList->mutateStagingProperties().mutableOutline().setConvexPath(outlinePath);
+ displayList->mutateStagingProperties().updateClipPath();
}
+
static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->mutateStagingProperties().mutableOutline().setEmpty();
+ displayList->mutateStagingProperties().updateClipPath();
}
static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
+ displayList->mutateStagingProperties().updateClipPath();
+}
+
+static void android_view_RenderNode_setRevealClip(JNIEnv* env,
+ jobject clazz, jlong displayListPtr, jboolean shouldClip, jboolean inverseClip,
+ jfloat x, jfloat y, jfloat radius) {
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+ displayList->mutateStagingProperties().mutableRevealClip().set(
+ shouldClip, inverseClip, x, y, radius);
+ displayList->mutateStagingProperties().updateClipPath();
}
static void android_view_RenderNode_setAlpha(JNIEnv* env,
@@ -396,6 +411,7 @@ static JNINativeMethod gMethods[] = {
{ "nSetOutlineConvexPath", "(JJ)V", (void*) android_view_RenderNode_setOutlineConvexPath },
{ "nSetOutlineEmpty", "(J)V", (void*) android_view_RenderNode_setOutlineEmpty },
{ "nSetClipToOutline", "(JZ)V", (void*) android_view_RenderNode_setClipToOutline },
+ { "nSetRevealClip", "(JZZFFF)V", (void*) android_view_RenderNode_setRevealClip },
{ "nSetAlpha", "(JF)V", (void*) android_view_RenderNode_setAlpha },
{ "nSetHasOverlappingRendering", "(JZ)V",
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index c5ab284..159ffb2 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -58,36 +58,11 @@ static struct {
jfieldID secure;
} gPhysicalDisplayInfoClassInfo;
-
-class ScreenshotPixelRef : public SkPixelRef {
-public:
- ScreenshotPixelRef(const SkImageInfo& info, ScreenshotClient* screenshot) :
- SkPixelRef(info),
- mScreenshot(screenshot) {
- setImmutable();
- }
-
- virtual ~ScreenshotPixelRef() {
- delete mScreenshot;
- }
-
-protected:
- // overrides from SkPixelRef
- virtual void* onLockPixels(SkColorTable** ct) {
- *ct = NULL;
- return (void*)mScreenshot->getPixels();
- }
-
- virtual void onUnlockPixels() {
- }
-
- SK_DECLARE_UNFLATTENABLE_OBJECT()
-private:
- ScreenshotClient* mScreenshot;
-
- typedef SkPixelRef INHERITED;
-};
-
+// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
+void DeleteScreenshot(void* addr, void* context) {
+ SkASSERT(addr == ((ScreenshotClient*) context)->getPixels());
+ delete ((ScreenshotClient*) context);
+}
// ----------------------------------------------------------------------------
@@ -167,20 +142,19 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display
}
}
- // takes ownership of ScreenshotClient
- ScreenshotPixelRef* pixels = new ScreenshotPixelRef(screenshotInfo, screenshot);
const ssize_t rowBytes =
screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
SkBitmap* bitmap = new SkBitmap();
bitmap->setConfig(screenshotInfo, (size_t)rowBytes);
if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
+ // takes ownership of ScreenshotClient
+ SkMallocPixelRef* pixels = SkMallocPixelRef::NewWithProc(screenshotInfo,
+ (size_t) rowBytes, NULL, (void*) screenshot->getPixels(), &DeleteScreenshot,
+ (void*) screenshot);
+ pixels->setImmutable();
bitmap->setPixelRef(pixels)->unref();
bitmap->lockPixels();
- } else {
- // be safe with an empty bitmap.
- delete pixels;
- bitmap->setPixels(NULL);
}
return GraphicsJNI::createBitmap(env, bitmap,
diff --git a/core/res/res/drawable/background_cache_hint_selector_holo_dark.xml b/core/res/res/color/background_cache_hint_selector_holo_dark.xml
index b18c5b7..b18c5b7 100644
--- a/core/res/res/drawable/background_cache_hint_selector_holo_dark.xml
+++ b/core/res/res/color/background_cache_hint_selector_holo_dark.xml
diff --git a/core/res/res/drawable/background_cache_hint_selector_holo_light.xml b/core/res/res/color/background_cache_hint_selector_holo_light.xml
index 9d80944..9d80944 100644
--- a/core/res/res/drawable/background_cache_hint_selector_holo_light.xml
+++ b/core/res/res/color/background_cache_hint_selector_holo_light.xml
diff --git a/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml b/core/res/res/color/background_cache_hint_selector_quantum_dark.xml
index ab66501..ab66501 100644
--- a/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
+++ b/core/res/res/color/background_cache_hint_selector_quantum_dark.xml
diff --git a/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml b/core/res/res/color/background_cache_hint_selector_quantum_light.xml
index fb940a9..fb940a9 100644
--- a/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
+++ b/core/res/res/color/background_cache_hint_selector_quantum_light.xml
diff --git a/core/res/res/drawable/ab_transparent_quantum_dark.xml b/core/res/res/drawable/ab_transparent_quantum.xml
index 9ac2fc0..495bfb6 100644
--- a/core/res/res/drawable/ab_transparent_quantum_dark.xml
+++ b/core/res/res/drawable/ab_transparent_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ab_transparent_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ab_transparent_quantum_light.xml b/core/res/res/drawable/ab_transparent_quantum_light.xml
deleted file mode 100644
index bc49848..0000000
--- a/core/res/res/drawable/ab_transparent_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ab_transparent_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/activated_background_quantum_dark.xml b/core/res/res/drawable/activated_background_quantum.xml
index a9e3fea..e06c9f2 100644
--- a/core/res/res/drawable/activated_background_quantum_dark.xml
+++ b/core/res/res/drawable/activated_background_quantum.xml
@@ -15,6 +15,10 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true" android:drawable="@color/control_activated_foreground_quantum_dark" />
- <item android:drawable="@color/transparent" />
+ <item android:state_activated="true">
+ <color android:color="?attr/colorControlActivated" />
+ </item>
+ <item>
+ <color android:color="@color/transparent" />
+ </item>
</selector>
diff --git a/core/res/res/drawable/activated_background_quantum_light.xml b/core/res/res/drawable/activated_background_quantum_light.xml
deleted file mode 100644
index 5d10ea2..0000000
--- a/core/res/res/drawable/activated_background_quantum_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true" android:drawable="@color/control_activated_foreground_quantum_light" />
- <item android:drawable="@color/transparent" />
-</selector>
diff --git a/core/res/res/drawable/btn_borderless_quantum_dark.xml b/core/res/res/drawable/btn_borderless_quantum.xml
index 2c0d3b7..2e3c515 100644
--- a/core/res/res/drawable/btn_borderless_quantum_dark.xml
+++ b/core/res/res/drawable/btn_borderless_quantum.xml
@@ -15,5 +15,7 @@
-->
<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/btn_default_pressed_quantum_dark"
- android:mask="@drawable/btn_qntm_alpha" />
+ android:tint="?attr/colorButtonPressed">
+ <item android:id="@id/mask"
+ android:drawable="@drawable/btn_qntm_alpha" />
+</touch-feedback>
diff --git a/core/res/res/drawable/btn_borderless_quantum_light.xml b/core/res/res/drawable/btn_borderless_quantum_light.xml
deleted file mode 100644
index 2faec20..0000000
--- a/core/res/res/drawable/btn_borderless_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/btn_default_pressed_quantum_light"
- android:mask="@drawable/btn_qntm_alpha" />
diff --git a/core/res/res/drawable/btn_check_quantum_dark.xml b/core/res/res/drawable/btn_check_quantum.xml
index a35bec4..6ceba60 100644
--- a/core/res/res/drawable/btn_check_quantum_dark.xml
+++ b/core/res/res/drawable/btn_check_quantum.xml
@@ -17,18 +17,18 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:state_pressed="true">
<bitmap android:src="@drawable/btn_check_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_checked="true">
<bitmap android:src="@drawable/btn_check_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_pressed="true">
<bitmap android:src="@drawable/btn_check_off_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<bitmap android:src="@drawable/btn_check_off_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/btn_check_quantum_light.xml b/core/res/res/drawable/btn_check_quantum_light.xml
deleted file mode 100644
index 8588fce..0000000
--- a/core/res/res/drawable/btn_check_quantum_light.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:state_pressed="true">
- <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_checked="true">
- <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_pressed="true">
- <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/btn_color_quantum_dark.xml b/core/res/res/drawable/btn_color_quantum.xml
index 0507755..e923003 100644
--- a/core/res/res/drawable/btn_color_quantum_dark.xml
+++ b/core/res/res/drawable/btn_color_quantum.xml
@@ -15,15 +15,15 @@
-->
<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/theme_color_300">
+ android:tint="?attr/colorButtonPressedColored">
<selector>
<item android:state_enabled="false">
<nine-patch android:src="@drawable/btn_qntm_alpha"
- android:tint="@color/btn_default_normal_quantum_dark" />
+ android:tint="?attr/colorButtonNormal" />
</item>
<item>
<nine-patch android:src="@drawable/btn_qntm_alpha"
- android:tint="@color/theme_color_500" />
+ android:tint="?attr/colorButtonNormalColored" />
</item>
</selector>
</touch-feedback>
diff --git a/core/res/res/drawable/btn_color_quantum_light.xml b/core/res/res/drawable/btn_color_quantum_light.xml
deleted file mode 100644
index 9166b8d..0000000
--- a/core/res/res/drawable/btn_color_quantum_light.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/theme_color_700">
- <selector>
- <item android:state_enabled="false">
- <nine-patch android:src="@drawable/btn_qntm_alpha"
- android:tint="@color/btn_default_normal_quantum_dark" />
- </item>
- <item>
- <nine-patch android:src="@drawable/btn_qntm_alpha"
- android:tint="@color/theme_color_500" />
- </item>
- </selector>
-</touch-feedback>
diff --git a/core/res/res/drawable/btn_default_quantum_dark.xml b/core/res/res/drawable/btn_default_quantum.xml
index 29c3e24..2919621 100644
--- a/core/res/res/drawable/btn_default_quantum_dark.xml
+++ b/core/res/res/drawable/btn_default_quantum.xml
@@ -15,7 +15,9 @@
-->
<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/btn_default_pressed_quantum_dark">
- <nine-patch android:src="@drawable/btn_qntm_alpha"
- android:tint="@color/btn_default_normal_quantum_dark" />
+ android:tint="?attr/colorButtonPressed">
+ <item>
+ <nine-patch android:src="@drawable/btn_qntm_alpha"
+ android:tint="?attr/colorButtonNormal" />
+ </item>
</touch-feedback>
diff --git a/core/res/res/drawable/btn_default_quantum_light.xml b/core/res/res/drawable/btn_default_quantum_light.xml
deleted file mode 100644
index c6e828c..0000000
--- a/core/res/res/drawable/btn_default_quantum_light.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/btn_default_pressed_quantum_light">
- <nine-patch android:src="@drawable/btn_qntm_alpha"
- android:tint="@color/btn_default_normal_quantum_light" />
-</touch-feedback>
diff --git a/core/res/res/drawable/btn_radio_quantum_dark.xml b/core/res/res/drawable/btn_radio_quantum.xml
index 54f4f9a..152e3d3 100644
--- a/core/res/res/drawable/btn_radio_quantum_dark.xml
+++ b/core/res/res/drawable/btn_radio_quantum.xml
@@ -17,18 +17,18 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:state_enabled="true" android:state_pressed="true">
<bitmap android:src="@drawable/btn_radio_on_pressed_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_checked="true">
<bitmap android:src="@drawable/btn_radio_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_enabled="true" android:state_pressed="true">
<bitmap android:src="@drawable/btn_radio_off_pressed_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<bitmap android:src="@drawable/btn_radio_off_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/btn_radio_quantum_light.xml b/core/res/res/drawable/btn_radio_quantum_light.xml
deleted file mode 100644
index c1ace70..0000000
--- a/core/res/res/drawable/btn_radio_quantum_light.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:state_enabled="true" android:state_pressed="true">
- <bitmap android:src="@drawable/btn_radio_on_pressed_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_checked="true">
- <bitmap android:src="@drawable/btn_radio_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_enabled="true" android:state_pressed="true">
- <bitmap android:src="@drawable/btn_radio_off_pressed_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <bitmap android:src="@drawable/btn_radio_off_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/btn_star_quantum_dark.xml b/core/res/res/drawable/btn_star_quantum.xml
index 7b26a3c..512cd57 100644
--- a/core/res/res/drawable/btn_star_quantum_dark.xml
+++ b/core/res/res/drawable/btn_star_quantum.xml
@@ -17,14 +17,14 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<bitmap android:src="@drawable/btn_star_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_pressed="true">
<bitmap android:src="@drawable/btn_star_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<bitmap android:src="@drawable/btn_star_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/btn_star_quantum_light.xml b/core/res/res/drawable/btn_star_quantum_light.xml
deleted file mode 100644
index df2cc91..0000000
--- a/core/res/res/drawable/btn_star_quantum_light.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true">
- <bitmap android:src="@drawable/btn_star_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_pressed="true">
- <bitmap android:src="@drawable/btn_star_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <bitmap android:src="@drawable/btn_star_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/edit_text_quantum_dark.xml b/core/res/res/drawable/edit_text_quantum.xml
index ea3fc52..d1f9831 100644
--- a/core/res/res/drawable/edit_text_quantum_dark.xml
+++ b/core/res/res/drawable/edit_text_quantum.xml
@@ -17,26 +17,26 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true">
<nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
<item android:state_window_focused="false" android:state_enabled="false">
<nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
<item android:state_enabled="true" android:state_focused="true">
<nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_enabled="true" android:state_activated="true">
<nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_enabled="true">
<nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
<item>
<nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/edit_text_quantum_light.xml b/core/res/res/drawable/edit_text_quantum_light.xml
deleted file mode 100644
index dd7fe53..0000000
--- a/core/res/res/drawable/edit_text_quantum_light.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true">
- <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
- <item android:state_window_focused="false" android:state_enabled="false">
- <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
- <item android:state_enabled="true" android:state_focused="true">
- <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_enabled="true" android:state_activated="true">
- <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_enabled="true">
- <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
- <item>
- <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/expander_group_quantum_dark.xml b/core/res/res/drawable/expander_group_quantum.xml
index 7250e01..48245ea 100644
--- a/core/res/res/drawable/expander_group_quantum_dark.xml
+++ b/core/res/res/drawable/expander_group_quantum.xml
@@ -17,10 +17,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_expanded="true">
<nine-patch android:src="@drawable/expander_close_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
<item>
<nine-patch android:src="@drawable/expander_open_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/expander_group_quantum_light.xml b/core/res/res/drawable/expander_group_quantum_light.xml
deleted file mode 100644
index 62af983..0000000
--- a/core/res/res/drawable/expander_group_quantum_light.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_expanded="true">
- <nine-patch android:src="@drawable/expander_close_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
- <item>
- <nine-patch android:src="@drawable/expander_open_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/fastscroll_thumb_quantum_dark.xml b/core/res/res/drawable/fastscroll_thumb_quantum.xml
index 53c7fdd..496b2ae 100644
--- a/core/res/res/drawable/fastscroll_thumb_quantum_dark.xml
+++ b/core/res/res/drawable/fastscroll_thumb_quantum.xml
@@ -17,10 +17,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/fastscroll_thumb_quantum_light.xml b/core/res/res/drawable/fastscroll_thumb_quantum_light.xml
deleted file mode 100644
index 3bc87e9..0000000
--- a/core/res/res/drawable/fastscroll_thumb_quantum_light.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true">
- <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/fastscroll_track_quantum_light.xml b/core/res/res/drawable/fastscroll_track_quantum.xml
index 627c079..59c35db 100644
--- a/core/res/res/drawable/fastscroll_track_quantum_light.xml
+++ b/core/res/res/drawable/fastscroll_track_quantum.xml
@@ -16,4 +16,4 @@
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/fastscroll_track_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/fastscroll_track_quantum_dark.xml b/core/res/res/drawable/fastscroll_track_quantum_dark.xml
deleted file mode 100644
index 0ae57d2..0000000
--- a/core/res/res/drawable/fastscroll_track_quantum_dark.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/fastscroll_track_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_ab_back_quantum_dark.xml b/core/res/res/drawable/ic_ab_back_quantum.xml
index 628d53e..65c7584 100644
--- a/core/res/res/drawable/ic_ab_back_quantum_dark.xml
+++ b/core/res/res/drawable/ic_ab_back_quantum.xml
@@ -17,4 +17,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_ab_back_qntm_am_alpha"
android:autoMirrored="true"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_ab_back_quantum_light.xml b/core/res/res/drawable/ic_ab_back_quantum_light.xml
deleted file mode 100644
index 01f5362..0000000
--- a/core/res/res/drawable/ic_ab_back_quantum_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_ab_back_qntm_am_alpha"
- android:autoMirrored="true"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_cab_done_quantum_dark.xml b/core/res/res/drawable/ic_cab_done_quantum.xml
index 472996e..97495a8 100644
--- a/core/res/res/drawable/ic_cab_done_quantum_dark.xml
+++ b/core/res/res/drawable/ic_cab_done_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_cab_done_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_cab_done_quantum_light.xml b/core/res/res/drawable/ic_cab_done_quantum_light.xml
deleted file mode 100644
index d70a3f1..0000000
--- a/core/res/res/drawable/ic_cab_done_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_cab_done_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_dialog_alert_quantum_light.xml b/core/res/res/drawable/ic_dialog_alert_quantum.xml
index 8b8cb0c..05f3630 100644
--- a/core/res/res/drawable/ic_dialog_alert_quantum_light.xml
+++ b/core/res/res/drawable/ic_dialog_alert_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_dialog_alert_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml b/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml
deleted file mode 100644
index 8b8cb0c..0000000
--- a/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_dialog_alert_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_find_next_quantum_dark.xml b/core/res/res/drawable/ic_find_next_quantum.xml
index 929bea3..fee196c 100644
--- a/core/res/res/drawable/ic_find_next_quantum_dark.xml
+++ b/core/res/res/drawable/ic_find_next_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_find_next_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_next_quantum_light.xml b/core/res/res/drawable/ic_find_next_quantum_light.xml
deleted file mode 100644
index 9c20327..0000000
--- a/core/res/res/drawable/ic_find_next_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_find_next_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_find_previous_quantum_dark.xml b/core/res/res/drawable/ic_find_previous_quantum.xml
index e944223..28f887a 100644
--- a/core/res/res/drawable/ic_find_previous_quantum_dark.xml
+++ b/core/res/res/drawable/ic_find_previous_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_find_previous_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_find_previous_quantum_light.xml b/core/res/res/drawable/ic_find_previous_quantum_light.xml
deleted file mode 100644
index b037094..0000000
--- a/core/res/res/drawable/ic_find_previous_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_find_previous_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_copy_quantum_dark.xml b/core/res/res/drawable/ic_menu_copy_quantum.xml
index 285b752..5f6ce51 100644
--- a/core/res/res/drawable/ic_menu_copy_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_copy_quantum.xml
@@ -16,5 +16,5 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_copy_qntm_am_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark"
+ android:tint="?attr/colorControlNormal"
android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_copy_quantum_light.xml b/core/res/res/drawable/ic_menu_copy_quantum_light.xml
deleted file mode 100644
index a40b219..0000000
--- a/core/res/res/drawable/ic_menu_copy_quantum_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_copy_qntm_am_alpha"
- android:tint="@color/control_normal_foreground_quantum_light"
- android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_cut_quantum_dark.xml b/core/res/res/drawable/ic_menu_cut_quantum.xml
index 563400b..1e4996e 100644
--- a/core/res/res/drawable/ic_menu_cut_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_cut_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_cut_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_cut_quantum_light.xml b/core/res/res/drawable/ic_menu_cut_quantum_light.xml
deleted file mode 100644
index 36c9442..0000000
--- a/core/res/res/drawable/ic_menu_cut_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_cut_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_find_quantum_dark.xml b/core/res/res/drawable/ic_menu_find_quantum.xml
index 8803463..a69c673 100644
--- a/core/res/res/drawable/ic_menu_find_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_find_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_find_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_find_quantum_light.xml b/core/res/res/drawable/ic_menu_find_quantum_light.xml
deleted file mode 100644
index 9b3bd73..0000000
--- a/core/res/res/drawable/ic_menu_find_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_find_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml b/core/res/res/drawable/ic_menu_moreoverflow_quantum.xml
index 9f39a68..7d3fcac 100644
--- a/core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_moreoverflow_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml b/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml
deleted file mode 100644
index e15eaec..0000000
--- a/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_moreoverflow_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_paste_quantum_dark.xml b/core/res/res/drawable/ic_menu_paste_quantum.xml
index 7033404..f590904 100644
--- a/core/res/res/drawable/ic_menu_paste_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_paste_quantum.xml
@@ -16,5 +16,5 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_paste_qntm_am_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark"
+ android:tint="?attr/colorControlNormal"
android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_paste_quantum_light.xml b/core/res/res/drawable/ic_menu_paste_quantum_light.xml
deleted file mode 100644
index 155ec34..0000000
--- a/core/res/res/drawable/ic_menu_paste_quantum_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_paste_qntm_am_alpha"
- android:tint="@color/control_normal_foreground_quantum_light"
- android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_search_quantum_dark.xml b/core/res/res/drawable/ic_menu_search_quantum.xml
index 1c6efcd..2ca8c20 100644
--- a/core/res/res/drawable/ic_menu_search_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_search_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_search_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_search_quantum_light.xml b/core/res/res/drawable/ic_menu_search_quantum_light.xml
deleted file mode 100644
index ba6efb6..0000000
--- a/core/res/res/drawable/ic_menu_search_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_search_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_selectall_quantum_dark.xml b/core/res/res/drawable/ic_menu_selectall_quantum.xml
index c1d3e69..fd72ebf 100644
--- a/core/res/res/drawable/ic_menu_selectall_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_selectall_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_selectall_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_selectall_quantum_light.xml b/core/res/res/drawable/ic_menu_selectall_quantum_light.xml
deleted file mode 100644
index 4de8962..0000000
--- a/core/res/res/drawable/ic_menu_selectall_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_selectall_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_share_quantum_dark.xml b/core/res/res/drawable/ic_menu_share_quantum.xml
index a7c5afc..f44e06c 100644
--- a/core/res/res/drawable/ic_menu_share_quantum_dark.xml
+++ b/core/res/res/drawable/ic_menu_share_quantum.xml
@@ -16,4 +16,4 @@
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_share_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/ic_menu_share_quantum_light.xml b/core/res/res/drawable/ic_menu_share_quantum_light.xml
deleted file mode 100644
index 9257c25..0000000
--- a/core/res/res/drawable/ic_menu_share_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_menu_share_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/item_background_borderless_quantum_dark.xml b/core/res/res/drawable/item_background_quantum.xml
index 3f32850..f668ca0 100644
--- a/core/res/res/drawable/item_background_borderless_quantum_dark.xml
+++ b/core/res/res/drawable/item_background_quantum.xml
@@ -15,4 +15,4 @@
-->
<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/lighter_gray" />
+ android:tint="?attr/colorButtonPressed" />
diff --git a/core/res/res/drawable/item_background_quantum_dark.xml b/core/res/res/drawable/item_background_quantum_dark.xml
deleted file mode 100644
index 3f32850..0000000
--- a/core/res/res/drawable/item_background_quantum_dark.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/lighter_gray" />
diff --git a/core/res/res/drawable/list_divider_quantum_dark.xml b/core/res/res/drawable/list_divider_quantum.xml
index 9d05b2f..e3d4ba2 100644
--- a/core/res/res/drawable/list_divider_quantum_dark.xml
+++ b/core/res/res/drawable/list_divider_quantum.xml
@@ -16,4 +16,4 @@
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/list_divider_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/list_divider_quantum_light.xml b/core/res/res/drawable/list_divider_quantum_light.xml
deleted file mode 100644
index d312e2d..0000000
--- a/core/res/res/drawable/list_divider_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/list_divider_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/list_section_divider_quantum_dark.xml b/core/res/res/drawable/list_section_divider_quantum.xml
index 6344c7e..87a1439 100644
--- a/core/res/res/drawable/list_section_divider_quantum_dark.xml
+++ b/core/res/res/drawable/list_section_divider_quantum.xml
@@ -16,4 +16,4 @@
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/list_section_divider_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/list_section_divider_quantum_light.xml b/core/res/res/drawable/list_section_divider_quantum_light.xml
deleted file mode 100644
index 98ede38..0000000
--- a/core/res/res/drawable/list_section_divider_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/list_section_divider_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml b/core/res/res/drawable/notification_icon_legacy_bg.xml
index 4ac67c3..4ac67c3 100644
--- a/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml
+++ b/core/res/res/drawable/notification_icon_legacy_bg.xml
diff --git a/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml b/core/res/res/drawable/notification_icon_legacy_bg_inset.xml
index 96c5573..96c5573 100644
--- a/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml
+++ b/core/res/res/drawable/notification_icon_legacy_bg_inset.xml
diff --git a/core/res/res/drawable/notification_quantum_background.xml b/core/res/res/drawable/notification_quantum_background.xml
index f33e2e3..7b508a9 100644
--- a/core/res/res/drawable/notification_quantum_background.xml
+++ b/core/res/res/drawable/notification_quantum_background.xml
@@ -17,5 +17,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff" />
- <corners android:radius="2dp" />
+ <corners android:radius="@dimen/notification_quantum_rounded_rect_radius" />
</shape> \ No newline at end of file
diff --git a/core/res/res/drawable/progress_horizontal_quantum_dark.xml b/core/res/res/drawable/progress_horizontal_quantum.xml
index fb4b67e..1c2d494 100644
--- a/core/res/res/drawable/progress_horizontal_quantum_dark.xml
+++ b/core/res/res/drawable/progress_horizontal_quantum.xml
@@ -17,18 +17,18 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@id/background">
<nine-patch android:src="@drawable/progress_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
<item android:id="@id/secondaryProgress">
<scale android:scaleWidth="100%">
<nine-patch android:src="@drawable/progress_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</scale>
</item>
<item android:id="@id/progress">
<scale android:scaleWidth="100%">
<nine-patch android:src="@drawable/progress_primary_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</scale>
</item>
</layer-list>
diff --git a/core/res/res/drawable/progress_horizontal_quantum_light.xml b/core/res/res/drawable/progress_horizontal_quantum_light.xml
deleted file mode 100644
index 1ceb2e2..0000000
--- a/core/res/res/drawable/progress_horizontal_quantum_light.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@id/background">
- <nine-patch android:src="@drawable/progress_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
- <item android:id="@id/secondaryProgress">
- <scale android:scaleWidth="100%">
- <nine-patch android:src="@drawable/progress_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </scale>
- </item>
- <item android:id="@id/progress">
- <scale android:scaleWidth="100%">
- <nine-patch android:src="@drawable/progress_primary_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </scale>
- </item>
-</layer-list>
diff --git a/core/res/res/drawable/scrollbar_handle_quantum_dark.xml b/core/res/res/drawable/scrollbar_handle_quantum.xml
index 2d4e37d..f2de252 100644
--- a/core/res/res/drawable/scrollbar_handle_quantum_dark.xml
+++ b/core/res/res/drawable/scrollbar_handle_quantum.xml
@@ -16,4 +16,4 @@
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/scrollbar_handle_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/drawable/scrollbar_handle_quantum_light.xml b/core/res/res/drawable/scrollbar_handle_quantum_light.xml
deleted file mode 100644
index d4d4b8d..0000000
--- a/core/res/res/drawable/scrollbar_handle_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/scrollbar_handle_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml b/core/res/res/drawable/scrubber_control_selector_quantum.xml
index 521bcca..e31c2c1 100644
--- a/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml
+++ b/core/res/res/drawable/scrubber_control_selector_quantum.xml
@@ -17,10 +17,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
<bitmap android:src="@drawable/scrubber_control_on_pressed_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<bitmap android:src="@drawable/scrubber_control_on_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/scrubber_control_selector_quantum_light.xml b/core/res/res/drawable/scrubber_control_selector_quantum_light.xml
deleted file mode 100644
index 8d009b7..0000000
--- a/core/res/res/drawable/scrubber_control_selector_quantum_light.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="true" android:state_pressed="true">
- <bitmap android:src="@drawable/scrubber_control_on_pressed_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <bitmap android:src="@drawable/scrubber_control_on_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml b/core/res/res/drawable/scrubber_progress_horizontal_quantum.xml
index fa0d631..7b124ac 100644
--- a/core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml
+++ b/core/res/res/drawable/scrubber_progress_horizontal_quantum.xml
@@ -17,10 +17,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml b/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml
deleted file mode 100644
index 053f542..0000000
--- a/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true">
- <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/spinner_background_quantum_dark.xml b/core/res/res/drawable/spinner_background_quantum.xml
index d1e7407..727a78f 100644
--- a/core/res/res/drawable/spinner_background_quantum_dark.xml
+++ b/core/res/res/drawable/spinner_background_quantum.xml
@@ -18,14 +18,14 @@
android:autoMirrored="true">
<item android:state_checked="true">
<nine-patch android:src="@drawable/spinner_qntm_am_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_pressed="true">
<nine-patch android:src="@drawable/spinner_qntm_am_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<nine-patch android:src="@drawable/spinner_qntm_am_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/spinner_background_quantum_light.xml b/core/res/res/drawable/spinner_background_quantum_light.xml
deleted file mode 100644
index b01628d..0000000
--- a/core/res/res/drawable/spinner_background_quantum_light.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- android:autoMirrored="true">
- <item android:state_checked="true">
- <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_pressed="true">
- <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/switch_inner_quantum_dark.xml b/core/res/res/drawable/switch_inner_quantum.xml
index 927a55e..915377e 100644
--- a/core/res/res/drawable/switch_inner_quantum_dark.xml
+++ b/core/res/res/drawable/switch_inner_quantum.xml
@@ -17,18 +17,18 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:state_pressed="true">
<nine-patch android:src="@drawable/switch_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_checked="true">
<nine-patch android:src="@drawable/switch_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_pressed="true">
<nine-patch android:src="@drawable/switch_off_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<nine-patch android:src="@drawable/switch_off_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/switch_inner_quantum_light.xml b/core/res/res/drawable/switch_inner_quantum_light.xml
deleted file mode 100644
index b5aa47b..0000000
--- a/core/res/res/drawable/switch_inner_quantum_light.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:state_pressed="true">
- <nine-patch android:src="@drawable/switch_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_checked="true">
- <nine-patch android:src="@drawable/switch_on_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_pressed="true">
- <nine-patch android:src="@drawable/switch_off_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <nine-patch android:src="@drawable/switch_off_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/switch_track_quantum_dark.xml b/core/res/res/drawable/switch_track_quantum.xml
index c018bd2..8c4e6b71 100644
--- a/core/res/res/drawable/switch_track_quantum_dark.xml
+++ b/core/res/res/drawable/switch_track_quantum.xml
@@ -17,10 +17,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<nine-patch android:src="@drawable/switch_track_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<nine-patch android:src="@drawable/switch_track_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/switch_track_quantum_light.xml b/core/res/res/drawable/switch_track_quantum_light.xml
deleted file mode 100644
index ab87a57..0000000
--- a/core/res/res/drawable/switch_track_quantum_light.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true">
- <nine-patch android:src="@drawable/switch_track_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <nine-patch android:src="@drawable/switch_track_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/tab_indicator_quantum_dark.xml b/core/res/res/drawable/tab_indicator_quantum.xml
index 9b57c33..6fabe23 100644
--- a/core/res/res/drawable/tab_indicator_quantum_dark.xml
+++ b/core/res/res/drawable/tab_indicator_quantum.xml
@@ -17,27 +17,27 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_pressed="true">
<nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_selected="true" android:state_focused="true">
<nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_selected="true">
<nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
<item android:state_pressed="true">
<nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item android:state_focused="true">
<nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
</item>
<item>
<nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_dark" />
+ android:tint="?attr/colorControlNormal" />
</item>
</selector>
diff --git a/core/res/res/drawable/tab_indicator_quantum_light.xml b/core/res/res/drawable/tab_indicator_quantum_light.xml
deleted file mode 100644
index 371322a..0000000
--- a/core/res/res/drawable/tab_indicator_quantum_light.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_selected="true" android:state_pressed="true">
- <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_selected="true" android:state_focused="true">
- <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_selected="true">
- <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-
- <item android:state_pressed="true">
- <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item android:state_focused="true">
- <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
- </item>
- <item>
- <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="@color/control_normal_foreground_quantum_light" />
- </item>
-</selector>
diff --git a/core/res/res/drawable/text_cursor_quantum_dark.xml b/core/res/res/drawable/text_cursor_quantum.xml
index bd0d66f..23d4ae0 100644
--- a/core/res/res/drawable/text_cursor_quantum_dark.xml
+++ b/core/res/res/drawable/text_cursor_quantum.xml
@@ -16,4 +16,4 @@
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/text_cursor_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_dark" />
+ android:tint="?attr/colorControlActivated" />
diff --git a/core/res/res/drawable/text_cursor_quantum_light.xml b/core/res/res/drawable/text_cursor_quantum_light.xml
deleted file mode 100644
index 0ec7f01..0000000
--- a/core/res/res/drawable/text_cursor_quantum_light.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/text_cursor_qntm_alpha"
- android:tint="@color/control_activated_foreground_quantum_light" />
diff --git a/core/res/res/layout/notification_quantum_action.xml b/core/res/res/layout/notification_quantum_action.xml
index 775182f..0986343 100644
--- a/core/res/res/layout/notification_quantum_action.xml
+++ b/core/res/res/layout/notification_quantum_action.xml
@@ -16,7 +16,7 @@
-->
<Button xmlns:android="http://schemas.android.com/apk/res/android"
- style="?android:attr/borderlessButtonStyle"
+ style="@android:style/Widget.Quantum.Light.Button.Borderless.Small"
android:id="@+id/action0"
android:layout_width="0dp"
android:layout_height="48dp"
diff --git a/core/res/res/layout/notification_quantum_action_list.xml b/core/res/res/layout/notification_quantum_action_list.xml
index a8aef97..ec4919b 100644
--- a/core/res/res/layout/notification_quantum_action_list.xml
+++ b/core/res/res/layout/notification_quantum_action_list.xml
@@ -23,7 +23,7 @@
android:visibility="gone"
android:layout_marginBottom="8dp"
android:showDividers="middle"
- android:divider="?android:attr/listDivider"
+ android:divider="@drawable/list_divider_holo_light"
android:dividerPadding="12dp"
>
<!-- actions will be added here -->
diff --git a/core/res/res/layout/notification_quantum_action_tombstone.xml b/core/res/res/layout/notification_quantum_action_tombstone.xml
index 9104991..51e4205 100644
--- a/core/res/res/layout/notification_quantum_action_tombstone.xml
+++ b/core/res/res/layout/notification_quantum_action_tombstone.xml
@@ -16,7 +16,7 @@
-->
<Button xmlns:android="http://schemas.android.com/apk/res/android"
- style="?android:attr/borderlessButtonStyle"
+ style="@android:style/Widget.Quantum.Light.Button.Borderless.Small"
android:id="@+id/action0"
android:layout_width="0dp"
android:layout_height="48dp"
diff --git a/core/res/res/layout/notification_template_quantum_base.xml b/core/res/res/layout/notification_template_quantum_base.xml
index 3e97b2a..8863cfa 100644
--- a/core/res/res/layout/notification_template_quantum_base.xml
+++ b/core/res/res/layout/notification_template_quantum_base.xml
@@ -92,7 +92,7 @@
android:layout_height="12dp"
android:layout_marginStart="8dp"
android:visibility="gone"
- style="?android:attr/progressBarStyleHorizontal"
+ style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
/>
<LinearLayout
android:id="@+id/line3"
diff --git a/core/res/res/layout/notification_template_quantum_big_base.xml b/core/res/res/layout/notification_template_quantum_big_base.xml
index d860045..63935bb 100644
--- a/core/res/res/layout/notification_template_quantum_big_base.xml
+++ b/core/res/res/layout/notification_template_quantum_big_base.xml
@@ -148,7 +148,7 @@
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:visibility="gone"
- style="?android:attr/progressBarStyleHorizontal"
+ style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
/>
</LinearLayout>
<ImageView
@@ -156,7 +156,7 @@
android:layout_height="1dp"
android:id="@+id/action_divider"
android:visibility="gone"
- android:background="?android:attr/dividerHorizontal" />
+ android:background="@drawable/list_divider_holo_light" />
<include
layout="@layout/notification_quantum_action_list"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_template_quantum_big_text.xml b/core/res/res/layout/notification_template_quantum_big_text.xml
index 585be80..516b0c4 100644
--- a/core/res/res/layout/notification_template_quantum_big_text.xml
+++ b/core/res/res/layout/notification_template_quantum_big_text.xml
@@ -101,7 +101,7 @@
android:layout_marginEnd="8dp"
android:visibility="gone"
android:layout_weight="0"
- style="?android:attr/progressBarStyleHorizontal"
+ style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
/>
<TextView android:id="@+id/big_text"
android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
@@ -121,7 +121,7 @@
android:layout_height="1dip"
android:id="@+id/action_divider"
android:visibility="gone"
- android:background="?android:attr/dividerHorizontal" />
+ android:background="@drawable/list_divider_holo_light" />
<include
layout="@layout/notification_quantum_action_list"
android:layout_width="match_parent"
@@ -135,7 +135,7 @@
android:id="@+id/overflow_divider"
android:layout_marginBottom="8dp"
android:visibility="visible"
- android:background="?android:attr/dividerHorizontal" />
+ android:background="@drawable/list_divider_holo_light" />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_template_quantum_inbox.xml b/core/res/res/layout/notification_template_quantum_inbox.xml
index 31ed508..c6192be 100644
--- a/core/res/res/layout/notification_template_quantum_inbox.xml
+++ b/core/res/res/layout/notification_template_quantum_inbox.xml
@@ -103,7 +103,7 @@
android:layout_marginEnd="8dp"
android:visibility="gone"
android:layout_weight="0"
- style="?android:attr/progressBarStyleHorizontal"
+ style="@style/Widget.Quantum.Light.ProgressBar.Horizontal"
/>
<TextView android:id="@+id/inbox_text0"
android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
@@ -206,7 +206,7 @@
android:layout_height="1dip"
android:id="@+id/action_divider"
android:visibility="gone"
- android:background="?android:attr/dividerHorizontal" />
+ android:background="@drawable/list_divider_holo_light" />
<include
layout="@layout/notification_quantum_action_list"
android:layout_width="match_parent"
@@ -218,7 +218,7 @@
android:layout_height="1dip"
android:id="@+id/overflow_divider"
android:visibility="visible"
- android:background="?android:attr/dividerHorizontal" />
+ android:background="@drawable/list_divider_holo_light" />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4d272ee..df7cde7 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -910,6 +910,16 @@
<!-- Drawable for WebView find-on-page dialogue's "previous" button. @hide -->
<attr name="findOnPagePreviousDrawable" format="reference" />
+ <!-- ============= -->
+ <!-- Color palette -->
+ <!-- ============= -->
+ <attr name="colorControlNormal" format="color" />
+ <attr name="colorControlActivated" format="color" />
+ <attr name="colorButtonNormal" format="color" />
+ <attr name="colorButtonPressed" format="color" />
+ <attr name="colorButtonNormalColored" format="color" />
+ <attr name="colorButtonPressedColored" format="color" />
+
</declare-styleable>
<!-- **************************************************************** -->
@@ -4426,16 +4436,12 @@
<!-- Drawable used to show animated touch feedback. -->
<declare-styleable name="TouchFeedbackDrawable">
- <!-- The tint to use for feedback ripples. This attribute is mandatory. -->
+ <!-- The tint to use for feedback ripples. This attribute is required. -->
<attr name="tint" />
<!-- Specifies the Porter-Duff blending mode used to apply the tint. The default vlaue is src_atop, which draws over the opaque parts of the drawable. -->
<attr name="tintMode" />
<!-- Whether to pin feedback ripples to the center of the drawable. Default value is false. -->
<attr name="pinned" format="boolean" />
- <!-- Optional drawable used to mask ripple bounds before projection. -->
- <attr name="mask" format="reference" />
- <!-- Optional drawable onto which ripples are projected. -->
- <attr name="drawable" />
</declare-styleable>
<declare-styleable name="ScaleDrawable">
@@ -4531,6 +4537,145 @@
</declare-styleable>
<!-- ========================== -->
+ <!-- Vector drawable class -->
+ <!-- ========================== -->
+ <eat-comment />
+
+ <!-- Drawable used to draw Vector Drawables. -->
+ <declare-styleable name="VectorDrawable">
+ <!-- What event triggers the animation -->
+ <attr name="trigger" format="enum">
+ <enum name="state_pressed" value="1" />
+ <enum name="state_focused" value="2" />
+ <enum name="state_hovered" value="3" />
+ <enum name="state_selected" value="4" />
+ <enum name="state_checkable" value="5" />
+ <enum name="state_checked" value="6" />
+ <enum name="state_enabled" value="7" />
+ <enum name="state_activated" value="8" />
+ <enum name="state_window_focused" value="9" />
+ </attr>
+ </declare-styleable>
+
+ <!-- Define the virtual size of the drawing surface paths will draw to. -->
+ <declare-styleable name="VectorDrawableViewport">
+ <!-- The width of the canvas the drawing is on. -->
+ <attr name="viewportWidth" format="float"/>
+ <!-- The height of the canvas the drawing is on. -->
+ <attr name="viewportHeight" format="float"/>
+ </declare-styleable>
+
+ <!-- Define the size of the drawable -->
+ <declare-styleable name="VectorDrawableSize">
+ <!-- Width of the Vector Drawable. -->
+ <attr name="width" />
+ <!-- Height of the Vector Drawable. -->
+ <attr name="height" />
+ </declare-styleable>
+
+ <!-- Define the animations of drawable -->
+ <declare-styleable name="VectorDrawableAnimation">
+ <!-- Configures this animation sequence between the named paths -->
+ <attr name="sequence" format="string"/>
+ <!-- Limits an animation to only interpolate the selected variable -->
+ <attr name="limitTo" format="enum">
+ <enum name="unlimited" value="0"/>
+ <enum name="path" value="1"/>
+ <enum name="rotation" value="2"/>
+ <enum name="trimPathStart" value="3"/>
+ <enum name="trimPathEnd" value="4"/>
+ <enum name="trimPathOffset" value="5"/>
+ </attr>
+ <!-- Number of times to loop this aspect of the animation -->
+ <attr name="repeatCount"/>
+ <!-- A list of times in milliseconds to transision from on path to another.
+ List must contain one less than the number of named paths
+ e.g. given sequence="A,B,C,D" durations="100,0,100" implies 100ms for the
+ "A" to "B" transision instantanious switch to "C" and 100ms for "C" to "D". -->
+ <attr name="durations" format="string" />
+ <!-- The delay before stating this aspect of the animation in milli seconds -->
+ <attr name="startDelay" />
+ <!-- when repeating how does it repeat back and forth or a to b -->
+ <attr name="repeatStyle" format="enum">
+ <enum name="forward" value="0"/>
+ <enum name="reverse" value="1"/>[]
+ </attr>
+ <!-- how does the animation progress from start to finish -->
+ <attr name="animate" format="enum">
+ <enum name="linear" value="0"/>
+ <enum name="easeIn" value="1"/>
+ <enum name="easeOut" value="2"/>
+ <enum name="easeInOut" value="3"/>
+ </attr>
+ </declare-styleable>
+
+ <!-- Defines the path used in Vector Drawables. -->
+ <declare-styleable name="VectorDrawablePath">
+ <!-- The Name of this path -->
+ <attr name="name" />
+ <!-- The width a path stroke -->
+ <attr name="strokeWidth" format="float" />
+ <!-- The opacity of a path stroke -->
+ <attr name="strokeOpacity" format="float" />
+ <!-- The amount to rotate the path stroke -->
+ <attr name="rotation" />
+ <!-- The X coordinate of the center of rotation of a path -->
+ <attr name="pivotX" />
+ <!-- The Y coordinate of the center of rotation of a path -->
+ <attr name="pivotY" />
+ <!-- The color to stroke the path if not defined implies no stroke-->
+ <attr name="stroke" format="color" />
+ <!-- The color to fill the path if not defined implies no fill-->
+ <attr name="fill" format="color" />
+ <!-- The level of opacity of the filled area of the path -->
+ <attr name="fillOpacity" format="float" />
+ <!-- The specification of the operations that define the path -->
+ <attr name="pathData" format="string" />
+ <!-- The fraction of the path to trim from the start from 0 to 1 -->
+ <attr name="trimPathStart" format="float" />
+ <!-- The fraction of the path to trim from the end from 0 to 1 -->
+ <attr name="trimPathEnd" format="float" />
+ <!-- Shift trim region (allows visible region to include the start and end) from 0 to 1 -->
+ <attr name="trimPathOffset" format="float" />
+ <!-- Path will set the current clip path -->
+ <attr name="clipToPath" format="boolean" />
+ <!-- sets the linecap for a stroked path -->
+ <attr name="strokeLineCap" format="enum">
+ <enum name="butt" value="0"/>
+ <enum name="round" value="1"/>
+ <enum name="square" value="2"/>
+ </attr>
+ <!-- sets the lineJoin for a stroked path -->
+ <attr name="strokeLineJoin" format="enum">
+ <enum name="miter" value="0"/>
+ <enum name="round" value="1"/>
+ <enum name="bevel" value="2"/>
+ </attr>
+ <!-- sets the Miter limit for a stroked path -->
+ <attr name="strokeMiterLimit" format="float"/>
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_pressed" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_focused" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_selected" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_window_focused" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_enabled" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_activated" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_accelerated" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_hovered" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_checked" />
+ <!-- sets a condition to be met to draw path -->
+ <attr name="state_checkable" />
+ </declare-styleable>
+
+ <!-- ========================== -->
<!-- Animation class attributes -->
<!-- ========================== -->
<eat-comment />
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 1947c50..d0c455b 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -193,6 +193,9 @@
<drawable name="notification_template_icon_bg">#3333B5E5</drawable>
<drawable name="notification_template_icon_low_bg">#0cffffff</drawable>
+ <color name="notification_icon_legacy_bg_color">#ff4285F4</color>
+ <color name="notification_action_legacy_color_filter">#ff555555</color>
+
<!-- Keyguard colors -->
<color name="keyguard_avatar_frame_color">#ffffffff</color>
<color name="keyguard_avatar_frame_shadow_color">#80000000</color>
diff --git a/core/res/res/values/colors_quantum.xml b/core/res/res/values/colors_quantum.xml
index c8083f4..d10f7c0 100644
--- a/core/res/res/values/colors_quantum.xml
+++ b/core/res/res/values/colors_quantum.xml
@@ -148,13 +148,13 @@
<!-- Text & foreground colors -->
- <color name="primary_text_quantum_light">#ff000000</color>
- <color name="secondary_text_quantum_light">#de000000</color>
- <color name="tertiary_text_quantum_light">#8a000000</color>
+ <color name="primary_text_quantum_light">#de000000</color>
+ <color name="secondary_text_quantum_light">#8a000000</color>
+ <color name="tertiary_text_quantum_light">#4d000000</color>
- <color name="primary_text_quantum_dark">#ffffffff</color>
- <color name="secondary_text_quantum_dark">#deffffff</color>
- <color name="tertiary_text_quantum_dark">#8affffff</color>
+ <color name="primary_text_quantum_dark">#deffffff</color>
+ <color name="secondary_text_quantum_dark">#8affffff</color>
+ <color name="tertiary_text_quantum_dark">#4dffffff</color>
<!-- "Theme" colors to be replaced by attrs when available -->
<color name="theme_color_100">@color/quantum_teal_100</color>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 8ec2e6f..94123a2 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -366,4 +366,7 @@
<!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
<dimen name="immersive_mode_cling_width">-1px</dimen>
+ <!-- radius of the corners of the quantum rounded rect background -->
+ <dimen name="notification_quantum_rounded_rect_radius">2dp</dimen>
+
</resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 56bb15f..a79e1fe 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -83,4 +83,5 @@
<item type="id" name="current_scene" />
<item type="id" name="scene_layoutid_cache" />
<item type="id" name="shared_element_name" />
+ <item type="id" name="mask" />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 64cdc05..d49980f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2101,6 +2101,8 @@
=============================================================== -->
<eat-comment />
+ <public-padding type="attr" name="l_resource_pad" end="0x1010410" />
+
<public type="attr" name="fragmentBreadCrumbsStyle" />
<public type="attr" name="fastScrollStyle" />
<public type="attr" name="windowContentTransitions" />
@@ -2113,13 +2115,45 @@
<public type="attr" name="controlY2" />
<public type="attr" name="sharedElementName" />
<public type="attr" name="transitionGroup" />
+ <public type="attr" name="trigger" />
+ <public type="attr" name="viewportWidth" />
+ <public type="attr" name="viewportHeight" />
+ <public type="attr" name="fillOpacity" />
+ <public type="attr" name="fill" />
+ <public type="attr" name="pathData" />
+ <public type="attr" name="stroke" />
+ <public type="attr" name="strokeOpacity" />
+ <public type="attr" name="strokeWidth" />
+ <public type="attr" name="durations" />
+ <public type="attr" name="sequence" />
+ <public type="attr" name="repeatStyle" />
+ <public type="attr" name="trimPathStart" />
+ <public type="attr" name="trimPathEnd" />
+ <public type="attr" name="trimPathOffset" />
+ <public type="attr" name="strokeLineCap" />
+ <public type="attr" name="clipToPath" />
+ <public type="attr" name="animate" />
+ <public type="attr" name="limitTo" />
<public type="attr" name="requiredForProfile"/>
<public type="attr" name="pinned" />
+ <public type="attr" name="colorControlNormal" />
+ <public type="attr" name="colorControlActivated" />
+ <public type="attr" name="colorButtonNormal" />
+ <public type="attr" name="colorButtonPressed" />
+ <public type="attr" name="colorButtonNormalColored" />
+ <public type="attr" name="colorButtonPressedColored" />
+
+ <public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
<public type="dimen" name="recents_thumbnail_height" />
<public type="dimen" name="recents_thumbnail_width" />
+ <public-padding type="id" name="l_resource_pad" end="0x01020040" />
+
<public type="id" name="shared_element_name" />
+ <public type="id" name="mask" />
+
+ <public-padding type="style" name="l_resource_pad" end="0x01030200" />
<public type="style" name="Widget.Holo.FragmentBreadCrumbs" />
<public type="style" name="Widget.Holo.Light.FragmentBreadCrumbs" />
@@ -2147,13 +2181,9 @@
<public type="style" name="TextAppearance.Quantum.Widget" />
<public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Menu" />
<public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" />
- <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" />
<public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title" />
- <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" />
<public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" />
- <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" />
<public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title" />
- <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" />
<public type="style" name="TextAppearance.Quantum.Widget.Button" />
<public type="style" name="TextAppearance.Quantum.Widget.DropDownHint" />
<public type="style" name="TextAppearance.Quantum.Widget.DropDownItem" />
@@ -2215,6 +2245,8 @@
<public type="style" name="Widget.Quantum.Button.Inset" />
<public type="style" name="Widget.Quantum.Button.Small" />
<public type="style" name="Widget.Quantum.Button.Toggle" />
+ <public type="style" name="Widget.Quantum.ButtonBar" />
+ <public type="style" name="Widget.Quantum.ButtonBar.AlertDialog" />
<public type="style" name="Widget.Quantum.CalendarView" />
<public type="style" name="Widget.Quantum.CheckedTextView" />
<public type="style" name="Widget.Quantum.CompoundButton.CheckBox" />
@@ -2246,6 +2278,7 @@
<public type="style" name="Widget.Quantum.RatingBar.Small" />
<public type="style" name="Widget.Quantum.ScrollView" />
<public type="style" name="Widget.Quantum.SeekBar" />
+ <public type="style" name="Widget.Quantum.SegmentedButton" />
<public type="style" name="Widget.Quantum.Spinner" />
<public type="style" name="Widget.Quantum.Tab" />
<public type="style" name="Widget.Quantum.TabWidget" />
@@ -2257,17 +2290,12 @@
<public type="style" name="Widget.Quantum.Light" />
<public type="style" name="Widget.Quantum.Light.ActionBar" />
<public type="style" name="Widget.Quantum.Light.ActionBar.Solid" />
- <public type="style" name="Widget.Quantum.Light.ActionBar.Solid.Inverse" />
<public type="style" name="Widget.Quantum.Light.ActionBar.TabBar" />
- <public type="style" name="Widget.Quantum.Light.ActionBar.TabBar.Inverse" />
<public type="style" name="Widget.Quantum.Light.ActionBar.TabText" />
- <public type="style" name="Widget.Quantum.Light.ActionBar.TabText.Inverse" />
<public type="style" name="Widget.Quantum.Light.ActionBar.TabView" />
- <public type="style" name="Widget.Quantum.Light.ActionBar.TabView.Inverse" />
<public type="style" name="Widget.Quantum.Light.ActionButton" />
<public type="style" name="Widget.Quantum.Light.ActionButton.CloseMode" />
<public type="style" name="Widget.Quantum.Light.ActionButton.Overflow" />
- <public type="style" name="Widget.Quantum.Light.ActionMode.Inverse" />
<public type="style" name="Widget.Quantum.Light.ActionMode" />
<public type="style" name="Widget.Quantum.Light.AutoCompleteTextView" />
<public type="style" name="Widget.Quantum.Light.Button" />
@@ -2275,6 +2303,8 @@
<public type="style" name="Widget.Quantum.Light.Button.Inset" />
<public type="style" name="Widget.Quantum.Light.Button.Small" />
<public type="style" name="Widget.Quantum.Light.Button.Toggle" />
+ <public type="style" name="Widget.Quantum.Light.ButtonBar" />
+ <public type="style" name="Widget.Quantum.Light.ButtonBar.AlertDialog" />
<public type="style" name="Widget.Quantum.Light.CalendarView" />
<public type="style" name="Widget.Quantum.Light.CheckedTextView" />
<public type="style" name="Widget.Quantum.Light.CompoundButton.CheckBox" />
@@ -2308,6 +2338,7 @@
<public type="style" name="Widget.Quantum.Light.RatingBar.Small" />
<public type="style" name="Widget.Quantum.Light.ScrollView" />
<public type="style" name="Widget.Quantum.Light.SeekBar" />
+ <public type="style" name="Widget.Quantum.Light.SegmentedButton" />
<public type="style" name="Widget.Quantum.Light.Spinner" />
<public type="style" name="Widget.Quantum.Light.Tab" />
<public type="style" name="Widget.Quantum.Light.TabWidget" />
@@ -2316,17 +2347,22 @@
<public type="style" name="Widget.Quantum.Light.WebTextView" />
<public type="style" name="Widget.Quantum.Light.WebView" />
- <public type="style" name="Quantum.ButtonBar.AlertDialog" />
- <public type="style" name="Quantum.ButtonBar" />
- <public type="style" name="Quantum.SegmentedButton" />
-
- <public type="style" name="Quantum.Light.ButtonBar.AlertDialog" />
- <public type="style" name="Quantum.Light.ButtonBar" />
- <public type="style" name="Quantum.Light.SegmentedButton" />
-
<public type="style" name="Widget.Quantum.Button.Paper" />
<public type="style" name="Widget.Quantum.Button.Paper.Color" />
<public type="style" name="Widget.Quantum.Light.Button.Paper" />
<public type="style" name="Widget.Quantum.Light.Button.Paper.Color" />
+
+ <public type="style" name="TextAppearance.Quantum.Display4" />
+ <public type="style" name="TextAppearance.Quantum.Display3" />
+ <public type="style" name="TextAppearance.Quantum.Display2" />
+ <public type="style" name="TextAppearance.Quantum.Display1" />
+ <public type="style" name="TextAppearance.Quantum.Headline" />
+ <public type="style" name="TextAppearance.Quantum.Title" />
+ <public type="style" name="TextAppearance.Quantum.Subhead" />
+ <public type="style" name="TextAppearance.Quantum.Body2" />
+ <public type="style" name="TextAppearance.Quantum.Body1" />
+ <public type="style" name="TextAppearance.Quantum.Caption" />
+ <public type="style" name="TextAppearance.Quantum.Menu" />
+ <public type="style" name="TextAppearance.Quantum.Button" />
</resources>
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index 44cdb5f..2020fea 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -30,7 +30,7 @@ please see styles_device_defaults.xml.
-->
<resources>
<!-- Preference styles -->
- <eat-comment />
+ <eat-comment/>
<style name="Preference.Quantum">
<item name="layout">@layout/preference_holo</item>
@@ -90,16 +90,98 @@ please see styles_device_defaults.xml.
<!-- Text styles -->
- <style name="TextAppearance.Quantum" parent="TextAppearance"/>
+ <style name="TextAppearance.Quantum">
+ <item name="textColor">?textColorPrimary</item>
+ <item name="textColorHint">?textColorHint</item>
+ <item name="textColorHighlight">?textColorHighlight</item>
+ <item name="textColorLink">?textColorLink</item>
+ <item name="textSize">@dimen/text_size_body_1_quantum</item>
+ <item name="fontFamily">@string/font_family_body_1_quantum</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Display4">
+ <item name="textSize">@dimen/text_size_display_4_quantum</item>
+ <item name="fontFamily">@string/font_family_display_4_quantum</item>
+ <item name="textColor">?textColorSecondary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Display3">
+ <item name="textSize">@dimen/text_size_display_3_quantum</item>
+ <item name="fontFamily">@string/font_family_display_3_quantum</item>
+ <item name="textColor">?textColorSecondary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Display2">
+ <item name="textSize">@dimen/text_size_display_2_quantum</item>
+ <item name="fontFamily">@string/font_family_display_2_quantum</item>
+ <item name="textColor">?textColorSecondary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Display1">
+ <item name="textSize">@dimen/text_size_display_1_quantum</item>
+ <item name="fontFamily">@string/font_family_display_1_quantum</item>
+ <item name="textColor">?textColorSecondary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Headline">
+ <item name="textSize">@dimen/text_size_headline_quantum</item>
+ <item name="fontFamily">@string/font_family_headline_quantum</item>
+ <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Title">
+ <item name="textSize">@dimen/text_size_title_quantum</item>
+ <item name="fontFamily">@string/font_family_title_quantum</item>
+ <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Subhead">
+ <item name="textSize">@dimen/text_size_subhead_quantum</item>
+ <item name="fontFamily">@string/font_family_subhead_quantum</item>
+ <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Body2">
+ <item name="textSize">@dimen/text_size_body_2_quantum</item>
+ <item name="fontFamily">@string/font_family_body_2_quantum</item>
+ <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Body1">
+ <item name="textSize">@dimen/text_size_body_1_quantum</item>
+ <item name="fontFamily">@string/font_family_body_1_quantum</item>
+ <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Caption">
+ <item name="textSize">@dimen/text_size_caption_quantum</item>
+ <item name="fontFamily">@string/font_family_caption_quantum</item>
+ <item name="textColor">?textColorSecondary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Menu">
+ <item name="textSize">@dimen/text_size_menu_quantum</item>
+ <item name="fontFamily">@string/font_family_menu_quantum</item>
+ <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Button">
+ <item name="textSize">@dimen/text_size_button_quantum</item>
+ <item name="fontFamily">@string/font_family_button_quantum</item>
+ <item name="textAllCaps">true</item>
+ <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <!-- Deprecated text styles -->
- <style name="TextAppearance.Quantum.Inverse" parent="TextAppearance.Inverse">
+ <style name="TextAppearance.Quantum.Inverse">
<item name="textColor">?attr/textColorPrimaryInverse</item>
<item name="textColorHint">?attr/textColorHintInverse</item>
<item name="textColorHighlight">?attr/textColorHighlightInverse</item>
<item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
- <style name="TextAppearance.Quantum.Large" parent="TextAppearance.Large"/>
+ <style name="TextAppearance.Quantum.Large" parent="TextAppearance.Quantum.Headline" />
<style name="TextAppearance.Quantum.Large.Inverse">
<item name="textColor">?attr/textColorPrimaryInverse</item>
@@ -108,7 +190,7 @@ please see styles_device_defaults.xml.
<item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
- <style name="TextAppearance.Quantum.Medium" parent="TextAppearance.Medium"/>
+ <style name="TextAppearance.Quantum.Medium" parent="TextAppearance.Quantum.Body1" />
<style name="TextAppearance.Quantum.Medium.Inverse">
<item name="textColor">?attr/textColorSecondaryInverse</item>
@@ -117,65 +199,50 @@ please see styles_device_defaults.xml.
<item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
- <style name="TextAppearance.Quantum.Small" parent="TextAppearance.Small"/>
+ <style name="TextAppearance.Quantum.Small" parent="TextAppearance.Quantum.Caption" />
<style name="TextAppearance.Quantum.Small.Inverse">
- <item name="textColor">?attr/textColorSecondaryInverse</item>
+ <item name="textColor">?attr/textColorTertiaryInverse</item>
<item name="textColorHint">?attr/textColorHintInverse</item>
<item name="textColorHighlight">?attr/textColorHighlightInverse</item>
<item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
<style name="TextAppearance.Quantum.SearchResult">
- <item name="textStyle">normal</item>
- <item name="textColor">?attr/textColorPrimary</item>
- <item name="textColorHint">?attr/textColorHint</item>
- </style>
-
- <style name="TextAppearance.Quantum.SearchResult.Title">
- <item name="textSize">18sp</item>
</style>
- <style name="TextAppearance.Quantum.SearchResult.Subtitle">
- <item name="textSize">14sp</item>
- <item name="textColor">?attr/textColorSecondary</item>
- </style>
+ <style name="TextAppearance.Quantum.SearchResult.Title" parent="TextAppearance.Quantum.Title" />
+ <style name="TextAppearance.Quantum.SearchResult.Subtitle" parent="TextAppearance.Quantum.Subhead" />
- <style name="TextAppearance.Quantum.Widget" parent="TextAppearance.Widget"/>
-
- <style name="TextAppearance.Quantum.Widget.Button">
- <item name="fontFamily">@string/font_family_button_quantum</item>
- <item name="textSize">@dimen/text_size_button_quantum</item>
- <item name="textAllCaps">true</item>
- <item name="textColor">?attr/textColorPrimary</item>
- <item name="textStyle">normal</item>
- </style>
+ <style name="TextAppearance.Quantum.Widget"/>
+ <style name="TextAppearance.Quantum.Widget.Button" parent="TextAppearance.Quantum.Button" />
<style name="TextAppearance.Quantum.Widget.EditText">
- <item name="textColor">?textColorPrimaryInverse</item>
- <item name="textColorHint">?textColorHintInverse</item>
+ <item name="textColor">?attr/textColorPrimaryInverse</item>
+ <item name="textColorHint">?attr/textColorHintInverse</item>
</style>
- <style name="TextAppearance.Quantum.Widget.Switch" parent="TextAppearance.Quantum.Small">
- <item name="textColor">@color/secondary_text_quantum_dark</item>
+ <style name="TextAppearance.Quantum.Widget.Switch">
+ <item name="textSize">14sp</item>
</style>
- <style name="TextAppearance.Quantum.Widget.PopupMenu" parent="TextAppearance.Widget.PopupMenu">
- <item name="textColor">?attr/textColorPrimary</item>
- </style>
+ <style name="TextAppearance.Quantum.Widget.PopupMenu"/>
<style name="TextAppearance.Quantum.Widget.PopupMenu.Large">
- <item name="textSize">18sp</item>
+ <item name="fontFamily">@string/font_family_menu_quantum</item>
+ <item name="textSize">@dimen/text_size_menu_quantum</item>>
</style>
<style name="TextAppearance.Quantum.Widget.PopupMenu.Small">
- <item name="textSize">14sp</item>
+ <item name="fontFamily">@string/font_family_menu_quantum</item>
+ <item name="textSize">@dimen/text_size_menu_quantum</item>>
</style>
<style name="TextAppearance.Quantum.Widget.DropDownHint">
- <item name="textColor">?attr/textColorPrimary</item>
- <item name="textSize">14sp</item>
+ <item name="fontFamily">@string/font_family_menu_quantum</item>
+ <item name="textSize">@dimen/text_size_menu_quantum</item>>
</style>
+
<style name="TextAppearance.Quantum.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Small">
<item name="textColor">?attr/textColorPrimary</item>
</style>
@@ -194,10 +261,11 @@ please see styles_device_defaults.xml.
</style>
<style name="TextAppearance.Quantum.Widget.TextView.PopupMenu">
- <item name="textSize">18sp</item>
+ <item name="fontFamily">@string/font_family_menu_quantum</item>
+ <item name="textSize">@dimen/text_size_menu_quantum</item>
</style>
- <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem" />
+ <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem"/>
<style name="TextAppearance.Quantum.Widget.DropDownItem">
<item name="textColor">?attr/textColorPrimaryDisableOnly</item>
@@ -223,106 +291,85 @@ please see styles_device_defaults.xml.
<item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
</style>
- <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
- <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
- <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
- </style>
-
<style name="TextAppearance.Quantum.Widget.ActionBar.Menu" parent="TextAppearance.Quantum.Small">
- <item name="textSize">12sp</item>
- <item name="textStyle">bold</item>
+ <item name="fontFamily">@string/font_family_menu_quantum</item>
+ <item name="textSize">@dimen/text_size_menu_quantum</item>>
<item name="textColor">?attr/actionMenuTextColor</item>
<item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
</style>
- <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
- <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
- <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
- </style>
-
<style name="TextAppearance.Quantum.WindowTitle">
<item name="textColor">?attr/textColorPrimary</item>
- <item name="textSize">14sp</item>
- <item name="textStyle">bold</item>
+ <item name="fontFamily">@string/font_family_headline_quantum</item>
+ <item name="textSize">@dimen/text_size_headline_quantum</item>
</style>
<style name="TextAppearance.Quantum.DialogWindowTitle">
- <item name="textSize">22sp</item>
+ <item name="fontFamily">@string/font_family_headline_quantum</item>
+ <item name="textSize">@dimen/text_size_headline_quantum</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
- <style name="TextAppearance.Quantum.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView">
+ <style name="TextAppearance.Quantum.CalendarViewWeekDayView" parent="TextAppearance.Quantum.Small">
+ <item name="textStyle">bold</item>
<item name="textColor">#505050</item>
</style>
- <!-- Light text styles -->
- <style name="TextAppearance.Quantum.Light" parent="TextAppearance.Quantum"/>
+ <style name="TextAppearance.Quantum.TimePicker.TimeLabel" parent="TextAppearance.Quantum">
+ <item name="textSize">@dimen/timepicker_time_label_size</item>
+ <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
+ </style>
- <style name="TextAppearance.Quantum.Light.Inverse" parent="TextAppearance.Quantum.Inverse" />
+ <style name="TextAppearance.Quantum.TimePicker.AmPmLabel" parent="TextAppearance.Quantum">
+ <item name="textSize">@dimen/timepicker_ampm_label_size</item>
+ <item name="textAllCaps">true</item>
+ <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
+ <item name="textStyle">bold</item>
+ </style>
+ <!-- Light text styles -->
+ <style name="TextAppearance.Quantum.Light" parent="TextAppearance.Quantum"/>
+ <style name="TextAppearance.Quantum.Light.Inverse" parent="TextAppearance.Quantum.Inverse"/>
<style name="TextAppearance.Quantum.Light.Large" parent="TextAppearance.Quantum.Large"/>
-
+ <style name="TextAppearance.Quantum.Light.Large.Inverse" parent="TextAppearance.Quantum.Large.Inverse"/>
<style name="TextAppearance.Quantum.Light.Medium" parent="TextAppearance.Quantum.Medium"/>
-
+ <style name="TextAppearance.Quantum.Light.Medium.Inverse" parent="TextAppearance.Quantum.Medium.Inverse"/>
<style name="TextAppearance.Quantum.Light.Small" parent="TextAppearance.Quantum.Small"/>
-
- <style name="TextAppearance.Quantum.Light.Large.Inverse" parent="TextAppearance.Quantum.Large.Inverse" />
-
- <style name="TextAppearance.Quantum.Light.Medium.Inverse" parent="TextAppearance.Quantum.Medium.Inverse" />
-
- <style name="TextAppearance.Quantum.Light.Small.Inverse" parent="TextAppearance.Quantum.Small.Inverse" />
-
- <style name="TextAppearance.Quantum.Light.SearchResult" parent="TextAppearance.Quantum.SearchResult" />
-
- <style name="TextAppearance.Quantum.Light.SearchResult.Title" parent="TextAppearance.Quantum.SearchResult.Title" />
-
- <style name="TextAppearance.Quantum.Light.SearchResult.Subtitle" parent="TextAppearance.Quantum.SearchResult.Subtitle" />
-
- <style name="TextAppearance.Quantum.Light.Widget" parent="TextAppearance.Widget"/>
-
- <style name="TextAppearance.Quantum.Light.Widget.Button" parent="TextAppearance.Quantum.Widget.Button" />
-
- <style name="TextAppearance.Quantum.Light.Widget.EditText" parent="TextAppearance.Quantum.Widget.EditText" />
-
- <style name="TextAppearance.Quantum.Light.Widget.Switch" parent="TextAppearance.Quantum.Small">
- <item name="textColor">@color/secondary_text_quantum_dark</item>
- </style>
-
+ <style name="TextAppearance.Quantum.Light.Small.Inverse" parent="TextAppearance.Quantum.Small.Inverse"/>
+ <style name="TextAppearance.Quantum.Light.SearchResult" parent="TextAppearance.Quantum.SearchResult"/>
+ <style name="TextAppearance.Quantum.Light.SearchResult.Title" parent="TextAppearance.Quantum.SearchResult.Title"/>
+ <style name="TextAppearance.Quantum.Light.SearchResult.Subtitle" parent="TextAppearance.Quantum.SearchResult.Subtitle"/>
+ <style name="TextAppearance.Quantum.Light.Widget" parent="TextAppearance.Quantum.Widget"/>
+ <style name="TextAppearance.Quantum.Light.Widget.Button" parent="TextAppearance.Quantum.Widget.Button"/>
+ <style name="TextAppearance.Quantum.Light.Widget.EditText" parent="TextAppearance.Quantum.Widget.EditText"/>
+ <style name="TextAppearance.Quantum.Light.Widget.Switch" parent="TextAppearance.Quantum.Widget.Switch"/>
<style name="TextAppearance.Quantum.Light.Widget.PopupMenu" parent="TextAppearance.Quantum.Widget.PopupMenu"/>
-
<style name="TextAppearance.Quantum.Light.Widget.PopupMenu.Large" parent="TextAppearance.Quantum.Widget.PopupMenu.Large"/>
-
<style name="TextAppearance.Quantum.Light.Widget.PopupMenu.Small" parent="TextAppearance.Quantum.Widget.PopupMenu.Small"/>
-
<style name="TextAppearance.Quantum.Light.Widget.DropDownHint" parent="TextAppearance.Quantum.Widget.DropDownHint"/>
+ <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Title" parent="TextAppearance.Quantum.Widget.ActionMode.Title"/>
+ <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Subtitle" parent="TextAppearance.Quantum.Widget.ActionMode.Subtitle"/>
+ <style name="TextAppearance.Quantum.Light.WindowTitle" parent="TextAppearance.Quantum.WindowTitle"/>
+ <style name="TextAppearance.Quantum.Light.DialogWindowTitle" parent="TextAppearance.Quantum.DialogWindowTitle"/>
+ <style name="TextAppearance.Quantum.Light.CalendarViewWeekDayView" parent="TextAppearance.Quantum.CalendarViewWeekDayView"/>
- <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Title" parent="TextAppearance.Widget.ActionMode.Title"/>
-
- <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle"/>
-
- <style name="TextAppearance.Quantum.Light.WindowTitle" parent="TextAppearance.Quantum.WindowTitle" />
-
- <style name="TextAppearance.Quantum.Light.DialogWindowTitle" parent="TextAppearance.Quantum.DialogWindowTitle" />
+ <style name="TextAppearance.Quantum.Light.TimePicker.TimeLabel" parent="TextAppearance.Quantum.TimePicker.TimeLabel">
+ <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
+ </style>
- <style name="TextAppearance.Quantum.Light.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView"/>
+ <style name="TextAppearance.Quantum.Light.TimePicker.AmPmLabel" parent="TextAppearance.Quantum.TimePicker.AmPmLabel">
+ <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
+ </style>
<!-- Widget Styles -->
-
- <style name="Quantum" />
- <style name="Quantum.Light" />
-
+ <style name="Quantum"/>
+ <style name="Quantum.Light"/>
<style name="Widget.Quantum" parent="Widget" />
<!-- Bordered ink button -->
<style name="Widget.Quantum.Button" parent="Widget.Button">
- <item name="background">@drawable/btn_default_quantum_dark</item>
+ <item name="background">@drawable/btn_default_quantum</item>
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="minHeight">48dip</item>
<item name="minWidth">96dip</item>
@@ -341,12 +388,12 @@ please see styles_device_defaults.xml.
<!-- Bordered paper button with color -->
<style name="Widget.Quantum.Button.Paper.Color">
- <item name="background">@drawable/btn_color_quantum_dark</item>
+ <item name="background">@drawable/btn_color_quantum</item>
</style>
<!-- Borderless ink button -->
<style name="Widget.Quantum.Button.Borderless">
- <item name="background">@drawable/btn_borderless_quantum_dark</item>
+ <item name="background">@drawable/btn_borderless_quantum</item>
</style>
<!-- Small borderless ink button -->
@@ -359,6 +406,7 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.Button.Borderless.Paper">
<!-- TODO: Specify pressed state animation. -->
</style>
+
<style name="Widget.Quantum.Button.Inset">
<item name="background">@drawable/button_inset</item>
</style>
@@ -371,7 +419,7 @@ please see styles_device_defaults.xml.
<item name="minHeight">48dip</item>
</style>
- <style name="Quantum.ButtonBar" parent="ButtonBar">
+ <style name="Widget.Quantum.ButtonBar">
<item name="paddingTop">0dip</item>
<item name="paddingStart">0dip</item>
<item name="paddingEnd">0dip</item>
@@ -382,15 +430,17 @@ please see styles_device_defaults.xml.
<item name="background">@null</item>
</style>
- <style name="Quantum.SegmentedButton" parent="SegmentedButton">
- <item name="background">@drawable/btn_group_holo_dark</item>
- </style>
-
- <style name="Quantum.ButtonBar.AlertDialog">
+ <style name="Widget.Quantum.ButtonBar.AlertDialog">
<item name="background">@null</item>
<item name="dividerPadding">0dp</item>
</style>
+ <style name="Widget.Quantum.ButtonBar.Button"/>
+
+ <style name="Widget.Quantum.SegmentedButton" parent="SegmentedButton">
+ <item name="background">@drawable/btn_group_holo_dark</item>
+ </style>
+
<style name="Widget.Quantum.StackView">
<item name="resOutColor">@color/holo_blue_light</item>
<item name="clickColor">@color/holo_blue_light</item>
@@ -398,17 +448,20 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.TextView" parent="Widget.TextView"/>
- <style name="Widget.Quantum.CheckedTextView" parent="Widget.CheckedTextView"/>
-
<style name="Widget.Quantum.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
- <item name="background">@drawable/list_section_divider_quantum_dark</item>
+ <item name="background">@drawable/list_section_divider_quantum</item>
<item name="textAllCaps">true</item>
</style>
- <style name="Widget.Quantum.TextSelectHandle" parent="Widget.TextSelectHandle"/>
+ <style name="Widget.Quantum.TextView.SpinnerItem" parent="Widget.TextView.SpinnerItem">
+ <item name="textAppearance">@style/TextAppearance.Quantum.Widget.TextView.SpinnerItem</item>
+ <item name="paddingStart">8dp</item>
+ <item name="paddingEnd">8dp</item>
+ </style>
+ <style name="Widget.Quantum.CheckedTextView" parent="Widget.CheckedTextView"/>
+ <style name="Widget.Quantum.TextSelectHandle" parent="Widget.TextSelectHandle"/>
<style name="Widget.Quantum.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow"/>
-
<style name="Widget.Quantum.AbsListView" parent="Widget.AbsListView"/>
<style name="Widget.Quantum.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
@@ -417,31 +470,38 @@ please see styles_device_defaults.xml.
</style>
<style name="Widget.Quantum.CompoundButton" parent="Widget.CompoundButton"/>
-
<style name="Widget.Quantum.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox"/>
+ <style name="Widget.Quantum.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton"/>
- <style name="Widget.Quantum.ListView.DropDown"/>
+ <style name="Widget.Quantum.CompoundButton.Star" parent="Widget.CompoundButton.Star">
+ <item name="button">@drawable/btn_star_quantum</item>
+ </style>
+
+ <style name="Widget.Quantum.CompoundButton.Switch">
+ <item name="track">@drawable/switch_track_quantum</item>
+ <item name="thumb">@drawable/switch_inner_quantum</item>
+ <item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item>
+ <item name="textOn"></item>
+ <item name="textOff"></item>
+ <item name="thumbTextPadding">12dip</item>
+ <item name="switchMinWidth">72dip</item>
+ <item name="switchPadding">16dip</item>
+ </style>
<style name="Widget.Quantum.EditText" parent="Widget.EditText"/>
<style name="Widget.Quantum.ExpandableListView" parent="Widget.Quantum.ListView">
- <item name="groupIndicator">@drawable/expander_group_quantum_dark</item>
+ <item name="groupIndicator">@drawable/expander_group_quantum</item>
<item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
<item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
<item name="childDivider">?attr/listDivider</item>
</style>
<style name="Widget.Quantum.ExpandableListView.White"/>
-
<style name="Widget.Quantum.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs"/>
-
<style name="Widget.Quantum.Gallery" parent="Widget.Gallery"/>
-
<style name="Widget.Quantum.GestureOverlayView" parent="Widget.GestureOverlayView"/>
-
- <style name="Widget.Quantum.GridView" parent="Widget.GridView">
- <item name="listSelector">?attr/selectableItemBackground</item>
- </style>
+ <style name="Widget.Quantum.GridView" parent="Widget.GridView"/>
<style name="Widget.Quantum.CalendarView" parent="Widget.CalendarView">
<item name="selectedWeekBackgroundColor">#330099FF</item>
@@ -454,7 +514,7 @@ please see styles_device_defaults.xml.
</style>
<style name="Widget.Quantum.ImageButton" parent="Widget.ImageButton">
- <item name="background">@drawable/btn_default_quantum_dark</item>
+ <item name="background">@drawable/btn_default_quantum</item>
</style>
<style name="Widget.Quantum.NumberPicker" parent="Widget.NumberPicker">
@@ -489,7 +549,6 @@ please see styles_device_defaults.xml.
</style>
<style name="Widget.Quantum.ActivityChooserView" parent="Widget.ActivityChooserView"/>
-
<style name="Widget.Quantum.ImageWell" parent="Widget.ImageWell"/>
<style name="Widget.Quantum.ListView" parent="Widget.ListView">
@@ -497,6 +556,7 @@ please see styles_device_defaults.xml.
<item name="listSelector">?attr/listChoiceBackgroundIndicator</item>
</style>
+ <style name="Widget.Quantum.ListView.DropDown"/>
<style name="Widget.Quantum.ListView.White"/>
<style name="Widget.Quantum.PopupWindow" parent="Widget.PopupWindow"/>
@@ -510,8 +570,10 @@ please see styles_device_defaults.xml.
<item name="indeterminateDrawable">@drawable/progress_medium_holo</item>
</style>
+ <style name="Widget.Quantum.ProgressBar.Inverse"/>
+
<style name="Widget.Quantum.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
- <item name="progressDrawable">@drawable/progress_horizontal_quantum_dark</item>
+ <item name="progressDrawable">@drawable/progress_horizontal_quantum</item>
<item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
<item name="minHeight">16dip</item>
<item name="maxHeight">16dip</item>
@@ -521,25 +583,22 @@ please see styles_device_defaults.xml.
<item name="indeterminateDrawable">@drawable/progress_small_holo</item>
</style>
+ <style name="Widget.Quantum.ProgressBar.Small.Inverse"/>
<style name="Widget.Quantum.ProgressBar.Small.Title"/>
<style name="Widget.Quantum.ProgressBar.Large" parent="Widget.ProgressBar.Large">
<item name="indeterminateDrawable">@drawable/progress_large_holo</item>
</style>
- <style name="Widget.Quantum.ProgressBar.Inverse"/>
-
- <style name="Widget.Quantum.ProgressBar.Small.Inverse"/>
-
<style name="Widget.Quantum.ProgressBar.Large.Inverse"/>
<style name="Widget.Quantum.SeekBar">
<item name="indeterminateOnly">false</item>
- <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum_dark</item>
- <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum_dark</item>
+ <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum</item>
+ <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum</item>
<item name="minHeight">13dip</item>
<item name="maxHeight">13dip</item>
- <item name="thumb">@drawable/scrubber_control_selector_quantum_dark</item>
+ <item name="thumb">@drawable/scrubber_control_selector_quantum</item>
<item name="thumbOffset">16dip</item>
<item name="focusable">true</item>
<item name="paddingStart">16dip</item>
@@ -566,14 +625,11 @@ please see styles_device_defaults.xml.
<item name="maxHeight">16dip</item>
</style>
- <style name="Widget.Quantum.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton"/>
-
<style name="Widget.Quantum.ScrollView" parent="Widget.ScrollView"/>
-
<style name="Widget.Quantum.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
<style name="Widget.Quantum.Spinner" parent="Widget.Spinner.DropDown">
- <item name="background">@drawable/spinner_background_quantum_dark</item>
+ <item name="background">@drawable/spinner_background_quantum</item>
<item name="dropDownSelector">@drawable/list_selector_holo_dark</item>
<item name="popupBackground">?attr/colorBackground</item>
<item name="dropDownVerticalOffset">0dip</item>
@@ -587,11 +643,7 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.Spinner.DropDown"/>
<style name="Widget.Quantum.Spinner.DropDown.ActionBar">
- <item name="background">@drawable/spinner_background_quantum_dark</item>
- </style>
-
- <style name="Widget.Quantum.CompoundButton.Star" parent="Widget.CompoundButton.Star">
- <item name="button">@drawable/btn_star_quantum_dark</item>
+ <item name="background">@drawable/spinner_background_quantum</item>
</style>
<style name="Widget.Quantum.TabWidget" parent="Widget.TabWidget">
@@ -606,7 +658,7 @@ please see styles_device_defaults.xml.
</style>
<style name="Widget.Quantum.Tab" parent="Widget.Quantum.ActionBar.TabView">
- <item name="background">@drawable/tab_indicator_quantum_dark</item>
+ <item name="background">@drawable/tab_indicator_quantum</item>
<item name="layout_width">0dip</item>
<item name="layout_weight">1</item>
<item name="minWidth">80dip</item>
@@ -628,24 +680,12 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.DropDownItem.Spinner"/>
- <style name="Widget.Quantum.TextView.SpinnerItem" parent="Widget.TextView.SpinnerItem">
- <item name="textAppearance">@style/TextAppearance.Quantum.Widget.TextView.SpinnerItem</item>
- <item name="paddingStart">8dp</item>
- <item name="paddingEnd">8dp</item>
- </style>
-
<style name="Widget.Quantum.KeyboardView" parent="Widget.KeyboardView"/>
-
<style name="Widget.Quantum.QuickContactBadge.WindowSmall" parent="Widget.QuickContactBadge.WindowSmall"/>
-
<style name="Widget.Quantum.QuickContactBadge.WindowMedium" parent="Widget.QuickContactBadge.WindowMedium"/>
-
<style name="Widget.Quantum.QuickContactBadge.WindowLarge" parent="Widget.QuickContactBadge.WindowLarge"/>
-
<style name="Widget.Quantum.QuickContactBadgeSmall.WindowSmall" parent="Widget.QuickContactBadgeSmall.WindowSmall"/>
-
<style name="Widget.Quantum.QuickContactBadgeSmall.WindowMedium" parent="Widget.QuickContactBadgeSmall.WindowMedium"/>
-
<style name="Widget.Quantum.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
<style name="Widget.Quantum.ListPopupWindow" parent="Widget.ListPopupWindow">
@@ -658,12 +698,6 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.PopupMenu" parent="Widget.Quantum.ListPopupWindow"/>
- <style name="Widget.Quantum.ButtonBar">
- <item name="divider">?attr/dividerVertical</item>
- </style>
-
- <style name="Widget.Quantum.ButtonBar.Button"/>
-
<style name="Widget.Quantum.ActionButton" parent="Widget.ActionButton">
<item name="minWidth">@dimen/action_button_min_width</item>
<item name="gravity">center</item>
@@ -673,8 +707,12 @@ please see styles_device_defaults.xml.
<item name="maxLines">2</item>
</style>
+ <style name="Widget.Quantum.ActionButton.CloseMode">
+ <item name="background">@drawable/btn_cab_done_holo_dark</item>
+ </style>
+
<style name="Widget.Quantum.ActionButton.Overflow">
- <item name="src">@drawable/ic_menu_moreoverflow_quantum_dark</item>
+ <item name="src">@drawable/ic_menu_moreoverflow_quantum</item>
<item name="background">?attr/actionBarItemBackground</item>
<item name="contentDescription">@string/action_menu_overflow_description</item>
</style>
@@ -682,7 +720,7 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.ActionButton.TextButton" parent="Widget.Quantum.ButtonBar.Button"/>
<style name="Widget.Quantum.ActionBar.TabView" parent="Widget.ActionBar.TabView">
- <item name="background">@drawable/tab_indicator_quantum_dark</item>
+ <item name="background">@drawable/tab_indicator_quantum</item>
<item name="paddingStart">16dip</item>
<item name="paddingEnd">16dip</item>
</style>
@@ -703,19 +741,10 @@ please see styles_device_defaults.xml.
<item name="maxLines">2</item>
</style>
- <style name="Widget.Quantum.ActionMode" parent="Widget.ActionMode">
- <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
- <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
- </style>
-
- <style name="Widget.Quantum.ActionButton.CloseMode">
- <item name="background">@drawable/btn_cab_done_holo_dark</item>
- </style>
-
<style name="Widget.Quantum.ActionBar" parent="Widget.ActionBar">
<item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
- <item name="background">@drawable/ab_transparent_quantum_dark</item>
+ <item name="background">@drawable/ab_transparent_quantum</item>
<item name="backgroundStacked">@drawable/ab_stacked_transparent_dark_holo</item>
<item name="backgroundSplit">@drawable/ab_bottom_transparent_dark_holo</item>
<item name="divider">?attr/dividerVertical</item>
@@ -738,61 +767,43 @@ please see styles_device_defaults.xml.
<item name="itemPadding">8dip</item>
</style>
- <style name="Widget.Quantum.CompoundButton.Switch">
- <item name="track">@drawable/switch_track_quantum_dark</item>
- <item name="thumb">@drawable/switch_inner_quantum_dark</item>
- <item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item>
- <item name="textOn"></item>
- <item name="textOff"></item>
- <item name="thumbTextPadding">12dip</item>
- <item name="switchMinWidth">72dip</item>
- <item name="switchPadding">16dip</item>
- </style>
-
- <!-- Light widget styles -->
-
- <style name="Widget.Quantum.Light" parent="Widget" />
-
- <!-- Bordered ink button -->
- <style name="Widget.Quantum.Light.Button" parent="Widget.Quantum.Button">
- <item name="background">@drawable/btn_default_quantum_light</item>
- <item name="textAppearance">?attr/textAppearanceButton</item>
- <item name="minHeight">48dip</item>
- <item name="minWidth">96dip</item>
- </style>
-
- <!-- Small bordered ink button -->
- <style name="Widget.Quantum.Light.Button.Small">
- <item name="minHeight">48dip</item>
- <item name="minWidth">48dip</item>
+ <style name="Widget.Quantum.ActionMode" parent="Widget.ActionMode">
+ <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
+ <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
</style>
- <!-- Bordered paper button -->
- <style name="Widget.Quantum.Light.Button.Paper">
- <!-- TODO: Specify pressed state animation. -->
+ <style name="Widget.Quantum.FastScroll" parent="Widget.FastScroll">
+ <item name="thumbMinWidth">0dp</item>
+ <item name="thumbMinHeight">0dp</item>
</style>
- <!-- Bordered paper button with color -->
- <style name="Widget.Quantum.Light.Button.Paper.Color">
- <item name="background">@drawable/btn_color_quantum_light</item>
+ <style name="Widget.Quantum.PreferenceFrameLayout">
+ <item name="borderTop">0dip</item>
+ <item name="borderBottom">@dimen/preference_fragment_padding_bottom</item>
+ <item name="borderLeft">?attr/preferenceFragmentPaddingSide</item>
+ <item name="borderRight">?attr/preferenceFragmentPaddingSide</item>
</style>
- <!-- Borderless ink button -->
- <style name="Widget.Quantum.Light.Button.Borderless">
- <item name="background">@drawable/btn_borderless_quantum_light</item>
+ <style name="Widget.Quantum.MediaRouteButton">
+ <item name="background">?attr/selectableItemBackground</item>
+ <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_dark</item>
+ <item name="minWidth">56dp</item>
+ <item name="minHeight">48dp</item>
+ <item name="focusable">true</item>
+ <item name="contentDescription">@string/media_route_button_content_description</item>
</style>
- <!-- Small borderless ink button -->
- <style name="Widget.Quantum.Light.Button.Borderless.Small">
- <item name="minHeight">48dip</item>
- <item name="minWidth">48dip</item>
- </style>
+ <!-- Light widget styles -->
- <!-- Borderless paper button -->
- <style name="Widget.Quantum.Light.Button.Borderless.Paper">
- <!-- TODO: Specify pressed state animation. -->
- </style>
- <style name="Widget.Quantum.Light.Button.Inset"/>
+ <style name="Widget.Quantum.Light" parent="Widget.Quantum"/>
+ <style name="Widget.Quantum.Light.Button" parent="Widget.Quantum.Button"/>
+ <style name="Widget.Quantum.Light.Button.Small" parent="Widget.Quantum.Button.Small"/>
+ <style name="Widget.Quantum.Light.Button.Paper" parent="Widget.Quantum.Button.Paper"/>
+ <style name="Widget.Quantum.Light.Button.Paper.Color" parent="Widget.Quantum.Button.Paper.Color"/>
+ <style name="Widget.Quantum.Light.Button.Borderless" parent="Widget.Quantum.Button.Borderless"/>
+ <style name="Widget.Quantum.Light.Button.Borderless.Small" parent="Widget.Quantum.Button.Borderless.Small"/>
+ <style name="Widget.Quantum.Light.Button.Borderless.Paper" parent="Widget.Quantum.Button.Borderless.Paper"/>
+ <style name="Widget.Quantum.Light.Button.Inset" parent="Widget.Quantum.Button.Inset"/>
<style name="Widget.Quantum.Light.Button.Toggle">
<item name="background">@drawable/btn_toggle_holo_light</item>
@@ -802,63 +813,36 @@ please see styles_device_defaults.xml.
<item name="minHeight">48dip</item>
</style>
- <style name="Quantum.Light.ButtonBar" parent="Quantum.ButtonBar"/>
+ <style name="Widget.Quantum.Light.ButtonBar" parent="Widget.Quantum.ButtonBar"/>
+ <style name="Widget.Quantum.Light.ButtonBar.AlertDialog" parent="Widget.Quantum.ButtonBar.AlertDialog"/>
- <style name="Quantum.Light.ButtonBar.AlertDialog">
- <item name="background">@null</item>
- <item name="dividerPadding">0dp</item>
- </style>
-
- <style name="Quantum.Light.SegmentedButton" parent="SegmentedButton">
+ <style name="Widget.Quantum.Light.SegmentedButton" parent="Widget.Quantum.SegmentedButton">
<item name="background">@drawable/btn_group_holo_light</item>
</style>
- <style name="Widget.Quantum.Light.TextView" parent="Widget.TextView"/>
-
- <style name="Widget.Quantum.Light.CheckedTextView" parent="Widget.CheckedTextView"/>
-
- <style name="Widget.Quantum.Light.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
- <item name="background">@drawable/list_section_divider_quantum_light</item>
- <item name="textAllCaps">true</item>
- </style>
-
- <style name="Widget.Quantum.Light.TextSelectHandle" parent="Widget.TextSelectHandle"/>
-
- <style name="Widget.Quantum.Light.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow"/>
-
- <style name="Widget.Quantum.Light.AbsListView" parent="Widget.AbsListView"/>
+ <style name="Widget.Quantum.Light.TextView" parent="Widget.Quantum.TextView"/>
+ <style name="Widget.Quantum.Light.TextView.ListSeparator" parent="Widget.Quantum.TextView.ListSeparator"/>
+ <style name="Widget.Quantum.Light.TextView.SpinnerItem" parent="Widget.Quantum.TextView.SpinnerItem"/>
+ <style name="Widget.Quantum.Light.CheckedTextView" parent="Widget.Quantum.CheckedTextView"/>
+ <style name="Widget.Quantum.Light.TextSelectHandle" parent="Widget.Quantum.TextSelectHandle"/>
+ <style name="Widget.Quantum.Light.TextSuggestionsPopupWindow" parent="Widget.Quantum.TextSuggestionsPopupWindow"/>
+ <style name="Widget.Quantum.Light.AbsListView" parent="Widget.Quantum.AbsListView"/>
<style name="Widget.Quantum.Light.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
<item name="dropDownSelector">@drawable/list_selector_holo_light</item>
<item name="popupBackground">?attr/colorBackground</item>
</style>
- <style name="Widget.Quantum.Light.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox"/>
-
- <style name="Widget.Quantum.Light.ListView.DropDown"/>
-
+ <style name="Widget.Quantum.Light.CompoundButton.CheckBox" parent="Widget.Quantum.CompoundButton.CheckBox"/>
+ <style name="Widget.Quantum.Light.ListView.DropDown" parent="Widget.Quantum.ListView.DropDown"/>
<style name="Widget.Quantum.Light.EditText" parent="Widget.Quantum.EditText"/>
-
- <style name="Widget.Quantum.Light.ExpandableListView" parent="Widget.Quantum.Light.ListView">
- <item name="groupIndicator">@drawable/expander_group_quantum_light</item>
- <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
- <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
- <item name="childDivider">?attr/listDivider</item>
- </style>
-
- <style name="Widget.Quantum.Light.ExpandableListView.White"/>
-
- <style name="Widget.Quantum.Light.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs"/>
-
- <style name="Widget.Quantum.Light.Gallery" parent="Widget.Gallery"/>
-
- <style name="Widget.Quantum.Light.GestureOverlayView" parent="Widget.GestureOverlayView"/>
-
+ <style name="Widget.Quantum.Light.ExpandableListView" parent="Widget.Quantum.ExpandableListView"/>
+ <style name="Widget.Quantum.Light.ExpandableListView.White" parent="Widget.Quantum.ExpandableListView.White"/>
+ <style name="Widget.Quantum.Light.FragmentBreadCrumbs" parent="Widget.Quantum.FragmentBreadCrumbs"/>
+ <style name="Widget.Quantum.Light.Gallery" parent="Widget.Quantum.Gallery"/>
+ <style name="Widget.Quantum.Light.GestureOverlayView" parent="Widget.Quantum.GestureOverlayView"/>
<style name="Widget.Quantum.Light.GridView" parent="Widget.Quantum.GridView"/>
-
- <style name="Widget.Quantum.Light.ImageButton" parent="Widget.Quantum.ImageButton">
- <item name="background">@drawable/btn_default_quantum_light</item>
- </style>
+ <style name="Widget.Quantum.Light.ImageButton" parent="Widget.Quantum.ImageButton"/>
<style name="Widget.Quantum.Light.CalendarView" parent="Widget.CalendarView">
<item name="selectedWeekBackgroundColor">#330066ff</item>
@@ -892,13 +876,10 @@ please see styles_device_defaults.xml.
<item name="background">@drawable/ab_share_pack_holo_light</item>
</style>
- <style name="Widget.Quantum.Light.ImageWell" parent="Widget.ImageWell"/>
-
+ <style name="Widget.Quantum.Light.ImageWell" parent="Widget.Quantum.ImageWell"/>
<style name="Widget.Quantum.Light.ListView" parent="Widget.Quantum.ListView"/>
-
- <style name="Widget.Quantum.Light.ListView.White"/>
-
- <style name="Widget.Quantum.Light.PopupWindow" parent="Widget.PopupWindow"/>
+ <style name="Widget.Quantum.Light.ListView.White" parent="Widget.Quantum.ListView.White"/>
+ <style name="Widget.Quantum.Light.PopupWindow" parent="Widget.Quantum.PopupWindow"/>
<style name="Widget.Quantum.Light.PopupWindow.ActionMode">
<item name="popupBackground">@color/white</item>
@@ -906,28 +887,14 @@ please see styles_device_defaults.xml.
</style>
<style name="Widget.Quantum.Light.ProgressBar" parent="Widget.Quantum.ProgressBar"/>
-
- <style name="Widget.Quantum.Light.ProgressBar.Horizontal" parent="Widget.Quantum.ProgressBar.Horizontal">
- <item name="progressDrawable">@drawable/progress_horizontal_quantum_light</item>
- </style>
-
+ <style name="Widget.Quantum.Light.ProgressBar.Horizontal" parent="Widget.Quantum.ProgressBar.Horizontal"/>
<style name="Widget.Quantum.Light.ProgressBar.Small" parent="Widget.Quantum.ProgressBar.Small"/>
-
<style name="Widget.Quantum.Light.ProgressBar.Small.Title" parent="Widget.Quantum.ProgressBar.Small.Title"/>
-
<style name="Widget.Quantum.Light.ProgressBar.Large" parent="Widget.Quantum.ProgressBar.Large"/>
-
<style name="Widget.Quantum.Light.ProgressBar.Inverse" parent="Widget.Quantum.ProgressBar.Inverse"/>
-
<style name="Widget.Quantum.Light.ProgressBar.Small.Inverse" parent="Widget.Quantum.ProgressBar.Small.Inverse"/>
-
<style name="Widget.Quantum.Light.ProgressBar.Large.Inverse" parent="Widget.Quantum.ProgressBar.Large.Inverse"/>
-
- <style name="Widget.Quantum.Light.SeekBar" parent="Widget.Quantum.SeekBar">
- <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum_light</item>
- <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum_light</item>
- <item name="thumb">@drawable/scrubber_control_selector_quantum_light</item>
- </style>
+ <style name="Widget.Quantum.Light.SeekBar" parent="Widget.Quantum.SeekBar"/>
<style name="Widget.Quantum.Light.RatingBar" parent="Widget.RatingBar">
<item name="progressDrawable">@drawable/ratingbar_full_holo_light</item>
@@ -948,14 +915,12 @@ please see styles_device_defaults.xml.
<item name="maxHeight">16dip</item>
</style>
- <style name="Widget.Quantum.Light.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton"/>
-
- <style name="Widget.Quantum.Light.ScrollView" parent="Widget.ScrollView"/>
-
- <style name="Widget.Quantum.Light.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
+ <style name="Widget.Quantum.Light.CompoundButton.RadioButton" parent="Widget.Quantum.CompoundButton.RadioButton"/>
+ <style name="Widget.Quantum.Light.ScrollView" parent="Widget.Quantum.ScrollView"/>
+ <style name="Widget.Quantum.Light.HorizontalScrollView" parent="Widget.Quantum.HorizontalScrollView"/>
<style name="Widget.Quantum.Light.Spinner" parent="Widget.Quantum.Spinner">
- <item name="background">@drawable/spinner_background_quantum_light</item>
+ <item name="background">@drawable/spinner_background_quantum</item>
<item name="dropDownSelector">@drawable/list_selector_holo_light</item>
<item name="popupBackground">?attr/colorBackground</item>
<item name="dropDownVerticalOffset">0dip</item>
@@ -964,41 +929,21 @@ please see styles_device_defaults.xml.
<item name="popupPromptView">@layout/simple_dropdown_hint</item>
</style>
- <style name="Widget.Quantum.Light.Spinner.DropDown"/>
-
- <style name="Widget.Quantum.Light.Spinner.DropDown.ActionBar">
- <item name="background">@drawable/spinner_background_quantum_light</item>
- </style>
-
- <style name="Widget.Quantum.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star">
- <item name="button">@drawable/btn_star_quantum_light</item>
- </style>
-
+ <style name="Widget.Quantum.Light.Spinner.DropDown" parent="Widget.Quantum.Spinner.DropDown"/>
+ <style name="Widget.Quantum.Light.Spinner.DropDown.ActionBar" parent="Widget.Quantum.Spinner.DropDown.ActionBar"/>
+ <style name="Widget.Quantum.Light.CompoundButton.Star" parent="Widget.Quantum.CompoundButton.Star"/>
<style name="Widget.Quantum.Light.TabWidget" parent="Widget.Quantum.TabWidget"/>
-
- <style name="Widget.Quantum.Light.WebTextView" parent="Widget.WebTextView"/>
-
- <style name="Widget.Quantum.Light.WebView" parent="Widget.WebView"/>
-
+ <style name="Widget.Quantum.Light.WebTextView" parent="Widget.Quantum.WebTextView"/>
+ <style name="Widget.Quantum.Light.WebView" parent="Widget.Quantum.WebView"/>
<style name="Widget.Quantum.Light.DropDownItem" parent="Widget.Quantum.DropDownItem"/>
-
- <style name="Widget.Quantum.Light.DropDownItem.Spinner"/>
-
- <style name="Widget.Quantum.Light.TextView.SpinnerItem" parent="Widget.Quantum.TextView.SpinnerItem"/>
-
- <style name="Widget.Quantum.Light.KeyboardView" parent="Widget.KeyboardView"/>
-
- <style name="Widget.Quantum.Light.QuickContactBadge.WindowSmall" parent="Widget.QuickContactBadge.WindowSmall"/>
-
- <style name="Widget.Quantum.Light.QuickContactBadge.WindowMedium" parent="Widget.QuickContactBadge.WindowMedium"/>
-
- <style name="Widget.Quantum.Light.QuickContactBadge.WindowLarge" parent="Widget.QuickContactBadge.WindowLarge"/>
-
- <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowSmall" parent="Widget.QuickContactBadgeSmall.WindowSmall"/>
-
- <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowMedium" parent="Widget.QuickContactBadgeSmall.WindowMedium"/>
-
- <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
+ <style name="Widget.Quantum.Light.DropDownItem.Spinner" parent="Widget.Quantum.DropDownItem.Spinner"/>
+ <style name="Widget.Quantum.Light.KeyboardView" parent="Widget.Quantum.KeyboardView"/>
+ <style name="Widget.Quantum.Light.QuickContactBadge.WindowSmall" parent="Widget.Quantum.QuickContactBadge.WindowSmall"/>
+ <style name="Widget.Quantum.Light.QuickContactBadge.WindowMedium" parent="Widget.Quantum.QuickContactBadge.WindowMedium"/>
+ <style name="Widget.Quantum.Light.QuickContactBadge.WindowLarge" parent="Widget.Quantum.QuickContactBadge.WindowLarge"/>
+ <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowSmall" parent="Widget.Quantum.QuickContactBadgeSmall.WindowSmall"/>
+ <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowMedium" parent="Widget.Quantum.QuickContactBadgeSmall.WindowMedium"/>
+ <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowLarge" parent="Widget.Quantum.QuickContactBadgeSmall.WindowLarge"/>
<style name="Widget.Quantum.Light.ListPopupWindow" parent="Widget.ListPopupWindow">
<item name="dropDownSelector">@drawable/list_selector_holo_light</item>
@@ -1011,44 +956,17 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.Light.PopupMenu" parent="Widget.Quantum.Light.ListPopupWindow"/>
<style name="Widget.Quantum.Light.ActionButton" parent="Widget.Quantum.ActionButton"/>
-
- <style name="Widget.Quantum.Light.ActionButton.Overflow">
- <item name="src">@drawable/ic_menu_moreoverflow_quantum_light</item>
- <item name="contentDescription">@string/action_menu_overflow_description</item>
- </style>
-
- <style name="Widget.Quantum.Light.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView">
- <item name="background">@drawable/tab_indicator_quantum_light</item>
- </style>
-
- <style name="Widget.Quantum.Light.Tab" parent="Widget.Quantum.Light.ActionBar.TabView">
- <item name="layout_width">0dip</item>
- <item name="layout_weight">1</item>
- <item name="minWidth">80dip</item>
- </style>
-
+ <style name="Widget.Quantum.Light.ActionButton.Overflow" parent="Widget.Quantum.ActionButton.Overflow"/>
+ <style name="Widget.Quantum.Light.Tab" parent="Widget.Quantum.Tab"/>
+ <style name="Widget.Quantum.Light.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView"/>
<style name="Widget.Quantum.Light.ActionBar.TabBar" parent="Widget.Quantum.ActionBar.TabBar"/>
-
<style name="Widget.Quantum.Light.ActionBar.TabText" parent="Widget.Quantum.ActionBar.TabText"/>
- <style name="Widget.Quantum.Light.ActionBar.TabView.Inverse"/>
-
- <style name="Widget.Quantum.Light.ActionBar.TabBar.Inverse"/>
-
- <style name="Widget.Quantum.Light.ActionBar.TabText.Inverse">
- <item name="textColor">?attr/textColorPrimaryInverse</item>
- </style>
-
<style name="Widget.Quantum.Light.ActionMode" parent="Widget.Quantum.ActionMode">
<item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
</style>
- <style name="Widget.Quantum.Light.ActionMode.Inverse" parent="Widget.ActionMode">
- <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title.Inverse</item>
- <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse</item>
- </style>
-
<style name="Widget.Quantum.Light.ActionButton.CloseMode">
<item name="background">@drawable/btn_cab_done_holo_light</item>
</style>
@@ -1056,10 +974,10 @@ please see styles_device_defaults.xml.
<style name="Widget.Quantum.Light.ActionBar" parent="Widget.Quantum.ActionBar">
<item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
- <item name="background">@drawable/ab_transparent_quantum_light</item>
+ <item name="background">@drawable/ab_transparent_quantum</item>
<item name="backgroundStacked">@drawable/ab_stacked_transparent_light_holo</item>
<item name="backgroundSplit">@drawable/ab_bottom_transparent_light_holo</item>
- <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_light</item>
+ <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum</item>
<item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
<item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
</style>
@@ -1077,36 +995,20 @@ please see styles_device_defaults.xml.
<item name="itemPadding">8dip</item>
</style>
- <style name="Widget.Quantum.Light.ActionBar.Solid.Inverse">
- <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title.Inverse</item>
- <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse</item>
- <item name="background">@drawable/ab_solid_dark_holo</item>
- <item name="backgroundStacked">@drawable/ab_stacked_solid_dark_holo</item>
- <item name="backgroundSplit">@drawable/ab_bottom_solid_inverse_holo</item>
- <item name="divider">@drawable/list_divider_quantum_dark</item>
- <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
- <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
- <item name="progressBarPadding">32dip</item>
- <item name="itemPadding">8dip</item>
+ <style name="Widget.Quantum.Light.CompoundButton.Switch" parent="Widget.Quantum.CompoundButton.Switch">
+ <item name="switchTextAppearance">@style/TextAppearance.Quantum.Light.Widget.Switch</item>
</style>
- <style name="Widget.Quantum.Light.CompoundButton.Switch" parent="Widget.CompoundButton.Switch">
- <item name="track">@drawable/switch_track_quantum_light</item>
- <item name="thumb">@drawable/switch_inner_quantum_light</item>
- <item name="switchTextAppearance">@style/TextAppearance.Quantum.Light.Widget.Switch</item>
- <item name="textOn"></item>
- <item name="textOff"></item>
- <item name="thumbTextPadding">12dip</item>
- <item name="switchMinWidth">96dip</item>
- <item name="switchPadding">16dip</item>
+ <style name="Widget.Quantum.Light.FastScroll" parent="Widget.Quantum.FastScroll"/>
+
+ <style name="Widget.Quantum.Light.MediaRouteButton" parent="Widget.Quantum.MediaRouteButton">
+ <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
</style>
<!-- Animation Styles -->
<style name="Animation.Quantum" parent="Animation"/>
-
<style name="Animation.Quantum.Activity" parent="Animation.Activity"/>
-
<style name="Animation.Quantum.Dialog" parent="Animation.Dialog"/>
<!-- Dialog styles -->
@@ -1131,7 +1033,7 @@ please see styles_device_defaults.xml.
<item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_holo</item>
</style>
- <style name="AlertDialog.Quantum.Light" />
+ <style name="AlertDialog.Quantum.Light"/>
<!-- Window title -->
<style name="WindowTitleBackground.Quantum">
@@ -1152,60 +1054,7 @@ please see styles_device_defaults.xml.
</style>
<style name="DialogWindowTitle.Quantum.Light">
- <item name="maxLines">1</item>
- <item name="scrollHorizontally">true</item>
<item name="textAppearance">@style/TextAppearance.Quantum.Light.DialogWindowTitle</item>
</style>
- <style name="Widget.Quantum.PreferenceFrameLayout">
- <item name="borderTop">0dip</item>
- <item name="borderBottom">@dimen/preference_fragment_padding_bottom</item>
- <item name="borderLeft">?attr/preferenceFragmentPaddingSide</item>
- <item name="borderRight">?attr/preferenceFragmentPaddingSide</item>
- </style>
-
- <style name="Widget.Quantum.MediaRouteButton">
- <item name="background">?attr/selectableItemBackground</item>
- <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_dark</item>
- <item name="minWidth">56dp</item>
- <item name="minHeight">48dp</item>
- <item name="focusable">true</item>
- <item name="contentDescription">@string/media_route_button_content_description</item>
- </style>
-
- <style name="Widget.Quantum.Light.MediaRouteButton" parent="Widget.Quantum.MediaRouteButton">
- <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
- </style>
-
- <style name="TextAppearance.Quantum.TimePicker.TimeLabel" parent="TextAppearance.Quantum">
- <item name="textSize">@dimen/timepicker_time_label_size</item>
- <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
- </style>
-
- <style name="TextAppearance.Quantum.TimePicker.AmPmLabel" parent="TextAppearance.Quantum">
- <item name="textSize">@dimen/timepicker_ampm_label_size</item>
- <item name="textAllCaps">true</item>
- <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
- <item name="textStyle">bold</item>
- </style>
-
- <style name="TextAppearance.Quantum.Light.TimePicker.TimeLabel" parent="TextAppearance.Quantum.Light">
- <item name="textSize">@dimen/timepicker_time_label_size</item>
- <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
- </style>
-
- <style name="TextAppearance.Quantum.Light.TimePicker.AmPmLabel" parent="TextAppearance.Quantum.Light">
- <item name="textSize">@dimen/timepicker_ampm_label_size</item>
- <item name="textAllCaps">true</item>
- <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
- <item name="textStyle">bold</item>
- </style>
-
- <style name="Widget.Quantum.FastScroll" parent="Widget.FastScroll">
- <item name="thumbMinWidth">0dp</item>
- <item name="thumbMinHeight">0dp</item>
- </style>
-
- <style name="Widget.Quantum.Light.FastScroll" parent="Widget.Quantum.FastScroll"/>
-
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index efa873d..fa84750 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -346,6 +346,7 @@
<java-symbol type="dimen" name="notification_title_text_size" />
<java-symbol type="dimen" name="notification_subtext_size" />
<java-symbol type="dimen" name="immersive_mode_cling_width" />
+ <java-symbol type="dimen" name="notification_quantum_rounded_rect_radius" />
<java-symbol type="string" name="add_account_button_label" />
<java-symbol type="string" name="addToDictionary" />
@@ -1637,6 +1638,8 @@
<java-symbol type="layout" name="notification_template_quantum_big_picture" />
<java-symbol type="layout" name="notification_template_quantum_big_text" />
<java-symbol type="layout" name="notification_template_quantum_inbox" />
+ <java-symbol type="color" name="notification_action_legacy_color_filter" />
+ <java-symbol type="drawable" name="notification_icon_legacy_bg_inset" />
<!-- From SystemUI -->
<java-symbol type="anim" name="push_down_in" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 4a0158e..3c4e848 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -927,7 +927,7 @@ please see themes_device_defaults.xml.
<item name="colorForeground">@android:color/bright_foreground_holo_dark</item>
<item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_dark</item>
<item name="colorBackground">@android:color/background_holo_dark</item>
- <item name="colorBackgroundCacheHint">@android:drawable/background_cache_hint_selector_holo_dark</item>
+ <item name="colorBackgroundCacheHint">@android:color/background_cache_hint_selector_holo_dark</item>
<item name="disabledAlpha">0.5</item>
<item name="backgroundDimAmount">0.6</item>
@@ -1256,7 +1256,7 @@ please see themes_device_defaults.xml.
<item name="colorForeground">@android:color/bright_foreground_holo_light</item>
<item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_light</item>
<item name="colorBackground">@android:color/background_holo_light</item>
- <item name="colorBackgroundCacheHint">@android:drawable/background_cache_hint_selector_holo_light</item>
+ <item name="colorBackgroundCacheHint">@android:color/background_cache_hint_selector_holo_light</item>
<item name="disabledAlpha">0.5</item>
<item name="backgroundDimAmount">0.6</item>
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
index d2eee28..24abd55 100644
--- a/core/res/res/values/themes_quantum.xml
+++ b/core/res/res/values/themes_quantum.xml
@@ -45,7 +45,7 @@ please see themes_device_defaults.xml.
<item name="colorForeground">@color/bright_foreground_quantum_dark</item>
<item name="colorForegroundInverse">@color/bright_foreground_quantum_light</item>
<item name="colorBackground">@color/background_quantum_dark</item>
- <item name="colorBackgroundCacheHint">@drawable/background_cache_hint_selector_quantum_dark</item>
+ <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_quantum_dark</item>
<item name="disabledAlpha">0.5</item>
<item name="backgroundDimAmount">0.6</item>
@@ -81,7 +81,7 @@ please see themes_device_defaults.xml.
<item name="textAppearanceButton">@style/TextAppearance.Quantum.Widget.Button</item>
<item name="editTextColor">?attr/textColorPrimary</item>
- <item name="editTextBackground">@drawable/edit_text_quantum_dark</item>
+ <item name="editTextBackground">@drawable/edit_text_quantum</item>
<item name="candidatesTextStyleSpans">@string/candidates_style</item>
@@ -100,9 +100,9 @@ please see themes_device_defaults.xml.
<item name="switchStyle">@style/Widget.Quantum.CompoundButton.Switch</item>
<item name="mediaRouteButtonStyle">@style/Widget.Quantum.MediaRouteButton</item>
- <item name="selectableItemBackground">@drawable/item_background_quantum_dark</item>
+ <item name="selectableItemBackground">@drawable/item_background_quantum</item>
<item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless</item>
- <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_dark</item>
+ <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum</item>
<!-- List attributes -->
<item name="listPreferredItemHeight">64dip</item>
@@ -117,17 +117,17 @@ please see themes_device_defaults.xml.
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
- <item name="listDivider">@drawable/list_divider_quantum_dark</item>
+ <item name="listDivider">@drawable/list_divider_quantum</item>
<item name="listSeparatorTextViewStyle">@style/Widget.Quantum.TextView.ListSeparator</item>
- <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_dark</item>
- <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_dark</item>
+ <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum</item>
+ <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum</item>
<item name="listChoiceBackgroundIndicator">@drawable/list_selector_holo_dark</item>
- <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum_dark</item>
+ <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum</item>
- <item name="listDividerAlertDialog">@drawable/list_divider_quantum_dark</item>
+ <item name="listDividerAlertDialog">@drawable/list_divider_quantum</item>
<item name="expandableListPreferredItemPaddingLeft">40dip</item>
<item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
@@ -136,8 +136,8 @@ please see themes_device_defaults.xml.
<item name="expandableListPreferredItemIndicatorRight">0dip</item>
<item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
<item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
- <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum_dark</item>
- <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum_dark</item>
+ <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum</item>
+ <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum</item>
<!-- Gallery attributes -->
<item name="galleryItemBackground">@drawable/gallery_item_background</item>
@@ -170,7 +170,7 @@ please see themes_device_defaults.xml.
<item name="alertDialogTheme">@style/Theme.Quantum.Dialog.Alert</item>
<item name="alertDialogStyle">@style/AlertDialog.Quantum</item>
<item name="alertDialogCenterButtons">false</item>
- <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum_dark</item>
+ <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum</item>
<!-- Presentation attributes -->
<item name="presentationTheme">@style/Theme.Quantum.Dialog.Presentation</item>
@@ -194,8 +194,8 @@ please see themes_device_defaults.xml.
<item name="scrollbarFadeDuration">250</item>
<item name="scrollbarDefaultDelayBeforeFade">300</item>
<item name="scrollbarSize">10dip</item>
- <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum_dark</item>
- <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum_dark</item>
+ <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum</item>
+ <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum</item>
<item name="scrollbarTrackHorizontal">@null</item>
<item name="scrollbarTrackVertical">@null</item>
@@ -205,7 +205,7 @@ please see themes_device_defaults.xml.
<item name="textSelectHandle">@drawable/text_select_handle_middle</item>
<item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
<item name="textSuggestionsWindowStyle">@style/Widget.Quantum.TextSuggestionsPopupWindow</item>
- <item name="textCursorDrawable">@drawable/text_cursor_quantum_dark</item>
+ <item name="textCursorDrawable">@drawable/text_cursor_quantum</item>
<!-- Widget styles -->
<item name="absListViewStyle">@style/Widget.Quantum.AbsListView</item>
@@ -290,7 +290,7 @@ please see themes_device_defaults.xml.
<item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
<item name="actionModeBackground">@color/theme_color_700</item>
<item name="actionModeSplitBackground">@color/theme_color_700</item>
- <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum_dark</item>
+ <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum</item>
<item name="actionBarTabStyle">@style/Widget.Quantum.ActionBar.TabView</item>
<item name="actionBarTabBarStyle">@style/Widget.Quantum.ActionBar.TabBar</item>
<item name="actionBarTabTextStyle">@style/Widget.Quantum.ActionBar.TabText</item>
@@ -300,21 +300,21 @@ please see themes_device_defaults.xml.
<item name="actionBarSize">@dimen/action_bar_default_height</item>
<item name="actionModePopupWindowStyle">@style/Widget.Quantum.PopupWindow.ActionMode</item>
<item name="actionBarWidgetTheme">@null</item>
- <item name="actionBarItemBackground">@drawable/item_background_borderless_quantum_dark</item>
+ <item name="actionBarItemBackground">@drawable/item_background_quantum</item>
- <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum_dark</item>
- <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum_dark</item>
- <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum_dark</item>
- <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum_dark</item>
- <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum_dark</item>
- <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum_dark</item>
- <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum_dark</item>
+ <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum</item>
+ <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum</item>
+ <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum</item>
+ <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum</item>
+ <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum</item>
+ <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum</item>
+ <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum</item>
<item name="dividerVertical">?attr/listDivider</item>
<item name="dividerHorizontal">?attr/listDivider</item>
- <item name="buttonBarStyle">@style/Quantum.ButtonBar</item>
+ <item name="buttonBarStyle">@style/Widget.Quantum.ButtonBar</item>
<item name="buttonBarButtonStyle">?attr/borderlessButtonStyle</item>
- <item name="segmentedButtonStyle">@style/Quantum.SegmentedButton</item>
+ <item name="segmentedButtonStyle">@style/Widget.Quantum.SegmentedButton</item>
<!-- SearchView attributes -->
<item name="searchDropdownBackground">@drawable/search_dropdown_dark</item>
@@ -349,11 +349,20 @@ please see themes_device_defaults.xml.
<item name="datePickerStyle">@style/Widget.Quantum.DatePicker</item>
<!-- TODO: This belongs in a FastScroll style -->
- <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum_light</item>
+ <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum</item>
<item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
<item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
- <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum_dark</item>
+ <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum</item>
<item name="fastScrollOverlayPosition">atThumb</item>
+
+ <!-- Color palette -->
+ <item name="colorControlNormal">@color/control_normal_foreground_quantum_dark</item>
+ <item name="colorControlActivated">@color/control_activated_foreground_quantum_dark</item>
+ <item name="colorButtonNormal">@color/btn_default_normal_quantum_dark</item>
+ <item name="colorButtonPressed">@color/btn_default_pressed_quantum_dark</item>
+ <!-- TODO: Remove these attrs and move into button style. -->
+ <item name="colorButtonNormalColored">@color/theme_color_500</item>
+ <item name="colorButtonPressedColored">@color/theme_color_300</item>
</style>
<!-- Quantum Paper theme (light version). -->
@@ -361,7 +370,7 @@ please see themes_device_defaults.xml.
<item name="colorForeground">@color/bright_foreground_quantum_light</item>
<item name="colorForegroundInverse">@color/bright_foreground_quantum_dark</item>
<item name="colorBackground">@color/background_quantum_light</item>
- <item name="colorBackgroundCacheHint">@drawable/background_cache_hint_selector_quantum_light</item>
+ <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_quantum_light</item>
<item name="disabledAlpha">0.5</item>
<item name="backgroundDimAmount">0.6</item>
@@ -398,7 +407,7 @@ please see themes_device_defaults.xml.
<item name="textAppearanceButton">@style/TextAppearance.Quantum.Light.Widget.Button</item>
<item name="editTextColor">?attr/textColorPrimary</item>
- <item name="editTextBackground">@drawable/edit_text_quantum_light</item>
+ <item name="editTextBackground">@drawable/edit_text_quantum</item>
<item name="candidatesTextStyleSpans">@string/candidates_style</item>
@@ -418,9 +427,9 @@ please see themes_device_defaults.xml.
<item name="switchStyle">@style/Widget.Quantum.Light.CompoundButton.Switch</item>
<item name="mediaRouteButtonStyle">@style/Widget.Quantum.Light.MediaRouteButton</item>
- <item name="selectableItemBackground">@drawable/item_background_quantum_light</item>
+ <item name="selectableItemBackground">@drawable/item_background_quantum</item>
<item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless</item>
- <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_light</item>
+ <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum</item>
<!-- List attributes -->
<item name="listPreferredItemHeight">64dip</item>
@@ -435,15 +444,15 @@ please see themes_device_defaults.xml.
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
- <item name="listDivider">@drawable/list_divider_quantum_light</item>
+ <item name="listDivider">@drawable/list_divider_quantum</item>
<item name="listSeparatorTextViewStyle">@style/Widget.Quantum.Light.TextView.ListSeparator</item>
- <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_light</item>
- <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_light</item>
+ <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum</item>
+ <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum</item>
<item name="listChoiceBackgroundIndicator">@drawable/list_selector_holo_light</item>
- <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum_light</item>
+ <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum</item>
<item name="expandableListPreferredItemPaddingLeft">40dip</item>
<item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
@@ -453,9 +462,9 @@ please see themes_device_defaults.xml.
<item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
<item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
- <item name="listDividerAlertDialog">@drawable/list_divider_quantum_light</item>
- <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum_light</item>
- <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum_light</item>
+ <item name="listDividerAlertDialog">@drawable/list_divider_quantum</item>
+ <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum</item>
+ <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum</item>
<!-- Gallery attributes -->
<item name="galleryItemBackground">@drawable/gallery_item_background</item>
@@ -487,7 +496,7 @@ please see themes_device_defaults.xml.
<item name="alertDialogTheme">@style/Theme.Quantum.Light.Dialog.Alert</item>
<item name="alertDialogStyle">@style/AlertDialog.Quantum.Light</item>
<item name="alertDialogCenterButtons">false</item>
- <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum_light</item>
+ <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum</item>
<!-- Presentation attributes -->
<item name="presentationTheme">@style/Theme.Quantum.Light.Dialog.Presentation</item>
@@ -511,8 +520,8 @@ please see themes_device_defaults.xml.
<item name="scrollbarFadeDuration">250</item>
<item name="scrollbarDefaultDelayBeforeFade">300</item>
<item name="scrollbarSize">10dip</item>
- <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum_light</item>
- <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum_light</item>
+ <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum</item>
+ <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum</item>
<item name="scrollbarTrackHorizontal">@null</item>
<item name="scrollbarTrackVertical">@null</item>
@@ -522,7 +531,7 @@ please see themes_device_defaults.xml.
<item name="textSelectHandle">@drawable/text_select_handle_middle</item>
<item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
<item name="textSuggestionsWindowStyle">@style/Widget.Quantum.Light.TextSuggestionsPopupWindow</item>
- <item name="textCursorDrawable">@drawable/text_cursor_quantum_light</item>
+ <item name="textCursorDrawable">@drawable/text_cursor_quantum</item>
<!-- Widget styles -->
<item name="absListViewStyle">@style/Widget.Quantum.Light.AbsListView</item>
@@ -610,7 +619,7 @@ please see themes_device_defaults.xml.
<item name="actionOverflowButtonStyle">@style/Widget.Quantum.Light.ActionButton.Overflow</item>
<item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
<item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
- <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum_light</item>
+ <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum</item>
<item name="actionBarTabStyle">@style/Widget.Quantum.Light.ActionBar.TabView</item>
<item name="actionBarTabBarStyle">@style/Widget.Quantum.Light.ActionBar.TabBar</item>
<item name="actionBarTabTextStyle">@style/Widget.Quantum.Light.ActionBar.TabText</item>
@@ -620,21 +629,21 @@ please see themes_device_defaults.xml.
<item name="actionBarSize">@dimen/action_bar_default_height</item>
<item name="actionModePopupWindowStyle">@style/Widget.Quantum.Light.PopupWindow.ActionMode</item>
<item name="actionBarWidgetTheme">@null</item>
- <item name="actionBarItemBackground">@drawable/item_background_borderless_quantum_light</item>
+ <item name="actionBarItemBackground">@drawable/item_background_quantum</item>
- <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum_light</item>
- <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum_light</item>
- <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum_light</item>
- <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum_light</item>
- <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum_light</item>
- <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum_light</item>
- <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum_light</item>
+ <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum</item>
+ <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum</item>
+ <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum</item>
+ <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum</item>
+ <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum</item>
+ <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum</item>
+ <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum</item>
<item name="dividerVertical">?attr/listDivider</item>
<item name="dividerHorizontal">?attr/listDivider</item>
- <item name="buttonBarStyle">@style/Quantum.Light.ButtonBar</item>
+ <item name="buttonBarStyle">@style/Widget.Quantum.Light.ButtonBar</item>
<item name="buttonBarButtonStyle">?attr/borderlessButtonStyle</item>
- <item name="segmentedButtonStyle">@style/Quantum.Light.SegmentedButton</item>
+ <item name="segmentedButtonStyle">@style/Widget.Quantum.Light.SegmentedButton</item>
<!-- SearchView attributes -->
<item name="searchDropdownBackground">@drawable/search_dropdown_light</item>
@@ -665,11 +674,20 @@ please see themes_device_defaults.xml.
<!-- DatePicker style -->
<item name="datePickerStyle">@style/Widget.Quantum.Light.DatePicker</item>
- <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum_light</item>
+ <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum</item>
<item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
<item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
- <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum_light</item>
+ <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum</item>
<item name="fastScrollOverlayPosition">atThumb</item>
+
+ <!-- Color palette -->
+ <item name="colorControlNormal">@color/control_normal_foreground_quantum_light</item>
+ <item name="colorControlActivated">@color/control_activated_foreground_quantum_light</item>
+ <item name="colorButtonNormal">@color/btn_default_normal_quantum_light</item>
+ <item name="colorButtonPressed">@color/btn_default_pressed_quantum_light</item>
+ <!-- TODO: Remove these attrs and move into button style. -->
+ <item name="colorButtonNormalColored">@color/theme_color_500</item>
+ <item name="colorButtonPressedColored">@color/theme_color_700</item>
</style>
<!-- Variant of the quantum (light) theme that has a solid (opaque) action bar
@@ -841,7 +859,7 @@ please see themes_device_defaults.xml.
<item name="colorBackgroundCacheHint">@null</item>
- <item name="buttonBarStyle">@style/Quantum.ButtonBar.AlertDialog</item>
+ <item name="buttonBarStyle">@style/Widget.Quantum.ButtonBar.AlertDialog</item>
<item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless.Small</item>
<item name="textAppearance">@style/TextAppearance.Quantum</item>
@@ -963,7 +981,7 @@ please see themes_device_defaults.xml.
<item name="colorBackgroundCacheHint">@null</item>
- <item name="buttonBarStyle">@style/Quantum.Light.ButtonBar.AlertDialog</item>
+ <item name="buttonBarStyle">@style/Widget.Quantum.Light.ButtonBar.AlertDialog</item>
<item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless.Small</item>
<item name="textAppearance">@style/TextAppearance.Quantum.Light</item>
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 04f8009..e77564f 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -21,6 +21,7 @@ import static libcore.io.OsConstants.*;
import com.android.frameworks.coretests.R;
import com.android.internal.content.PackageHelper;
+import android.app.PackageInstallObserver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -31,6 +32,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
@@ -117,12 +119,12 @@ public class PackageManagerTests extends AndroidTestCase {
super.tearDown();
}
- private class PackageInstallObserver extends IPackageInstallObserver.Stub {
+ private class TestInstallObserver extends PackageInstallObserver {
public int returnCode;
private boolean doneFlag = false;
- public void packageInstalled(String packageName, int returnCode) {
+ public void packageInstalled(String packageName, Bundle extras, int returnCode) {
synchronized (this) {
this.returnCode = returnCode;
doneFlag = true;
@@ -203,7 +205,7 @@ public class PackageManagerTests extends AndroidTestCase {
public void invokeInstallPackage(Uri packageURI, int flags, GenericReceiver receiver,
boolean shouldSucceed) {
- PackageInstallObserver observer = new PackageInstallObserver();
+ TestInstallObserver observer = new TestInstallObserver();
mContext.registerReceiver(receiver, receiver.filter);
try {
// Wait on observer
@@ -261,7 +263,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
public void invokeInstallPackageFail(Uri packageURI, int flags, int expectedResult) {
- PackageInstallObserver observer = new PackageInstallObserver();
+ TestInstallObserver observer = new TestInstallObserver();
try {
// Wait on observer
synchronized (observer) {
diff --git a/docs/html/design/index.jd b/docs/html/design/index.jd
index 9ba32dd..7c7c5d9 100644
--- a/docs/html/design/index.jd
+++ b/docs/html/design/index.jd
@@ -1,4 +1,5 @@
page.title=Design
+page.viewport_width=970
header.hide=1
footer.hide=1
@jd:body
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index 3f88b9d..eb28da8 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -1,5 +1,6 @@
fullpage=true
page.title=Develop
+page.viewport_width=970
header.hide=1
carousel=1
tabbedList=1
diff --git a/docs/html/distribute/index.jd b/docs/html/distribute/index.jd
index 544fdff..6c6e113 100644
--- a/docs/html/distribute/index.jd
+++ b/docs/html/distribute/index.jd
@@ -1,4 +1,5 @@
page.title=Distribute Apps
+page.viewport_width=970
header.hide=1
@jd:body
diff --git a/docs/html/google/play-services/index.jd b/docs/html/google/play-services/index.jd
index 26b4ccc..5da0b75 100644
--- a/docs/html/google/play-services/index.jd
+++ b/docs/html/google/play-services/index.jd
@@ -71,7 +71,7 @@ announcement <a href="http://android-developers.blogspot.com/2014/03/google-play
</li>
<li><strong>Analytics</strong> - Google Analytics and Tag Manager are now part of Google Play services.
<ul>
- <li><a href="http://developers.google.com/analytics/devguides/collection/android/v3/" class="external-link">Getting Started with the Analytics API in Android</a></li>
+ <li><a href="http://developers.google.com/analytics/devguides/collection/android/v4/" class="external-link">Getting Started with the Analytics API in Android</a></li>
<li><a href="/reference/com/google/android/gms/analytics/package-summary.html">Analytics API reference</a></li>
<li><a href="http://developers.google.com/tag-manager/android/" class="external-link">Getting Started with the Tag Manager API in Android</a></li>
<li><a href="/reference/com/google/android/gms/tagmanager/package-summary.html">Tag Manager API reference</a></li>
diff --git a/docs/html/images/tools/as-buildvariants.png b/docs/html/images/tools/as-buildvariants.png
new file mode 100644
index 0000000..a245163
--- /dev/null
+++ b/docs/html/images/tools/as-buildvariants.png
Binary files differ
diff --git a/docs/html/images/tools/as-demoflavordirs.png b/docs/html/images/tools/as-demoflavordirs.png
new file mode 100644
index 0000000..9d36a6d
--- /dev/null
+++ b/docs/html/images/tools/as-demoflavordirs.png
Binary files differ
diff --git a/docs/html/images/tools/as-gradlebutton.png b/docs/html/images/tools/as-gradlebutton.png
new file mode 100644
index 0000000..091b935
--- /dev/null
+++ b/docs/html/images/tools/as-gradlebutton.png
Binary files differ
diff --git a/docs/html/images/tools/as-gradleconsole.png b/docs/html/images/tools/as-gradleconsole.png
new file mode 100644
index 0000000..c676c94
--- /dev/null
+++ b/docs/html/images/tools/as-gradleconsole.png
Binary files differ
diff --git a/docs/html/images/tools/as-gradlepanel.png b/docs/html/images/tools/as-gradlepanel.png
new file mode 100644
index 0000000..a409462
--- /dev/null
+++ b/docs/html/images/tools/as-gradlepanel.png
Binary files differ
diff --git a/docs/html/images/tools/as-gradlesync.png b/docs/html/images/tools/as-gradlesync.png
new file mode 100644
index 0000000..b312359
--- /dev/null
+++ b/docs/html/images/tools/as-gradlesync.png
Binary files differ
diff --git a/docs/html/images/tools/as-mainscreen.png b/docs/html/images/tools/as-mainscreen.png
new file mode 100644
index 0000000..da399d7
--- /dev/null
+++ b/docs/html/images/tools/as-mainscreen.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index baeaa5b..99a469a 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -1,4 +1,5 @@
fullpage=true
+page.viewport_width=970
no_footer_links=true
carousel=true
excludeFromSuggestions=true
@@ -20,7 +21,7 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3
<li class="item carousel-home">
<div class="content-left col-10" style="width:580px;">
- <a href="{@docRoot}design/patterns/new.html">
+ <a href="{@docRoot}wear/index.html">
<img src="{@docRoot}images/home/aw_dac.png" style="margin-top:50px" >
</a>
</div>
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 1f5ca11..e4cf1bc 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -35,10 +35,10 @@ Software</strong>.</li>
<li>In the Add Repository dialog that appears, enter "ADT Plugin" for the <em>Name</em> and the
following URL for the <em>Location</em>:
<pre>https://dl-ssl.google.com/android/eclipse/</pre>
+ <p class="note"><strong>Note:</strong> The Android Developer Tools update site requires
+ a secure connection. Make sure the update site URL you enter starts with HTTPS.</p>
</li>
- <li>Click <strong>OK</strong>.
- <p>If you have trouble acquiring the plugin, try using "http" in the Location URL,
-instead of "https" (https is preferred for security reasons).</p></li>
+ <li>Click <strong>OK</strong>.</li>
<li>In the Available Software dialog, select the checkbox next to Developer Tools and click
<strong>Next</strong>.</li>
<li>In the next window, you'll see a list of the tools to be downloaded. Click
@@ -139,23 +139,16 @@ Software</strong>, uncheck "Contact all update sites during install to find requ
<h2 id="Troubleshooting">Troubleshooting ADT Installation</h2>
-<p> If you are having trouble downloading the ADT plugin after following the
-steps above, here are some suggestions: </p>
-
-<ul>
- <li>If Eclipse can not find the remote update site containing the ADT plugin,
-try changing the remote site URL to use http, rather than https. That is, set
-the Location for the remote site to:
-<pre>http://dl-ssl.google.com/android/eclipse/</pre></li>
-<li>If you are behind a firewall (such as a corporate firewall), make sure that
+<p>If you are having trouble downloading the ADT plugin after following the
+steps above and you are behind a firewall (such as a corporate firewall), make sure that
you have properly configured your proxy settings in Eclipse. In Eclipse,
you can configure proxy information from the main Eclipse menu in
<strong>Window</strong> (on Mac OS X, <strong>Eclipse</strong>) &gt;
<strong>Preferences</strong> &gt; <strong>General</strong> &gt; <strong>Network
-Connections</strong>.</li>
-</ul>
+Connections</strong>.
+</p>
-<p> If you are still unable to use Eclipse to download the ADT plugin as a
+<p>If you are still unable to use Eclipse to download the ADT plugin as a
remote update site, you can download the ADT zip file to your local machine and
manually install it:</p>
diff --git a/docs/html/sdk/installing/studio-build.jd b/docs/html/sdk/installing/studio-build.jd
new file mode 100644
index 0000000..41ad5de
--- /dev/null
+++ b/docs/html/sdk/installing/studio-build.jd
@@ -0,0 +1,1065 @@
+page.title=Building your Project
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>In this document</h2>
+<ol>
+ <li><a href="#overviewBuild">Overview of the Build System</a>
+ <ol>
+ <li><a href="#buildConf">Build configuration</a></li>
+ <li><a href="#buildConv">Build by convention</a></li>
+ <li><a href="#projectModules">Projects and modules</a></li>
+ <li><a href="#dependencies">Dependencies</a></li>
+ <li><a href="#buildTasks">Build tasks</a></li>
+ <li><a href="#gradleWrapper">The Gradle wrapper</a></li>
+ </ol>
+ </li>
+ <li><a href="#creatingBuilding">Create and Build a Project</a>
+ <ol>
+ <li><a href="#createProject">Create a project</a></li>
+ <li><a href="#projectStructure">Project structure</a></li>
+ <li><a href="#addLibModule">Add a library module</a></li>
+ <li><a href="#buildProject">Build the project</a></li>
+ <li><a href="#buildCmd">Build from the command line</a></li>
+ </ol>
+ </li>
+ <li><a href="#configBuild">Configure the Build</a>
+ <ol>
+ <li><a href="#buildFileBasics">Build file basics</a></li>
+ <li><a href="#declareDeps">Declare dependencies</a></li>
+ <li><a href="#runProguard">Run ProGuard</a></li>
+ <li><a href="#configureSigning">Configure signing settings</a></li>
+ <li><a href="#workBuildVariants">Work with build variants</a></li>
+ </ol>
+ </li>
+ <li><a href="#reference">Reference</a></li>
+</ol>
+<h2>See also</h2>
+<ul>
+<li><a href="{@docRoot}sdk/installing/studio.html">
+Getting Started with Android Studio</a></li>
+<li><a href="{@docRoot}sdk/installing/studio-tips.html">
+Android Studio Tips and Tricks</a></li>
+<li><a href="{@docRoot}sdk/installing/migrate.html">
+Migrating from Eclipse</a></li>
+</div>
+</div>
+
+<a class="notice-developers-video"
+href="https://developers.google.com/events/io/sessions/324603352">
+<div>
+ <h3>Video</h3>
+ <p>What's New in Android Developer Tools</p>
+</div>
+</a>
+
+<p>The Android Studio build system is the toolkit you use to build, test, run and package
+your apps. The build system is independent from Android Studio, so you can invoke it from Android
+Studio or from the command line. After you write your application, you can use the features
+of the build system to:</p>
+
+<ul>
+ <li>Customize, configure, and extend the build process.</li>
+ <li>Create multiple APKs for your app with different features using the same project.</li>
+ <li>Reuse code and resources.</li>
+</ul>
+
+<p>The flexibility of the Android Studio build system enables you to achieve all of this without
+modifying your app's core project files.</p>
+
+
+<h2 id="overviewBuild">Overview of the Build System</h2>
+
+<p>The Android Studio build system consists of an Android plugin for <em>Gradle</em>.
+<a href="http://www.gradle.org/">Gradle</a> is an advanced build toolkit that manages dependencies
+and allows you to define custom build logic. Many software projects use Gradle to manage their
+builds. The Android plugin for Gradle does not depend on Android Studio, although Android Studio
+is fully integrated with it. This means that:</p>
+
+<ul>
+ <li>You can build your Android apps from the command line on your machine or on machines
+ where Android Studio is not installed (such as continuous integration servers).</li>
+ <li>You can build your Android apps from Android Studio with the same custom build
+ configuration and logic as when you build from the command line.</li>
+</ul>
+
+<p>The output of the build is the same whether you are building a project from the command line,
+on a remote machine, or using Android Studio.</p>
+
+<h3 id="buildConf">Build configuration</h3>
+
+<p>The build configuration for your project is defined inside <em>Gradle build files</em>,
+which are plain text files that use the syntax and options from Gradle and the Android plugin
+to configure the following aspects of your build:</p>
+
+<ul>
+ <li><em>Build variants</em>. The build system can generate multiple APKs with different
+ configurations for the same project. This is useful when you want to build different
+ versions of your application without having to create a separate project for each of
+ them.</li>
+ <li><em>Dependencies</em>. The build system manages project dependencies and supports
+ dependencies from your local filesystem and from remote repositories. This prevents you
+ from having to search, download, and copy binary packages for your dependencies into your
+ project directory.</li>
+ <li><em>Manifest entries</em>. The build system enables you to specify values for some
+ elements of the manifest file in the build configuration. These new values override the
+ existing values in the manifest file. This is useful if you want to generate multiple APKs
+ for your project where each of them has a different package name, minimum SDK version, or
+ target SDK version.</li>
+ <li><em>Signing</em>. The build system enables you to specify signing settings in the build
+ configuration, and it can sign your APKs during the build process.</li>
+ <li><em>ProGuard</em>. The build system enables you to specify a different
+ <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> rules
+ file for each build variant. The build system can run ProGuard to obfuscate your classes
+ during the build process.</li>
+ <li><em>Testing</em>. The build system generates a test APK from the test sources in your
+ project, so you do not have to create a separate test project. The build system can run
+ your tests during the build process.</li>
+</ul>
+
+<p>Gradle build files use <em>Groovy</em> syntax.
+<a href="http://groovy.codehaus.org/">Groovy</a> is a dynamic language that you can use to
+define custom build logic and to interact with the Android-specific elements provided by the
+Android plugin for Gradle.</p>
+
+<h3 id="buildConv">Build by convention</h3>
+
+<p>The Android Studio build system assumes <em>sensible defaults</em> for the project structure
+and other build options. If your project adheres to these conventions, your Gradle build files are
+very simple. When some these conventions do not apply to your project, the flexibility of the
+build system allows you to configure almost every aspect of the build process. For example, if
+the sources for your project are located in a different directory than the default, you can
+specify this location in the build file.</p>
+
+<h3 id="projectModules">Projects and modules</h3>
+
+<p>A <em>project</em> in Android Studio represents a complete Android app. Android Studio
+projects consist of one or more modules. A <em>module</em> is a component of your app that you can
+build, test, or debug independently. Modules contain the source code and resources for your app.
+Android Studio projects contain three kinds of modules:</p>
+
+<ul>
+ <li><em>Java library modules</em> contain reusable code. The build system generates a
+ JAR package for Java library modules.</li>
+ <li><em>Android library modules</em> contain reusable Android-specific code and resources.
+ The build system generates an AAR (Android ARchive) package for library modules.</li>
+ <li><em>Android application modules</em> contain application code and may depend on library
+ modules, although many Android apps consists of only one application module. The build
+ system generates an APK package for application modules.</li>
+</ul>
+
+<p>Android Studio projects contain a top-level Gradle build file that lists all the modules in
+the project, and each module contains its own Gradle build file.</p>
+
+<h3 id="dependencies">Dependencies</h3>
+
+<p>The Android Studio build system manages project dependencies and supports module dependencies,
+local binary dependencies, and remote binary dependencies.</p>
+
+<dl>
+ <dt><em>Module Dependencies</em></dt>
+ <dd><p>A project module can include in its build file a list of other modules it depends on.
+ When you build this module, the build system assembles and includes the required
+ modules.</p></dd>
+ <dt><em>Local Dependencies</em></dt>
+ <dd><p>If you have binary archives in your local filesystem that a module depends on, such as
+ JAR files, you can declare these dependencies in the build file for that
+ module.</p></dd>
+ <dt><em>Remote Dependencies</em></dt>
+ <dd><p>When some of your dependencies are available in a remote repository, you do not have
+ to download them and copy them into your project. The Android Studio build system supports
+ remote <em>Maven</em> dependencies. <a href="http://maven.apache.org/">Maven</a> is a
+ popular software project management tool that helps organize project dependencies using
+ repositories.</p>
+ <p>Many popular software libraries and tools are available in public Maven repositories.
+ For these dependencies you only have to specify their Maven coordinates, which uniquely
+ identify each element in a remote repository. The format for Maven coordinates used in the
+ build system is <code>group:name:version</code>. For example, the Maven coordinates for
+ version 16.0.1 of the Google Guava libraries are
+ <code>com.google.guava:guava:16.0.1</code>.</p>
+ <p>The <a href="http://search.maven.org">Maven Central Repository</a> is widely used to
+ distribute many libraries and tools.</p>
+ </dd>
+</dl>
+
+<h3 id="buildTasks">Build tasks</h3>
+
+<p>The Android Studio build system defines a hierarchical set of build tasks: the top-level
+tasks invoke the tasks they depend on to produce the necessary outcomes. The build system
+provides project tasks to build your app and module tasks to build modules independently.</p>
+
+<p>You can view the list of available tasks and invoke any task from Android Studio and from
+the command line, as described in
+<a href="#buildProject">Build the project in Android Studio</a> and and
+<a href="#buildCmd">Build the project from the command line</a>.</p>
+
+<h3 id="gradleWrapper">The Gradle wrapper</h3>
+
+<p>Android Studio projects contain the <em>Gradle wrapper</em>, which consists of:</p>
+
+<ul>
+ <li>A JAR file</li>
+ <li>A properties file</li>
+ <li>A shell script for Windows platforms</li>
+ <li>A shell script for Mac and Linux platforms</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> You should submit all of these files to your source
+control system.</p>
+
+<p>Using the Gradle wrapper (instead of the local Gradle installation) ensures that
+you always run the version of Gradle defined in the properties file. To configure your project
+to use a newer version of Gradle, edit the properties file and specify the new version there.
+
+<p>Android Studio reads the properties file from the Gradle wrapper directory inside your project
+and runs the wrapper from this directory, so you can seamlessly work with multiple projects
+that require different versions of Gradle.</p>
+
+<p class="note"><strong>Note:</strong> Android Studio does not use the shell scripts, so any
+changes you make to them won't work when building from the IDE. You should define your custom
+logic inside Gradle build files instead.</p>
+
+<p>You can run the shell scripts to build your project from the command line on your development
+machine and on other machines where Android Studio is not installed.</p>
+
+
+<h2 id="creatingBuilding">Create and Build an Android Studio Project</h2>
+
+<p>This section builds on the concepts presented above and shows you how to:</p>
+
+<ul>
+ <li>Create projects and modules.</li>
+ <li>Work with the project structure.</li>
+ <li>Edit build files to configure the build process.</li>
+ <li>Build and run your app.</li>
+</ul>
+
+<h3 id="createProject">Create a project in Android Studio</h3>
+
+<p>To create a new project in Android Studio:</p>
+
+<ol>
+ <li>Click <strong>File</strong> and select <strong>New Project</strong>.</li>
+ <li>In the window that appears, enter "BuildSystemExample" in the <em>Application</em>
+ name field.</li>
+ <li>Leave the rest of the values unchanged and click <strong>Next</strong>.</li>
+ <li>Leave the default icon settings unchanged and click <strong>Next</strong>.</li>
+ <li>Select <em>Blank Activity</em> and click <strong>Next</strong>.</li>
+ <li>Leave the default activity and layout names unchanged and click
+ <strong>Finish</strong>.</li>
+</ol>
+
+<p>Figure 1 shows how the Android Studio window looks like after creating the project.</p>
+
+<img src="{@docRoot}images/tools/as-mainscreen.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> Previewing your app.</p>
+
+<h3 id="projectStructure">The project structure</h3>
+
+<p>Android Studio projects contain an application module by default (<code>app</code>).
+Table 1 lists where the main components of your app are located inside this module.</p>
+
+<p class="table-caption" id="table1">
+<strong>Table 1.</strong> Default location of the components in an application module.</p>
+<table>
+ <tr>
+ <th scope="col">Component</th>
+ <th scope="col">Location</th>
+ </tr>
+ <tr>
+ <td>Source files</td>
+ <td><code>app/src/main/java/&lt;package>/</code></td>
+ </tr>
+ <tr>
+ <td>Resource files</td>
+ <td><code>app/src/main/res/</code></td>
+ </tr>
+ <tr>
+ <td>Manifest file</td>
+ <td><code>app/src/main/AndroidManifest.xml</code></td>
+ </tr>
+ <tr>
+ <td>Build file</td>
+ <td><code>app/build.gradle</code></td>
+ </tr>
+</table>
+
+<p>When you add additional modules to your project, the directory structure for each module is
+similar to the one shown in table 1, replacing <code>app</code> by the name of the module.</p>
+
+<h3 id="addLibModule">Add a library module</h3>
+
+<p>This section shows you how to add a library module to your project and how to add this
+library as a dependency of an application module.</p>
+
+<h4>Create a new library module</h4>
+
+<p>It is good development practice to group functionality that you may reuse in other apps inside
+a library module. To create a library module inside the <code>BuildSystemExample</code>
+project:</p>
+
+<ol>
+ <li>Click <strong>File</strong> and select <strong>New Module</strong>.</li>
+ <li>On the window that appears, select <strong>Android Library</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Leave the default module name (<code>lib</code>) unchanged and click
+ <strong>Next</strong>.</li>
+ <li>Select <em>Blank Activity</em> and click <strong>Next</strong>.</li>
+ <li>Type "LibActivity1" on the <em>Activity Name</em> field and click
+ <strong>Finish</strong>.</li>
+</ol>
+
+<p>The project now contains two modules, <code>app</code> and <code>lib</code>, with one activity
+in each module.</p>
+
+<h4 id="openActFromLib">Open an activity from a library module</h4>
+
+<p>Library modules contain activities and other logic that one or more application modules reuse.
+In this example, <code>MainActivity</code> in the app module opens <code>LibActivity1</code>
+from the <code>lib</code> module. To open <code>LibActivity1</code> from
+<code>MainActivity</code>:</p>
+
+<ol>
+ <li>
+ <p>Edit the layout file for <code>MainActivity</code> in the <code>app</code> module.
+ This file is located in <code>app/src/main/res/layout/activity_main.xml</code>. Replace
+ the contents of this file with the following:</p>
+ <p><pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="com.buildsystemexample.app.MainActivity">
+
+ &lt;Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button1"
+ android:onClick="onButton1Clicked"/>
+
+&lt;/LinearLayout>
+</pre></p>
+ </li>
+ <li>
+ In this layout file, click on the line that contains
+ <code>android:text="@string/button1"</code> and press <strong>Alt+Enter</strong>. Follow
+ the suggestion from Android Studio to add a string resource with the value
+ "Open LibActivity1".
+ </li>
+ <li>
+ In this layout file, click on the line that contains
+ <code>android:onClick="onButton1Clicked"</code> and press <strong>Alt+Enter</strong>.
+ Follow the suggestion from Android Studio to add the <code>onButton1Clicked</code>
+ method to <code>MainActivity</code>.
+ </li>
+ <li>
+ <p>Copy the following code inside the <code>onButton1Clicked</code> method in
+ <code>MainActivity</code>:</p>
+ <p><pre>
+public void onButton1Clicked(View view) {
+ Intent intent = new Intent(this, LibActivity1.class);
+ startActivity(intent);
+}</pre></p>
+ </li>
+ <li>
+ Click on <code>LibActivity1</code> in the first line inside the
+ <code>onButton1Clicked</code> method of <code>MainActivity</code> and press
+ <strong>Alt+Enter</strong>. Follow the suggestion from Android Studio to add an import
+ for <code>LibActivity1</code> from the lib module.
+ </li>
+</ol>
+
+<p>When the user taps the <strong>Open LibActivity1</strong> button on <code>MainActivity</code>
+(from the <code>app</code> module), <code>LibActivity1</code> (from the <code>lib</code> module)
+starts.</p>
+
+<h4>Add a dependency on a library module</h4>
+
+<p>The <code>app</code> module now depends on the <code>lib</code> module, but the build system
+does not know about this yet. Edit the build file for the <code>app</code> module (
+<code>app/build.gradle</code>) and add a dependency on the <code>lib</code> module:</p>
+
+<pre>
+...
+dependencies {
+ ...
+ compile project(":lib")
+}
+</pre>
+
+<p>The <code>lib</code> module can still be built and tested independently, and the build system
+creates an AAR package for it that you could reuse in other projects.</p>
+
+<h3 id="buildProject">Build the project in Android Studio</h3>
+
+<p>To build the project on Android Studio, click <strong>Build</strong> and select
+<strong>Make Project</strong>. The status bar at the bottom of the window shows the current
+progress of the build:</p>
+
+<p><code>Gradle: Executing tasks: [:app:assembleDebug, :lib:bundleDebug]</code></p>
+
+<p class="note">If your project uses product flavors, Android Studio invokes the task for the
+selected build variant. For more information, see <a href="#workBuildVariants">Work with build
+variants.</a></p>
+
+<p>Click <img src="{@docRoot}images/tools/as-gradlebutton.png" alt=""
+style="vertical-align:bottom;margin:0;"/> on the bottom
+right part of the window to show the <em>Gradle Console</em>, as shown in figure 2.</p>
+
+<img src="{@docRoot}images/tools/as-gradleconsole.png" alt="" />
+<p class="img-caption"><strong>Figure 2.</strong> The Gradle Console in Android Studio.</p>
+
+<p>The Gradle Console shows the build tasks and subtasks that the build system runs for
+Android Studio. If the build fails, you can find more details on the console. To hide the Gradle
+Console, click <img src="{@docRoot}images/tools/as-gradlebutton.png" alt=""
+style="vertical-align:bottom;margin:0;"/> again.</p>
+
+<p>To view the list of all available build tasks in Android Studio, click <strong>Gradle</strong>
+on the right side of the IDE window. The <em>Gradle tasks</em> panel appears as shown in
+figure 3. Double-click any build task to run it in Android Studio. To hide the <em>Gradle tasks</em>
+panel, click <strong>Gradle</strong> again.</p>
+
+<img src="{@docRoot}images/tools/as-gradlepanel.png" alt="" />
+<p class="img-caption"><strong>Figure 3.</strong> The list of build tasks in Android Studio.</p>
+
+
+<h3 id="buildCmd">Build the project from the command line</h3>
+
+<p>To build the project from the command line, open a terminal window and navigate to the project
+root. On Windows platforms, type this command:</p>
+
+<pre>
+> gradlew.bat assembleDebug
+</pre>
+
+<p>On Mac OS and Linux platforms, type these commands:</p>
+
+<pre>
+$ chmod +x gradlew
+$ ./gradlew assembleDebug
+</pre>
+
+<p>The first command (<code>chmod</code>) adds the execution permission to the Gradle wrapper
+script and is only necessary the first time you build this project from the command line.</p>
+
+<p>The output of <code>gradlew</code> is similar to the output in the Gradle Console from
+figure 2.</p>
+
+<p>The <code>assembleDebug</code> build task builds the debug version of your app and signs it
+with the default local certificate, so that you can install it on the emulator and on real devices
+for debugging purposes.</p>
+
+<p>After you build the project, the output APK for the app module is located in
+<code>app/build/apk/</code>, and the output AAR for the lib module is located in
+<code>lib/build/libs/</code>.</p>
+
+<p>To see a list of all available build tasks for your project, type this command:</p>
+
+<pre>
+$ ./gradlew tasks
+</pre>
+
+
+<h2 id="configBuild">Configure the Build</h2>
+
+<p>This section uses the <code>BuildSystemExample</code> project from the previous section and
+shows you how to:</p>
+
+<ul>
+ <li>Use the syntax from the Android plugin for Gradle in build files.</li>
+ <li>Declare dependencies.</li>
+ <li>Configure ProGuard settings.</li>
+ <li>Configure signing settings.</li>
+ <li>Work with build variants.</li>
+</ul>
+
+<h3 id="buildFileBasics">Build file basics</h3>
+
+<p>Android Studio projects contain a top-level build file and a build file for each module. The
+build files are called <code>build.gradle</code>, and they are plain text files that use
+<a href="http://groovy.codehaus.org">Groovy</a> syntax to configure the build with the elements
+provided by the Android plugin for Gradle. In most cases, you only need to edit the build files
+at the module level. For example, the build file for the app module in the
+<code>BuildSystemExample</code> project looks like this:</p>
+
+<pre>
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.0"
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 19
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ runProguard true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), \
+ 'proguard-rules.txt'
+ }
+ }
+}
+
+dependencies {
+ compile project(":lib")
+ compile 'com.android.support:appcompat-v7:19.0.1'
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+}
+</pre>
+
+<p><code>apply plugin: 'android'</code> applies the Android plugin for Gradle to this build.
+This adds Android-specific build tasks to the top-level build tasks and makes the
+<code>android {...}</code> element available to specify Android-specific build options.</p>
+
+<p><code>android {...}</code> configures all the Android-specific build options:</p>
+
+<ul>
+ <li>The <code>compileSdkVersion</code> property specifies the compilation target.</li>
+ <li><p>The <code>buildToolsVersion</code> property specifies what version of the build tools
+ to use. To install several versions of the build tools, use the SDK Manager.</p>
+ <p class="note"><strong>Note:</strong> Always use a build tools version whose major
+ revision number is higher or equal to that of your compilation target and target SDK.</p>
+ </li>
+ <li><p>The <code>defaultConfig</code> element configures core settings and
+ entries in the manifest file (<code>AndroidManifest.xml</code>) dynamically from the
+ build system. The values in <code>defaultConfig</code> override those in the manifest
+ file.</p>
+ <p>The configuration specified in the <code>defaultConfig</code> element applies
+ to all build variants, unless the configuration for a build variant overrides some
+ of these values.</p>
+ </li>
+ <li>The <code>buildTypes</code> element controls how to build and package your app.
+ By default, the build system defines two build types: <em>debug</em> and
+ <em>release</em>. The debug build type includes debugging symbols and is signed with
+ the debug key. The release build type is not signed by default.
+ In this example the build file configures the release version to use
+ ProGuard.</li>
+</ul>
+
+<p>The <code>dependencies</code> element is outside and after the <code>android</code> element.
+This element declares the dependencies for this module. Dependencies are covered in the following
+sections.</p>
+
+<p class="note"><strong>Note:</strong> When you make changes to the build files in your project,
+Android Studio requires a project sync to import the build configuration changes. Click
+<strong>Sync Now</strong> on the yellow notification bar that appears for Android Studio
+to import the changes.</p>
+
+<img src="{@docRoot}images/tools/as-gradlesync.png" alt="" />
+<p class="img-caption"><strong>Figure 4.</strong> Sync the project in Android Studio.</p>
+
+<h3 id="declareDeps">Declare dependencies</h3>
+
+<p>The <code>app</code> module in <code>BuildSystemExample</code> declares three
+dependencies:</p>
+
+<pre>
+...
+dependencies {
+ // Module dependency
+ compile project(":lib")
+
+ // Remote binary dependency
+ compile 'com.android.support:appcompat-v7:19.0.1'
+
+ // Local binary dependency
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+}
+</pre>
+
+<p>Each of these dependencies is described below. The build system adds all the
+<code>compile</code> dependencies to the compilation classpath and includes them in the final
+package.</p>
+
+<h4>Module dependencies</h4>
+
+<p>The <code>app</code> module depends on the <code>lib</code> module, because
+<code>MainActivity</code> launches <code>LibActivity1</code> as described in
+<a href="#openActFromLib">Open an Activity from a Library Module</a>.</p>
+
+<p><code>compile project(":lib")</code> declares a dependency on the <code>lib</code>
+module of <code>BuildSystemExample</code>. When you build the <code>app</code> module,
+the build system assembles and includes the <code>lib</code> module.</p>
+
+<h4>Remote binary dependencies</h4>
+
+<p>The <code>app</code> and <code>lib</code> modules both use the <code>ActionBarActivity</code>
+class from the Android Support Library, so these modules depend on it.</p>
+
+<p><code>compile 'com.android.support:appcompat-v7:19.0.1'</code> declares a dependency on
+version 19.0.1 of the Android Support Library by specifying its Maven coordinates. The Android Support
+Library is available in the <em>Android Repository</em> package of the Android SDK. If your
+SDK installation does not have this package, download and install it using the SDK Manager.</p>
+
+Android Studio configures
+projects to use the Maven Central Repository by default. (This configuration is included in the
+top-level build file for the project.)</p>
+
+<h4>Local binary dependencies</h4>
+
+<p>The modules in <code>BuildSystemExample</code> do not use any binary dependencies from the
+local file system. If you have modules that require local binary dependencies, copy the JAR
+files for these dependencies into <code>&lt;moduleName>/libs</code> inside your project.</p>
+
+<p><code>compile fileTree(dir: 'libs', include: ['*.jar'])</code> tells the build system that any
+JAR file inside <code>app/libs</code> is a dependency and should be included in the compilation
+classpath and in the final package.</p>
+
+<p>For more information about dependencies in Gradle, see
+<a href="http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html">Dependency
+Management Basics</a> in the Gradle User Guide.</p>
+
+<h3 id="runProguard">Run ProGuard</h3>
+
+<p>The build system can run
+<a href="http://developer.android.com/tools/help/proguard.html">ProGuard</a> to obfuscate your
+classes during the build process. In <code>BuildSystemExample</code>, modify the build file for
+the app module to run ProGuard for the release build:</p>
+
+<pre>
+...
+android {
+ ...
+ buildTypes {
+ release {
+ runProguard true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), \
+ 'proguard-rules.txt'
+ }
+ }
+}
+...
+</pre>
+
+<p><code>getDefaultProguardFile('proguard-android.txt')</code> obtains the default ProGuard
+settings from the Android SDK installation. Android Studio adds the module-specific rules file
+<code>proguard-rules.txt</code> at the root of the module, where you can add custom ProGuard
+rules.</p>
+
+<p>You can build the release version of your application from the command line or using Android
+Studio. To build it from the command line, invoke the <code>assembleRelease</code> build task using
+the Gradle wrapper script (<code>gradlew assembleRelease</code>). To build it from Android
+Studio:</p>
+
+<ol>
+ <li>Click <strong>Gradle</strong> on the right side of the IDE window.</li>
+ <li>On the <em>All tasks</em> section of the sidebar that appears, expand
+ <strong>BuildSystemExample</strong>.</li>
+ <li>Expand <strong>:app</strong> and double-click <strong>assembleRelease</strong>.</li>
+</ol>
+
+<p>You can use this procedure to invoke any build task from Android Studio.</p>
+
+<h3 id="configureSigning">Configure signing settings</h3>
+
+<p>The debug and the release versions of the app differ on whether the application can be
+debugged on secure devices and on how the APK is signed. The build system signs the debug
+version with a default key and certificate using known credentials to avoid a password prompt at
+build time. The build system does not sign the release version unless you explicitly define a
+signing configuration for this build.</p>
+
+<p>To sign the release version of <code>BuildSystemExample</code>:</p>
+
+<ol>
+ <li><p>Copy your release key to the root directory of the <code>app</code> module
+ (<code>app/</code>).</p>
+ <p>This ensures that the build system can find your key when you move the location of your
+ project or when you build the project on a different machine. If you do not have a release
+ key, you can generate one as described in
+ <a href="{@docRoot}tools/publishing/app-signing.html">Signing your Applications</a>.</p>
+ </li>
+ <li><p>Add the signing configuration to the build file for the <code>app</code> module:</p>
+ <p><pre>
+...
+android {
+ ...
+ defaultConfig { ... }
+ signingConfigs {
+ release {
+ storeFile file("myreleasekey.keystore")
+ storePassword "password"
+ keyAlias "MyReleaseKey"
+ keyPassword "password"
+ }
+ }
+ buildTypes {
+ release {
+ ...
+ signingConfig signingConfigs.release
+ }
+ }
+}
+...
+</pre></p>
+ </li>
+ <li>Invoke the <code>assembleRelease</code> build task from Android Studio or from the command
+ line.</li>
+</ol>
+
+<p>The package in <code>app/build/apk/app-release.apk</code> is now signed with your release key.</p>
+
+<p class="note"><strong>Note:</strong> Including the passwords for your release key and keystore
+inside the build file is not a good security practice. Alternatively, you can configure the build
+file to obtain these passwords from environment variables or have the build process prompt you
+for these passwords.</p>
+
+<p>To obtain these passwords from environment variables:</p>
+
+<pre>
+storePassword System.getenv("KSTOREPWD")
+keyPassword System.getenv("KEYPWD")
+</pre>
+
+<p>To have the build process prompt you for these passwords if you are invoking the build from
+the command line:</p>
+
+<pre>
+storePassword System.console().readLine("\nKeystore password: ")
+keyPassword System.console().readLIne("\nKey password: ")
+</pre>
+
+<h3 id="workBuildVariants">Work with build variants</h3>
+
+<p>This section describes how the build system can help you create different versions of the same
+application from a single project. This is useful when you have a demo version and a paid version
+of your app, or if you want to distribute multiple APKs for different device configurations on
+Google Play.</p>
+
+<p>The build system uses <em>product flavors</em> to create different versions of your app. Each
+version of your app can have different features or device requirements. The build system generates
+a different APK for each version of your app.</p>
+
+<h4>Build variants</h4>
+
+<p>Each version of your app is represented in the build system by a <em>build variant</em>.
+Build variants are combinations of build types and product flavor configurations. Android Studio
+projects define two build types (<em>debug</em> and <em>release</em>) and no product flavors by
+default. These projects consists of two build variants, debug and release, and the build system
+generates an APK for each.</p>
+
+<p>The exercise in this section defines two product flavors, <em>demo</em> and <em>full</em>.
+This generates four build variants:</p>
+
+<ul>
+ <li>demo-debug</li>
+ <li>demo-release</li>
+ <li>full-debug</li>
+ <li>full-release</li>
+</ul>
+
+<p>In this case the build system creates four APKs, one for each of these build variants.</p>
+
+<p>Some projects have complex combinations of features along more than one dimension, but they
+still represent the same app. For example, in addition to having a demo and a full version of the
+app, some games may contain binaries specific to a particular CPU/ABI. The flexibility of
+the build system makes it possible to generate the following build variants for such a project:</p>
+
+<ul>
+ <li>x86-demo-debug</li>
+ <li>x86-demo-release</li>
+ <li>x86-full-debug</li>
+ <li>x86-full-release</li>
+ <li>arm-demo-debug</li>
+ <li>arm-demo-release</li>
+ <li>arm-full-debug</li>
+ <li>arm-full-release</li>
+ <li>mips-demo-debug</li>
+ <li>mips-demo-release</li>
+ <li>mips-full-debug</li>
+ <li>mips-full-release</li>
+</ul>
+
+<p>This project would consist of two build types (<em>debug</em> and <em>release</em>)
+and two <em>dimensions</em> of product flavors, one for app type (demo or full) and one for
+CPU/ABI (x86, ARM, or MIPS). For more information on flavor dimensions, see the
+<a href="http://tools.android.com/tech-docs/new-build-system/user-guide">Gradle Plugin User
+Guide</a>.</p>
+
+<h4>Source directories</h4>
+
+<p>To build each version of your app, the build system combines source code and
+resources from:</p>
+
+<ul>
+ <li><code>src/main/</code> - the main source directory (common to all variants)</li>
+ <li><code>src/&lt;buildType>/</code> - the build type source directory</li>
+ <li><code>src/&lt;flavorName>/</code> - the flavor source directory</li>
+</ul>
+
+<p>The number of flavor source directories used in the build depends on the flavor configuration
+of your project:</p>
+<ul>
+ <li><p>For projects that do not define any flavors, the build system does not use any
+ flavor source directories. For example, to generate the <em>release</em> build variant
+ in projects with no flavors, the build system uses:</p>
+ <ul>
+ <li><code>src/main/</code></li>
+ <li><code>src/release/</code> (build type)</li>
+ </ul>
+ </li>
+ <li><p>For projects that define a set of flavors, the build system uses one flavor source
+ directory. For example, to generate the <em>full-debug</em> build variant in the example
+ in this section, the build system uses:</p>
+ <ul>
+ <li><code>src/main/</code></li>
+ <li><code>src/debug/</code> (build type)</li>
+ <li><code>src/full/</code> (flavor)</li>
+ </ul>
+ </li>
+ <li><p>For projects that use flavor dimensions, the build system uses one flavor source
+ directory per dimension. For example, to generate the <em>arm-demo-release</em> build
+ variant in the previous example, the build system uses:</p>
+ <ul>
+ <li><code>src/main/</code></li>
+ <li><code>src/release/</code> (build type)</li>
+ <li><code>src/demo/</code> (flavor - app type dimension)</li>
+ <li><code>src/arm/</code> (flavor - ABI dimension)</li>
+ </ul>
+ </li>
+</ul>
+
+<p class="note"><strong>Note:</strong> The build type and flavor source directories are optional,
+and Android Studio does not create these directories for you. The build system does not use them
+if they are not present.</p>
+
+<p>The source code from these directories is used together to generate the output for a build
+variant. You can have classes with the same name in different directories as long as those
+directories are not used together in the same variant. The exercise in this section shows you
+how to create different versions of the same activity class in different variants.</p>
+
+<p>The build system merges all the manifests into a single manifest, so each build variant
+can define different components or permissions in the final manifest.</p>
+
+<p>The build system merges all the resources from the all the source directories. If different
+folders contain resources with the same name for a build variant, the priority order is the
+following: build type resources override those from the product flavor, which override the
+resources in the main source directory.</p>
+
+<p class="note"><strong>Note:</strong> Build variants enable you to reuse common activities,
+application logic, and resources across different versions of your app.</p>
+
+<h4>Product flavors in BuildSystemExample</h4>
+
+<p>To create different versions of your app:</p>
+
+<ol>
+ <li>Define product flavors in the build file.</li>
+ <li>Create additional source directories for each flavor.</li>
+ <li>Add the flavor-specific sources to your project.</li>
+</ol>
+
+<p>The rest of this section walks you through these steps in detail using the
+<code>BuildSystemExample</code> project. You create two flavors of the
+<code>BuildSystemExample</code> app, a demo flavor and a full flavor. Both flavors share
+<code>MainActivity</code>, to which you add a new button to launch a new activity,
+<code>SecondActivity</code>. This new activity is different for each flavor, so you simulate a
+situation where the new activity would have more features in the full flavor than in the demo
+flavor. At the end of the exercise, you end up with two different APKs, one for each flavor.</p>
+
+<h4>Define product flavors in the build file</h4>
+
+<p>To define two product flavors, edit the build file for the app module to add the following
+configuration:</p>
+
+<pre>
+...
+android {
+ ...
+ defaultConfig { ... }
+ signingConfigs { ... }
+ buildTypes { ... }
+ productFlavors {
+ demo {
+ packageName "com.buildsystemexample.app.demo"
+ versionName "1.0-demo"
+ }
+ full {
+ packageName "com.buildsystemexample.app.full"
+ versionName "1.0-full"
+ }
+ }
+}
+...
+</pre>
+
+<p>The product flavor definitions support the same properties as the <code>defaultConfig</code>
+element. The base configuration for all flavors is specified in <code>defaultConfig</code>, and each
+flavor can override any value. The build file above assigns a different package name to each flavor:
+since each flavor definition creates a different app, they each need a distinct package name.</p>
+
+<p class="note"><strong>Note:</strong> To distribute your app using
+<a href="{@docRoot}google/play/publishing/multiple-apks.html">Multiple APK Support</a> in
+Google Play, assign the same package name to all variants and give each variant a different
+<code>versionCode</code>. To distribute different variants of your app as separate apps in Google
+Play, assign a different package name to each variant.</p>
+
+<h4>Add additional source directories for each flavor</h4>
+
+<p>Now you create source folders and add a <code>SecondActivity</code> to each flavor. To create
+the source directory structure for the demo flavor:</p>
+
+<ol>
+ <li>On the <em>Project</em> panel, expand <strong>BuildSystemExample</strong>, and then expand
+ the <strong>app</strong> directory.</li>
+ <li>Right click the <strong>src</strong> directory under <em>app</em> and select
+ <strong>New</strong> > <strong>Directory</strong>.</li>
+ <li>Enter "demo" as the name of the new directory and click <strong>OK</strong>.</li>
+ <li><p>Similarly, create the following directories:</p>
+ <ul>
+ <li><code>app/src/demo/java</code></li>
+ <li><code>app/src/demo/res</code></li>
+ <li><code>app/src/demo/res/layout</code></li>
+ <li><code>app/src/demo/res/values</code></li>
+ </ul>
+ </li>
+</ol>
+
+<p>The resulting directory structure looks like figure 5.</p>
+
+<img src="{@docRoot}images/tools/as-demoflavordirs.png" alt="" />
+<p class="img-caption"><strong>Figure 5.</strong> New source directories for the demo flavor.</p>
+
+<h4>Add a new activity to each flavor</h4>
+
+<p>To add <code>SecondActivity</code> to the <code>demo</code> flavor:</p>
+
+<ol>
+ <li>On the <em>Project</em> panel, right click on the <strong>app</strong> module and select
+ <strong>New</strong> > <strong>Activity</strong>.</li>
+ <li>Select <strong>Blank Activity</strong> and click <strong>Next</strong>.</li>
+ <li>Enter "SecondActivity" as the activity name.</li>
+ <li>Enter "com.buildsystemexample.app" as the package name and click
+ <strong>Finish</strong>.</li>
+ <li>Right click on the <strong>java</strong> directory under <em>app/src/demo</em> and select
+ <strong>New</strong> > <strong>Package</strong>.</li>
+ <li>Enter "com.buildsystemexample.app" as the package name and click <strong>OK</strong>.</li>
+ <li>Drag <strong>SecondActivity</strong> and drop it under the new package in
+ <em>app/src/demo/java</em>.</li>
+ <li>Accept the default values and click <strong>Refactor</strong>.</li>
+</ol>
+
+<p>To add the layout for <code>SecondActivity</code> and a strings resource to the demo flavor:</p>
+
+<ol>
+ <li>Drag <strong>activity_second.xml</strong> from <em>app/src/main/res/layout</em> and drop it
+ inside <em>app/src/demo/res/layout</em>.</li>
+ <li>Accept the default values on the window that appears and click <code>OK</code>.</li>
+ <li>Copy <strong>strings.xml</strong> from <em>app/src/main/res</em> into
+ <em>app/src/demo/res</em>.</li>
+ <li><p>Replace the contents of the new copy of <code>strings.xml</code> with the
+ following:</p>
+ <p><pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string name="hello_world">Demo version only.&lt;/string>
+&lt;/resources>
+</pre></p>
+ </li>
+</ol>
+
+<p>Now you add source folders and <code>SecondActivity</code> to the full flavor by making a copy
+of the <code>demo</code> flavor:</p>
+
+<ol>
+ <li>On the <em>Project</em> panel, right click on the <strong>demo</strong> directory under
+ <em>app/src</em> and select <strong>Copy</strong>.</li>
+ <li>Right-click on the <strong>src/</strong> directory under <em>app/</em> and select
+ <strong>Paste</strong>.</li>
+ <li>On the window that appears, enter "full" as the new name and click <strong>OK</strong>.</li>
+ <li><p>Replace the contents of <strong>strings.xml</strong> under <em>src/full/res/values</em>
+ with the following:</p>
+ <p><pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string name="hello_world">This is the full version!&lt;/string>
+&lt;/resources>
+</pre></p>
+ </li>
+</ol>
+
+<p class="note"><strong>Note:</strong> From this point on, you could develop
+<code>SecondActivity</code> independently inside each
+flavor. You can add more features to this activity in the <code>full</code> flavor.</p>
+
+<p>To work on files from a particular flavor, click on <strong>Build Variants</strong> on the left
+of the IDE window and select the flavor you want to modify in the <em>Build Variants</em> panel,
+as shown in figure 5. Android Studio may show errors in source files from flavors other than the
+one selected in the <em>Build Variants</em> panel, but this does not affect the outcome of the
+build.</p>
+
+<img src="{@docRoot}images/tools/as-buildvariants.png" alt="" />
+<p class="img-caption"><strong>Figure 6.</strong> The Build Variants panel.</p>
+
+<h4>Launch a flavor-specific activity from the main activity</h4>
+
+<p>Since the flavor-specific activity (<code>SecondActivity</code>) has the same package name and
+activity name in both flavors, you can launch it from the main activity, which is common to all
+flavors. To modify the main activity:</p>
+
+<ol>
+ <li><p>Edit <code>activity_main.xml</code> and add a new button to
+ <code>MainActivity</code>:</p>
+ <p><pre>
+&lt;LinearLayout ...>
+ ...
+ &lt;Button
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button2"
+ android:onClick="onButton2Clicked"/>
+&lt;/LinearLayout>
+</pre></p>
+ </li>
+ <li>Click on the areas marked in red in the layout file and press <strong>Alt</strong>+
+ <strong>Enter</strong>. Follow the suggestions from Android Studio to add a new string
+ resource with value “Open Second Activity” and an <code>onButton2Clicked</code> method to
+ <code>MainActivity</code>.</li>
+ <li><p>Add the following code to the <code>onButton2Clicked</code> method of
+ <code>MainActivity</code>:</p>
+ <p><pre>
+public void onButton2Clicked(View view) {
+ Intent intent = new Intent(this, SecondActivity.class);
+ startActivity(intent);
+}
+</pre></p>
+ </li>
+ <li><p>Edit the app's manifest to include a reference to <code>SecondActivity</code>:</p>
+ <p><pre>
+&lt;manifest ...>
+ &lt;application ...>
+ ...
+ &lt;activity
+ android:name="com.buildsystemexample.app.SecondActivity"
+ android:label="@string/title_activity_second" >
+ &lt;/activity>
+ &lt;/application>
+&lt;/manifest>
+</pre></p>
+ </li>
+</ol>
+
+<h4>Build output</h4>
+
+<p>The <code>BuildSystemExample</code> app is now complete. To build it, invoke the
+<code>assemble</code> task from Android Studio or from the command line.</p>
+
+<p>The build generates an APK for each build variant:
+the <code>app/build/apk/</code> directory contains packages named
+<code>app-&lt;flavor>-&lt;buildtype>.apk</code>; for example, <code>app-full-release.apk</code> and
+<code>app-demo-debug.apk</code>.</p>
+
+
+<h2 id="reference">Reference</h2>
+
+<p>The build system is very flexible and has more features than those described here. For a
+complete reference, see the
+<a href="http://tools.android.com/tech-docs/new-build-system/user-guide">Android Plugin for Gradle
+User Guide</a>.</p>
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index 7d20d5e..d106f4a 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -78,6 +78,11 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<dt>General Notes:</dt>
<dd>
<ul>
+ <li><p>Changed the URL for the Android Developer Tools update site to require HTTPS.</p>
+ <p class="note"><strong>Note:</strong> If you are
+ <a href="{@docRoot}sdk/installing/installing-adt.html">updating ADT</a>, make sure
+ you use HTTPS in the URL for the Android Developer Tools update site.</p>
+ </li>
<li>Fixed a problem where Eclipse was non-responsive for a few seconds after opening
an XML file. (<a href="http://b.android.com/67084">Issue 67084</a>)</li>
<li>Fixed a problem where the SDK Manager threw a <code>NullPointerException</code> after
@@ -88,7 +93,6 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues
<code>drawable-large-*</code> directories.</li>
<li>Fixed a problem with Nexus 5 Android virtual devices created from the command line
where the SD card file system was read-only.</li>
- <li>Changed the URL for the Android Developer Tools Update Site from HTTP to HTTPS.</li>
</ul>
</dd>
</dl>
diff --git a/docs/html/tools/support-library/index.jd b/docs/html/tools/support-library/index.jd
index 389238f..e905285 100644
--- a/docs/html/tools/support-library/index.jd
+++ b/docs/html/tools/support-library/index.jd
@@ -58,10 +58,36 @@ page.title=Support Library
<p>This section provides details about the Support Library package releases.</p>
-
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" alt=""
+/>Android Support Library, revision 19.1.0</a> <em>(March 2014)</em>
+ </p>
+ <div class="toggle-content-toggleme">
+ <dl>
+ <dt>Changes for v4 support library:</dt>
+ <dd>
+ <ul>
+ <li>Added the {@link android.support.v4.widget.SwipeRefreshLayout} class,
+ which enables users to refresh the contents of a view with a vertical
+ swipe gesture.</li>
+ <li>Fixed accessibility issues with navigation drawers.</li>
+ </ul>
+ </dd>
+
+ <dt>Changes for v7 appcompat library:</dt>
+ <dd>
+ <ul>
+ <li>Fixed background issues with the action bar.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+</div>
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt=""
/>Android Support Library, revision 19.0.1</a> <em>(December 2013)</em>
</p>
<div class="toggle-content-toggleme">
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 382165c..0e543e4 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -36,6 +36,8 @@
Tips and Tricks</a></li>
<li><a href="<?cs var:toroot ?>sdk/installing/studio-layout.html">
Using the Layout Editor</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/installing/studio-build.html">
+ Building your Project</a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>sdk/exploring.html">
diff --git a/docs/html/wear/design/index.html b/docs/html/wear/design/index.html
deleted file mode 100644
index 9952490..0000000
--- a/docs/html/wear/design/index.html
+++ /dev/null
@@ -1,607 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Design Principles of Android Wear | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Design Principles of Android Wear</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <style>
-h3 {
- padding:30px 0 10px;
-}
-</style>
-<p>
-Android wearables provide just the right information at just the right time, allowing you to be connected to the virtual world and present in the real world.</p>
-
-<img src="/wear/images/05_images.png" height="200" width="169" style="float:right;clear:right;margin:0 0 60px 60px" />
-
-<p>Here you’ll find some guidelines for designing great user experiences on the Android Wear
-platform. Designing for Android Wear is substantially different than designing for phones or
-tablets, so we’ll start by describing how your content can work in tandem with the overall
-Android Wear vision. To better understand the user experience on Android Wear, also be sure
-to read the <a href="/wear/design/user-interface.html">UI Overview</a>.</p>
-
-
-<img src="/wear/images/02_notifications.png" height="200" width="169" style="float:right;clear:right;margin:0 0 20px 60px" />
-
-
-
-<p>Android Wear experiences are:</p>
-
-<ul>
- <li><strong>Contextually aware and smart.</strong> These devices bring a new level of awareness to computing. Rather than requiring attention and input from users, Android wearables are aware of their situation and state, and helpfully display the right information at the right time. <em>Timely, relevant, specific</em>.</li>
-
- <li><strong>Glanceable.</strong> Wearable devices are used all throughout the day, even when they sit in our peripheral vision. Effective apps provide the maximum payload of information with a minimum of fuss, optimized to provide tiny snippets of relevant information throughout the day. <em>Short, sharp, immediate.</em></li>
-
- <li><strong>Zero/low interaction.</strong> Staying true to the strengths afforded by a smaller form factor, Android Wear focuses on simple interactions, only requiring input by the user when absolutely necessary. Most inputs are based around touch swipes or voice, and inputs requiring fine-grained motor skills are avoided. <em>Gestural, simple, fast.</em></li>
-
- <li><strong>Helpful.</strong> Android Wear is like a great personal assistant: it knows you and your preferences, it only interrupts you when absolutely necessary, and it’s always on hand to provide a ready answer. <em>Efficient, respectful, responsive.</em></li>
-</ul>
-
-
-<p>
-By providing a smart connection to the rest of the world while respecting the user’s attention, Android Wear feels personal and global, simple and smart, unobtrusive and ever-ready. Notifications that respect these principles will feel most at home in the overall Android Wear experience.
-</p>
-
-
-
-<h2 id="Notifications" style="clear:both">Notification UI Patterns</h2>
-
-<p>Android notifications appear as cards in the main stream and form the core of the Android Wear experience. Many of the main <a href="http://developer.android.com/design/patterns/notifications.html">Android Design guidelines for notifications</a> apply in Android Wear. Be respectful of users' attention and aware of how unnecessary interruptions will reflect on your application’s reputation.</p>
-
-<p>Omit needless text from your notifications. Design for glanceability, not reading. Use words and phrases, not sentences. Show, don't tell: where possible use simple icons, glyphs, and visualizations to convey your message.</p>
-<img src="/wear/images/circle_message2.png" height="200" style="float:right;clear:right;margin:0 0 20px 60px" />
-
-<p>In some cases, particularly with messaging applications, cards will contain dynamic content which may not fit on a single screen. In these cases the content will be automatically truncated to fit on the card and the user may tap to expand, so the full message should be provided.</p>
-
-<p>Notification priority should reflect the urgency of your notification, with only time-sensitive notifications carrying a high priority. Active notifications – that is, those that cause the device to vibrate – should only be used in cases that need the user's urgent attention or action (e.g. a time-based reminder, a message from a friend). Non-urgent notifications (e.g. a transit times card, daily pedometer count, social network updates) should be silently added to the card stream.</p>
-
-
-
-
-<h3 id="NotifictionActions" style="clear:both">Actions</h3>
-
-<img src="/wear/images/circle_message2_reply.png" height="200" style="float:right;clear:right;margin:0 0 20px 40px" />
-
-<p>Actions appear to the right of your notification, allowing the user to act on your notification. Up to three actions are permitted. The most-used action should be placed first, so that it is a single swipe away from your content.</p>
-
-<p>Actions consist of an icon and a caption. Icons should be PNG files, white on transparent background, 64 × 64 DP. Captions should be verb-driven and short, and will be automatically truncated at one line.</p>
-
-<p>Actions are optional. Many useful notifications will not need to include actions at all.</p>
-
-<p>For developer details about action buttons, see <a href="/wear/notifications/creating.html">Creating
-Notifications for Android Wear</a>.</p>
-
-
-
-
-
-
-<h3 id="Images" style="clear:both">Images</h3>
-
-<img src="/wear/images/circle_badge_B.png" height="200" style="float:right;clear:right;margin:0 0 20px 40px" />
-
-
-<p>Images appear behind cards in the stream, providing context and additional glanceability. Your image should support the core message of the notification; for example, a card about a sports team could include the team color and logo; a message from a contact should display that person's profile photo.</p>
-
-<p>Bear in mind that the card will partially cover the lower part of the image. Images should be at least 320 × 320 pixels at hdpi. Image backgrounds move when horizontally swiped, so landscape-oriented images work better on notifications that include pages or actions.</p>
-
-<p>To add large images, use <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setLargeIcon(android.graphics.Bitmap)">setLargeIcon()</a></code> with any notification, as
-shown in <a href="/wear/notifications/creating.html">Creating
-Notifications for Android Wear</a>.</p>
-
-
-
-
-
-<h3 id="AppIcons" style="clear:both">Application Icons</h3>
-
-<img src="/wear/images/07_appicons.png" height="200" style="float:right;margin:0 0 20px 60px" />
-
-<p>Your application’s launcher icon will be automatically placed on the card, identifying your notification. Do not use the notification title or background image to identify or brand your application. Instead, allow your icon to identify itself and focus on delivering a clear, succinct message in the card and image. You can choose not to display this icon using
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setHintHideIcon(boolean)"><code>setHintHideIcon()</code></a>.
-</p>
-
-
-
-
-
-
-
-<h3 id="NotificationPages" style="clear:both">Pages</h3>
-
-<p>Pages are additional cards that can appear to the right of your main card in the stream. If your core message is longer than a short snippet, do not sacrifice glanceability by packing a lot of information into your primary notification. Instead, use pages to provide additional content.</p>
-
-<img src="/wear/images/08_pages.png" height="200" style="float:left;margin:0 0 20px 0px" />
-<img src="/wear/images/09_pages.png" height="200" style="float:left;margin:0 0 20px 60px" />
-<img src="/wear/images/10_pages.png" height="200" style="float:left;margin:0 0 20px 60px" />
-
-<p style="clear:left">Pages appear immediately to the right of the main notification card. They are typically used to provide additional details or alternate views of the main card’s content. For example:</p>
-<ul>
- <li>A current weather card might provide an additional page showing a three-day forecast.</li>
- <li>A next train departure card might provide an additional page showing subsequent departures times.</li>
- <li>A daily step count card might provide an additional page showing the same measurement in calories and distance.</li>
-</ul>
-
-<p>There is no imposed limit on the number of pages you may add. However, notifications that provide actions should show no more than three pages to ensure that the actions remain easily accessible.</p>
-
-<p>Pages are optional. Many useful notifications will not need to include pages at all.</p>
-
-<p>For developer details about pages, see
-described in <a href="/wear/notifications/pages.html">Adding
-Pages to a Notification</a>.</p>
-
-
-
-
-
-<h3 id="NotificationStacks" style="clear:both">Notification Stacks</h3>
-
-<img src="/wear/images/11_bundles_B.png" height="200" style="float:right;margin:0 0 20px 60px" />
-<img src="/wear/images/11_bundles_A.png" height="200" style="float:right;margin:0 0 20px 60px" />
-
-<p>Stacks may be used to collect multiple notifications from the same application into a single stack of cards. Whereas pages are used to provide additional detail on a single notification, stacks are used to collect multiple sibling notifications together. A stack may be expanded by the user to access each individual card contained within.</p>
-
-<p>Stacks are a way of adding multiple useful notifications without overwhelming the user’s stream. If your application may produce multiple concurrent notifications, consider combining them into a stack.</p>
-
-<p>Each notification within a stack can contain separate pages and separate actions that are relevant to that specific notification. The user can access these actions after expanding that notification's card within the stack.</p>
-
-<p>For developer details about stacks, see
-described in <a href="/wear/notifications/stacks.html">Stacking
-Notifications</a>.</p>
-
-
-
-
-
-
-<h3 id="VoiceReplies" style="clear:both">Voice Replies</h3>
-
-
-<img src="/wear/images/circle_voice_B.png" height="200" style="float:right;margin:0 0 20px 40px" />
-<img src="/wear/images/circle_voice_A.png" height="200" style="float:right;margin:0 0 20px 40px" />
-
-<p>Voice replies are primarily used by messaging applications to provide a hands-free way of dictating a short message. You can also provide a up to five suggested replies or “canned responses” that are useful in a wide range of cases. These canned responses can be tapped by the user, allowing for a fast method of sending simple replies in cases where speaking may not be desirable.</p>
-
-<p>You should attempt to cover a range of simple, neutral replies in your choices. Longer voice replies may be automatically truncated in the Voice reply UI.</p>
-
-<p>For developer details about enabling voice replies, see
-described in <a href="/wear/notifications/remote-input.html">Receiving Voice Input from
-a Notification</a>.</p>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/design/index.jd b/docs/html/wear/design/index.jd
new file mode 100644
index 0000000..247cc87
--- /dev/null
+++ b/docs/html/wear/design/index.jd
@@ -0,0 +1,173 @@
+page.title=Design Principles of Android Wear
+
+@jd:body
+
+<style>
+h3 {
+ padding:30px 0 10px;
+}
+</style>
+<p>
+Android wearables provide just the right information at just the right time, allowing you to be connected to the virtual world and present in the real world.</p>
+
+<img src="{@docRoot}wear/images/05_images.png" height="200" width="169" style="float:right;clear:right;margin:0 0 60px 60px" />
+
+<p>Here you’ll find some guidelines for designing great user experiences on the Android Wear
+platform. Designing for Android Wear is substantially different than designing for phones or
+tablets, so we’ll start by describing how your content can work in tandem with the overall
+Android Wear vision. To better understand the user experience on Android Wear, also be sure
+to read the <a href="{@docRoot}wear/design/user-interface.html">UI Overview</a>.</p>
+
+
+<img src="{@docRoot}wear/images/02_notifications.png" height="200" width="169" style="float:right;clear:right;margin:0 0 20px 60px" />
+
+
+
+<p>Android Wear experiences are:</p>
+
+<ul>
+ <li><strong>Contextually aware and smart.</strong> These devices bring a new level of awareness to computing. Rather than requiring attention and input from users, Android wearables are aware of their situation and state, and helpfully display the right information at the right time. <em>Timely, relevant, specific</em>.</li>
+
+ <li><strong>Glanceable.</strong> Wearable devices are used all throughout the day, even when they sit in our peripheral vision. Effective apps provide the maximum payload of information with a minimum of fuss, optimized to provide tiny snippets of relevant information throughout the day. <em>Short, sharp, immediate.</em></li>
+
+ <li><strong>Zero/low interaction.</strong> Staying true to the strengths afforded by a smaller form factor, Android Wear focuses on simple interactions, only requiring input by the user when absolutely necessary. Most inputs are based around touch swipes or voice, and inputs requiring fine-grained motor skills are avoided. <em>Gestural, simple, fast.</em></li>
+
+ <li><strong>Helpful.</strong> Android Wear is like a great personal assistant: it knows you and your preferences, it only interrupts you when absolutely necessary, and it’s always on hand to provide a ready answer. <em>Efficient, respectful, responsive.</em></li>
+</ul>
+
+
+<p>
+By providing a smart connection to the rest of the world while respecting the user’s attention, Android Wear feels personal and global, simple and smart, unobtrusive and ever-ready. Notifications that respect these principles will feel most at home in the overall Android Wear experience.
+</p>
+
+
+
+<h2 id="Notifications" style="clear:both">Notification UI Patterns</h2>
+
+<p>Android notifications appear as cards in the main stream and form the core of the Android Wear experience. Many of the main <a href="http://developer.android.com/design/patterns/notifications.html">Android Design guidelines for notifications</a> apply in Android Wear. Be respectful of users' attention and aware of how unnecessary interruptions will reflect on your application’s reputation.</p>
+
+<p>Omit needless text from your notifications. Design for glanceability, not reading. Use words and phrases, not sentences. Show, don't tell: where possible use simple icons, glyphs, and visualizations to convey your message.</p>
+<img src="{@docRoot}wear/images/circle_message2.png" height="200" style="float:right;clear:right;margin:0 0 20px 60px" />
+
+<p>In some cases, particularly with messaging applications, cards will contain dynamic content which may not fit on a single screen. In these cases the content will be automatically truncated to fit on the card and the user may tap to expand, so the full message should be provided.</p>
+
+<p>Notification priority should reflect the urgency of your notification, with only time-sensitive notifications carrying a high priority. Active notifications – that is, those that cause the device to vibrate – should only be used in cases that need the user's urgent attention or action (e.g. a time-based reminder, a message from a friend). Non-urgent notifications (e.g. a transit times card, daily pedometer count, social network updates) should be silently added to the card stream.</p>
+
+
+
+
+<h3 id="NotifictionActions" style="clear:both">Actions</h3>
+
+<img src="{@docRoot}wear/images/circle_message2_reply.png" height="200" style="float:right;clear:right;margin:0 0 20px 40px" />
+
+<p>Actions appear to the right of your notification, allowing the user to act on your notification. Up to three actions are permitted. The most-used action should be placed first, so that it is a single swipe away from your content.</p>
+
+<p>Actions consist of an icon and a caption. Icons should be PNG files, white on transparent
+background, 32 × 32 dp (with 8 dp padding), as specified in the <a
+href="/design/style/iconography.html#action-bar">Iconography</a> design guide for action bar
+icons. Captions should be verb-driven and short, and will be automatically truncated at one line.
+</p>
+
+<p>Actions are optional. Many useful notifications will not need to include actions at all.</p>
+
+<p>For developer details about action buttons, see <a href="{@docRoot}wear/notifications/creating.html">Creating
+Notifications for Android Wear</a>.</p>
+
+
+
+
+
+
+<h3 id="Images" style="clear:both">Images</h3>
+
+<img src="{@docRoot}wear/images/circle_badge_B.png" height="200" style="float:right;clear:right;margin:0 0 20px 40px" />
+
+
+<p>Images appear behind cards in the stream, providing context and additional glanceability. Your image should support the core message of the notification; for example, a card about a sports team could include the team color and logo; a message from a contact should display that person's profile photo.</p>
+
+<p>Bear in mind that the card will partially cover the lower part of the image. Images should
+be sized as appropriate for the notification appearance on handsets, which is 64 x 64 dp. Image backgrounds move when horizontally swiped, so landscape-oriented images work better on notifications that include pages or actions.</p>
+
+<p>To add large images, use {@link android.support.v4.app.NotificationCompat.Builder#setLargeIcon
+setLargeIcon()} with any notification, as
+shown in <a href="{@docRoot}wear/notifications/creating.html">Creating
+Notifications for Android Wear</a>.</p>
+
+
+
+
+
+<h3 id="AppIcons" style="clear:both">Application Icons</h3>
+
+<img src="{@docRoot}wear/images/07_appicons.png" height="200" style="float:right;margin:0 0 20px 60px" />
+
+<p>Your application’s launcher icon will be automatically placed on the card, identifying your notification. Do not use the notification title or background image to identify or brand your application. Instead, allow your icon to identify itself and focus on delivering a clear, succinct message in the card and image. You can choose not to display this icon using
+ <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setHintHideIcon(boolean)"><code>setHintHideIcon()</code></a>.
+</p>
+
+
+
+
+
+
+
+<h3 id="NotificationPages" style="clear:both">Pages</h3>
+
+<p>Pages are additional cards that can appear to the right of your main card in the stream. If your core message is longer than a short snippet, do not sacrifice glanceability by packing a lot of information into your primary notification. Instead, use pages to provide additional content.</p>
+
+<img src="{@docRoot}wear/images/08_pages.png" height="200" style="float:left;margin:0 0 20px 0px" />
+<img src="{@docRoot}wear/images/09_pages.png" height="200" style="float:left;margin:0 0 20px 60px" />
+<img src="{@docRoot}wear/images/10_pages.png" height="200" style="float:left;margin:0 0 20px 60px" />
+
+<p style="clear:left">Pages appear immediately to the right of the main notification card. They are typically used to provide additional details or alternate views of the main card’s content. For example:</p>
+<ul>
+ <li>A current weather card might provide an additional page showing a three-day forecast.</li>
+ <li>A next train departure card might provide an additional page showing subsequent departures times.</li>
+ <li>A daily step count card might provide an additional page showing the same measurement in calories and distance.</li>
+</ul>
+
+<p>There is no imposed limit on the number of pages you may add. However, notifications that provide actions should show no more than three pages to ensure that the actions remain easily accessible.</p>
+
+<p>Pages are optional. Many useful notifications will not need to include pages at all.</p>
+
+<p>For developer details about pages, see
+described in <a href="{@docRoot}wear/notifications/pages.html">Adding
+Pages to a Notification</a>.</p>
+
+
+
+
+
+<h3 id="NotificationStacks" style="clear:both">Notification Stacks</h3>
+
+<img src="{@docRoot}wear/images/11_bundles_B.png" height="200" style="float:right;margin:0 0 20px 60px" />
+<img src="{@docRoot}wear/images/11_bundles_A.png" height="200" style="float:right;margin:0 0 20px 60px" />
+
+<p>Stacks may be used to collect multiple notifications from the same application into a single stack of cards. Whereas pages are used to provide additional detail on a single notification, stacks are used to collect multiple sibling notifications together. A stack may be expanded by the user to access each individual card contained within.</p>
+
+<p>Stacks are a way of adding multiple useful notifications without overwhelming the user’s stream. If your application may produce multiple concurrent notifications, consider combining them into a stack.</p>
+
+<p>Each notification within a stack can contain separate pages and separate actions that are relevant to that specific notification. The user can access these actions after expanding that notification's card within the stack.</p>
+
+<p>For developer details about stacks, see
+described in <a href="{@docRoot}wear/notifications/stacks.html">Stacking
+Notifications</a>.</p>
+
+
+
+
+
+
+<h3 id="VoiceReplies" style="clear:both">Voice Replies</h3>
+
+
+<img src="{@docRoot}wear/images/circle_voice_B.png" height="200" style="float:right;margin:0 0 20px 40px" />
+<img src="{@docRoot}wear/images/circle_voice_A.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>Voice replies are primarily used by messaging applications to provide a hands-free way of dictating a short message. You can also provide a up to five suggested replies or “canned responses” that are useful in a wide range of cases. These canned responses can be tapped by the user, allowing for a fast method of sending simple replies in cases where speaking may not be desirable.</p>
+
+<p>You should attempt to cover a range of simple, neutral replies in your choices. Longer voice replies may be automatically truncated in the Voice reply UI.</p>
+
+<p>For developer details about enabling voice replies, see
+described in <a href="{@docRoot}wear/notifications/remote-input.html">Receiving Voice Input from
+a Notification</a>.</p>
diff --git a/docs/html/wear/design/user-interface.html b/docs/html/wear/design/user-interface.html
deleted file mode 100644
index c23d79c..0000000
--- a/docs/html/wear/design/user-interface.html
+++ /dev/null
@@ -1,498 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>UI Overview | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<link rel="stylesheet" type="text/css" href="/wear/css/wear.css">
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >UI Overview</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <style>
-h3 {
- padding:30px 0 10px;
-}
-</style>
-
-<p>A new form factor deserves a new UI model. At a high level, the Android Wear UI consists of two
-main spaces centered around the core functions of <strong>Suggest</strong> and
-<strong>Demand</strong>. Your application will have an important role to play in both of these
-spaces.</p>
-
-
-
-<h3 id="Stream">Suggest: The Context Stream</h3>
-
-<div class="wear-inset-video-container" style="float:right;margin:0 -22px 60px 40px">
- <img class="wear-bezel-only" src="/wear/images/screens/bezel.png" alt="">
- <img class="gif" src="/wear/images/screens/stream.gif">
-</div>
-
-<p>The context stream is a vertical list of cards, each showing a useful or timely piece of
-information. Much like Google Now on Android phones and tablets, users swipe vertically to navigate
-from card to card for a brief and comprehensive update about what's important to them. Only one card
-is displayed on screen at a time, and background images are used to provide additional visual
-information. Your application can create cards and inject them into the stream when they are most
-likely to be useful.</p>
-
-<p>Cards in the stream are more than simple notifications. They can be swiped horizontally to
-reveal additional pages. Further horizontal swiping may reveal tappable buttons, allowing the user
-to take action on the notification. Cards can also be dismissed by swiping left to right, removing
-them from the stream until the next time they have useful information to display.
-In the emulator, hovering the mouse over the top of the screen illuminates a blue bar at
-the top of the device that takes you home when clicked.</p>
-
-
-
-<h3 id="CueCard">Demand: The Cue Card</h3>
-
-<div class="wear-inset-video-container" style="float:right;margin:0 -22px 60px 40px">
- <img class="wear-bezel-only" src="/wear/images/screens/bezel.png" alt="">
- <img class="gif" src="/wear/images/screens/cuecard.gif">
-</div>
-
-<p>For cases where the context stream can't anticipate what the user would like to do, the cue card
-allows users to speak to their device. The cue card is opened by saying, "Ok Google" or by tapping
-on the "g" icon on the home screen. Swiping up on the cue card shows a list of actions, which can
-also be tapped.</p>
-
-<p>The list of actions includes Android intents for voice actions. The upcoming Android Wear SDK
-will enable developers to match their applications to these intents so users can perform actions
-using these voice commands. Multiple applications may register for a single voice intent, and users
-will have the opportunity to choose which application they prefer to use.</p>
-
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/design/user-interface.jd b/docs/html/wear/design/user-interface.jd
new file mode 100644
index 0000000..2a3e9ef
--- /dev/null
+++ b/docs/html/wear/design/user-interface.jd
@@ -0,0 +1,58 @@
+page.title=UI Overview
+page.customHeadTag=<link rel="stylesheet" type="text/css" href="/wear/css/wear.css">
+
+@jd:body
+
+<style>
+h3 {
+ padding:30px 0 10px;
+}
+</style>
+
+<p>A new form factor deserves a new UI model. At a high level, the Android Wear UI consists of two
+main spaces centered around the core functions of <strong>Suggest</strong> and
+<strong>Demand</strong>. Your application will have an important role to play in both of these
+spaces.</p>
+
+
+
+<h3 id="Stream">Suggest: The Context Stream</h3>
+
+<div class="wear-inset-video-container" style="float:right;margin:0 -22px 60px 40px">
+ <img class="wear-bezel-only" src="{@docRoot}wear/images/screens/bezel.png" alt="">
+ <img class="gif" src="{@docRoot}wear/images/screens/stream.gif">
+</div>
+
+<p>The context stream is a vertical list of cards, each showing a useful or timely piece of
+information. Much like Google Now on Android phones and tablets, users swipe vertically to navigate
+from card to card for a brief and comprehensive update about what's important to them. Only one card
+is displayed on screen at a time, and background images are used to provide additional visual
+information. Your application can create cards and inject them into the stream when they are most
+likely to be useful.</p>
+
+<p>Cards in the stream are more than simple notifications. They can be swiped horizontally to
+reveal additional pages. Further horizontal swiping may reveal tappable buttons, allowing the user
+to take action on the notification. Cards can also be dismissed by swiping left to right, removing
+them from the stream until the next time they have useful information to display.
+In the emulator, hovering the mouse over the top of the screen illuminates a blue bar at
+the top of the device that takes you home when clicked.</p>
+
+
+
+<h3 id="CueCard">Demand: The Cue Card</h3>
+
+<div class="wear-inset-video-container" style="float:right;margin:0 -22px 60px 40px">
+ <img class="wear-bezel-only" src="{@docRoot}wear/images/screens/bezel.png" alt="">
+ <img class="gif" src="{@docRoot}wear/images/screens/cuecard.gif">
+</div>
+
+<p>For cases where the context stream can't anticipate what the user would like to do, the cue card
+allows users to speak to their device. The cue card is opened by saying, "Ok Google" or by tapping
+on the "g" icon on the home screen. Swiping up on the cue card shows a list of actions, which can
+also be tapped.</p>
+
+<p>The list of actions includes Android intents for voice actions. The upcoming Android Wear SDK
+will enable developers to match their applications to these intents so users can perform actions
+using these voice commands. Multiple applications may register for a single voice intent, and users
+will have the opportunity to choose which application they prefer to use.</p>
+
diff --git a/docs/html/wear/index.html b/docs/html/wear/index.jd
index 9660463..a6a6460 100644
--- a/docs/html/wear/index.html
+++ b/docs/html/wear/index.jd
@@ -1,286 +1,12 @@
-<!DOCTYPE html>
+page.title=Android Wear
+page.viewport_width=970
+fullpage=true
+no_footer_links=true
+page.customHeadTag=<link rel="stylesheet" type="text/css" href="/wear/css/wear.css">
+@jd:body
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=970" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Android Wear | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<link rel="stylesheet" type="text/css" href="/wear/css/wear.css">
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div id="body-content">
-
-
-
-
-<div class="fullpage" >
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <style>
+<style>
.fullpage>#footer,
#jd-content>.content-footer.wrap {
display:none;
@@ -471,10 +197,10 @@ $("#icon-video-close").on("click", function() {
</div>
<p>
- You can also trigger your notifications contextually using existing Android APIs. For example, use <a href="/training/location/geofencing.html">geofences</a> to provide glanceable information to your users when they are at home, or use the <a href="/training/location/activity-recognition.html">activity detection APIs</a> to send messages to your users’ wrists while they are bicycling.
+ You can also trigger your notifications contextually using existing Android APIs. For example, use <a href="{@docRoot}training/location/geofencing.html">geofences</a> to provide glanceable information to your users when they are at home, or use the <a href="{@docRoot}training/location/activity-recognition.html">activity detection APIs</a> to send messages to your users’ wrists while they are bicycling.
</p>
- <p>See the <a href="/wear/design/index.html">Android Wear Developer Preview Design Principles</a> for more suggestions on creating great wearable experiences.</p>
+ <p>See the <a href="{@docRoot}wear/design/index.html">Android Wear Developer Preview Design Principles</a> for more suggestions on creating great wearable experiences.</p>
</div>
</div> <!-- end .wrap -->
@@ -677,63 +403,3 @@ $("#icon-video-close").on("click", function() {
});
</script>
-
- </div>
-
- <div class="content-footer wrap"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-16" style="padding-top:4px">
- <style>#___plusone_0 {float:right !important;}</style>
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" style="width:940px">
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/license.html b/docs/html/wear/license.jd
index c7569bc..b07dacf 100644
--- a/docs/html/wear/license.html
+++ b/docs/html/wear/license.jd
@@ -1,379 +1,9 @@
-<!DOCTYPE html>
+page.title=Developer Preview License Agreement
+@jd:body
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Developer Preview License Agreement | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Developer Preview License Agreement</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <div class="sdk-terms" style="height:auto;border:0;padding:0;width:700px">
+<div class="sdk-terms" style="height:auto;border:0;padding:0;width:700px">
This is the Android Wear Developer Preview License Agreement.
1. Introduction
@@ -510,72 +140,3 @@ This is the Android Wear Developer Preview License Agreement.
14.7 This License Agreement, and your relationship with Google under this License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from this License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
</div>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/notifications/creating.html b/docs/html/wear/notifications/creating.html
deleted file mode 100644
index 7ad6833..0000000
--- a/docs/html/wear/notifications/creating.html
+++ /dev/null
@@ -1,722 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Creating Notifications for Android Wear | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Creating Notifications for Android Wear</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <p>When an Android device such as a phone or tablet is connected to an Android wearable,
-all notifications are shared between the devices by default. On the Android wearable, each
-notification appears as a new card in the <a href="/wear/design/user-interface.html#Stream"
->context stream</a>.</p>
-
-<img src="/wear/images/notification_phone@2x.png" width="700" height="265" />
-
-
-<p>So without any effort, your app notifications are available to users on Android Wear.
-However, you can enhance the user experience in several ways. For instance,
-if users may respond to a notification by entering text, such as to reply to
-a message, you can add the ability for users to reply by voice directly from the
-wearable.</p>
-
-<p>To help you provide the best user experience
-for your notifications on Android Wear, this guide shows you how to
-build notifications using standard templates in
-the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> APIs, plus how to begin
-extending your notification's capabilities for the wearable user experience.</p>
-
-<p class="note"><strong>Note:</strong>
-Notifications using <code><a href="/reference/android/widget/RemoteViews.html">RemoteViews</a></code> are stripped of custom
-layouts and the system uses only the text and icons in the
-<code><a href="/reference/android/app/Notification.html">Notification</a></code> object to
-display the notification in a card. However, custom card layouts will be supported by
-the official Android Wear SDK that is coming later.</p>
-</div>
-
-
-
-
-<h2 id="Import">Import the Necessary Classes</h2>
-
-<p>To begin development, you must first complete the instructions in the <a
-href="/wear/preview/start">Get Started with the Developer Preview</a> document.
-As mentioned in that document, your app must include
-both the <a href="http://developer.android.com/tools/support-library/features.html#v4">v4 support
-library</a> and the Developer Preview support library. So to get started,
-you should include the following imports in your project code:</p>
-
-<pre>
-import android.preview.support.wearable.notifications.*;
-import android.preview.support.v4.app.NotificationManagerCompat;
-import android.support.v4.app.NotificationCompat;
-</pre>
-
-<p class="caution"><strong>Caution:</strong>
-The APIs in the current Android Wear Developer Preview are intended for <b>development and testing purposes only</b>, not for production apps. Google may change this Developer Preview significantly prior to the official release of the Android Wear SDK. You may not publicly distribute or ship any application using this Developer Preview, as this Developer Preview will no longer be supported after the official SDK is released (which will cause applications based only on the Developer Preview to break).</p>
-
-
-
-<h2 id="NotificationBuilder">Create Notifications with the Notification Builder</h2>
-
-<p>The <a href="http://developer.android.com/tools/support-library/features.html#v4">v4
-support library</a> allows you to create notifications using the latest notification features
-such as action buttons and large icons, while remaining compatible with Android 1.6 (API level
-4) and higher.</p>
-
-
-<p>For example, here's some code that creates and issues a notification using the
-<code><a href="/reference/android/support/v4/app/NotificationCompat.html">NotificationCompat</a></code> APIs combined with the new
-<a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">
-<code>NotificationManagerCompat</code></a> API:</p>
-
-
-<pre>
-int notificationId = 001;
-// Build intent for notification content
-Intent viewIntent = new Intent(this, ViewEventActivity.class);
-viewIntent.putExtra(EXTRA_EVENT_ID, eventId);
-PendingIntent viewPendingIntent =
- PendingIntent.getActivity(this, 0, viewIntent, 0);
-
-NotificationCompat.Builder notificationBuilder =
- new NotificationCompat.Builder(this)
- .setSmallIcon(R.drawable.ic_event)
- .setContentTitle(eventTitle)
- .setContentText(eventLocation)
- .setContentIntent(viewPendingIntent);
-
-// Get an instance of the NotificationManager service
-NotificationManagerCompat notificationManager =
- NotificationManagerCompat.from(this);
-
-// Build the notification and issues it with notification manager.
-notificationManager.notify(notificationId, notificationBuilder.build());
-</pre>
-
-<p>When this notification appears on a handheld device, the user can invoke the
-<code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code>
-specified by the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentIntent(android.app.PendingIntent)">setContentIntent()</a></code> method by touching the notification. When this
-notification appears on an Android wearable, the user can swipe the notification to the left to
-reveal the <strong>Open</strong> action, which invokes the intent on the handheld device.</p>
-
-
-
-
-
-
-<img src="/wear/images/circle_email_action.png" height="200" style="float:right;clear:right;margin:0 0 20px 60px" />
-
-<h2 id="ActionButtons">Add Action Buttons</h2>
-
-<p>In addition to the primary content action defined by
-<code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentIntent(android.app.PendingIntent)">setContentIntent()</a></code>, you can add other actions by passing a <code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code> to
-the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#addAction(int, java.lang.CharSequence, android.app.PendingIntent)">addAction()</a></code> method.</p>
-
-<p>For example, the following code shows the same type of notification from above, but adds an
-action to view the event location on a map.</p>
-
-<pre style="clear:right">
-// Build an intent for an action to view a map
-Intent mapIntent = new Intent(Intent.ACTION_VIEW);
-Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
-mapIntent.setData(geoUri);
-PendingIntent mapPendingIntent =
- PendingIntent.getActivity(this, 0, mapIntent, 0);
-
-NotificationCompat.Builder notificationBuilder =
- new NotificationCompat.Builder(this)
- .setSmallIcon(R.drawable.ic_event)
- .setContentTitle(eventTitle)
- .setContentText(eventLocation)
- .setContentIntent(viewPendingIntent)
- <b>.addAction(R.drawable.ic_map,
- getString(R.string.map), mapPendingIntent);</b>
-</pre>
-
-<p>On a handheld device, the action appears as an
-additional button attached to the notification. On an Android wearable, the action appears as
-a large button when the user swipes the notification to the left. When the user taps the action,
-the associated <code><a href="/reference/android/content/Intent.html">Intent</a></code> is invoked on the handheld device.</p>
-
-<p class="note"><strong>Tip:</strong> If your notifications includes a "Reply" action
- (such as for a messaging app), you can enhance the behavior by enabling
- voice input replies directly from the Android wearable. For more information, read
- <a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification</a>.
-</p>
-
-<p>For details about designing action buttons (including the icon specifications), see the
-<a href="/wear/design/index.html#NotifictionActions">Design Principles of Android
-Wear</a>.</p>
-
-
-<h2 id="BigView">Add a Big View</h2>
-
-<img src="/wear/images/06_images.png" height="200" style="float:right;margin:0 0 20px 40px" />
-
-<p>You can insert extended text content
-to your notification by adding one of the "big view" styles to your notification. On a
-handheld device, users can see the big view content by expanding the notification,
-while on Android Wear, the big view content is visible by default.</p>
-
-<p>To add the extended content to your notification, call <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setStyle(android.support.v4.app.NotificationCompat.Style)">setStyle()</a></code> on the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> object, passing it an instance of either
-<code><a href="/reference/android/support/v4/app/NotificationCompat.BigTextStyle.html">BigTextStyle</a></code> or
-<code><a href="/reference/android/support/v4/app/NotificationCompat.InboxStyle.html">InboxStyle</a></code>.</p>
-
-<p>For example, the following code adds an instance of
-<code><a href="/reference/android/support/v4/app/NotificationCompat.BigTextStyle.html">NotificationCompat.BigTextStyle</a></code> to the event notification,
-in order to include the complete event description (which includes more text than can fit
-into the space provided for <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentText(java.lang.CharSequence)">setContentText()</a></code>).</p>
-
-
-<pre style="clear:right">
-// Specify the 'big view' content to display the long
-// event description that may not fit the normal content text.
-BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
-bigStyle.bigText(eventDescription);
-
-NotificationCompat.Builder notificationBuilder =
- new NotificationCompat.Builder(this)
- .setSmallIcon(R.drawable.ic_event)
- .setLargeIcon(BitmapFractory.decodeResource(
- getResources(), R.drawable.notif_background))
- .setContentTitle(eventTitle)
- .setContentText(eventLocation)
- .setContentIntent(viewPendingIntent)
- .addAction(R.drawable.ic_map,
- getString(R.string.map), mapPendingIntent)
- <b>.setStyle(bigStyle);</b>
-</pre>
-
-<p>Notice that you can add a large background image to any notification using the
-<code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setLargeIcon(android.graphics.Bitmap)">setLargeIcon()</a></code>
-method. For more information about designing notifications with large images, see the
-<a href="/wear/design/index.html#Images">Design Principles of Android
-Wear</a>.</p>
-
-
-
-<h2 id="NewFeatures">Add New Features for Wearables</h2>
-
-<p>The Android Wear preview support library provides new APIs that
- allow you to enhance the user experience for notifications on a wearable device. For example,
- you can add additional pages of content that users can view by swiping to the left, or add the ability
-for users to deliver your app a text response using voice input.</p>
-
-<p>To use these new APIs, pass your instance of
-<code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> to the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#WearableNotifications.Builder(android.content.Context)"> <code>WearableNotifications.Builder()</code></a> constructor. You can then add new
-features to your notification using the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"
- ><code>WearableNotifications.Builder</code></a> methods. For example:</p>
-
-<pre>
-// Create a NotificationCompat.Builder for standard notification features
-NotificationCompat.Builder notificationBuilder =
- new NotificationCompat.Builder(mContext)
- .setContentTitle("New mail from " + sender.toString())
- .setContentText(subject)
- .setSmallIcon(R.drawable.new_mail);
-
-// Create a WearablesNotification.Builder to add special functionality for wearables
-Notification notification =
- new WearableNotifications.Builder(notificationBuilder)
- .setHintHideIcon(true)
- .build();
-</pre>
-
-<p>The <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setBigActionIcon(int)">
- <code>setHintHideIcon()</code></a> method removes your app icon from the notification card.
- This method is just one example of new notification features available from the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"
- ><code>WearableNotifications.Builder</code></a> class.</p>
-
-<p>When you want to deliver your notifications, be certain to always use the
- <a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">
- <code>NotificationManagerCompat</code></a> API:</p>
-
-<pre>
-// Get an instance of the NotificationManager service
-NotificationManagerCompat notificationManager =
- NotificationManagerCompat.from(this);
-
-// Build the notification and issues it with notification manager.
-notificationManager.notify(notificationId, notification);
-</pre>
-
-<p>If you instead use the framework's <code><a href="/reference/android/app/NotificationManager.html">NotificationManager</a></code>, some
-features from <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a>
-will not work.</p>
-
-<p>To continue enhancing your notifications for wearables using
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"
- ><code>WearableNotifications.Builder</code></a> and other APIs in the
- preview support library, see the following developer guides:</p>
-
- <dl>
- <dt><a href="/wear/notifications/remote-input.html">Receiving Voice Input
-from a Notification</a></dt>
- <dd>Add an action that receives voice input from the user and delivers the
-transcribed message to your app.</dd>
- <dt><a href="/wear/notifications/pages.html">Adding Pages to a Notification</a></dt>
- <dd>Add additional pages of information that are visible when the user
-swipes to the left.</dd>
- <dt><a href="/wear/notifications/stacks.html">Stacking Notifications</a></dt>
- <dd>Place all similar notifications from your app in a stack, allowing each to be
-viewed individually without adding multiple cards to the card stream.</dd>
- </dl>
-
-
-<div class="next-docs">
-
-<div class="col-12">
- <h2 class="norule">You might also want to read:</h2>
- <dl>
- <dt><a href="/training/notify-user/index.html">Notifying the User</a></dt>
- <dd>Learn more about how to create notifications.</dd>
- <dt><a href="/guide/components/intents-filters.html">Intents and Intent Filters</a></dt>
- <dd>Learn everything you need to know about the <code><a href="/reference/android/content/Intent.html">Intent</a></code>
-APIs, used by notificaton actions.</dd>
- </dl>
-</div>
-</div>
-
-
-</body>
-</html>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/notifications/creating.jd b/docs/html/wear/notifications/creating.jd
new file mode 100644
index 0000000..133d057
--- /dev/null
+++ b/docs/html/wear/notifications/creating.jd
@@ -0,0 +1,289 @@
+page.title=Creating Notifications for Android Wear
+
+@jd:body
+
+
+<p>When an Android device such as a phone or tablet is connected to an Android wearable,
+all notifications are shared between the devices by default. On the Android wearable, each
+notification appears as a new card in the <a href="{@docRoot}wear/design/user-interface.html#Stream"
+>context stream</a>.</p>
+
+<img src="{@docRoot}wear/images/notification_phone@2x.png" width="700" height="265" />
+
+
+<p>So without any effort, your app notifications are available to users on Android Wear.
+However, you can enhance the user experience in several ways. For instance,
+if users may respond to a notification by entering text, such as to reply to
+a message, you can add the ability for users to reply by voice directly from the
+wearable.</p>
+
+<p>To help you provide the best user experience
+for your notifications on Android Wear, this guide shows you how to
+build notifications using standard templates in
+the {@link android.support.v4.app.NotificationCompat.Builder} APIs, plus how to begin
+extending your notification's capabilities for the wearable user experience.</p>
+
+<p class="note"><strong>Note:</strong>
+Notifications using {@link android.widget.RemoteViews} are stripped of custom
+layouts and the system uses only the text and icons in the
+{@link android.app.Notification} object to
+display the notification in a card. However, custom card layouts will be supported by
+the official Android Wear SDK that is coming later.</p>
+</div>
+
+
+
+
+<h2 id="Import">Import the Necessary Classes</h2>
+
+<p>To begin development, you must first complete the instructions in the <a
+href="{@docRoot}wear/preview/start">Get Started with the Developer Preview</a> document.
+As mentioned in that document, your app must include
+both the <a href="http://developer.android.com/tools/support-library/features.html#v4">v4 support
+library</a> and the Developer Preview support library. So to get started,
+you should include the following imports in your project code:</p>
+
+<pre>
+import android.preview.support.wearable.notifications.*;
+import android.preview.support.v4.app.NotificationManagerCompat;
+import android.support.v4.app.NotificationCompat;
+</pre>
+
+<p class="caution"><strong>Caution:</strong>
+The APIs in the current Android Wear Developer Preview are intended for <b>development and testing purposes only</b>, not for production apps. Google may change this Developer Preview significantly prior to the official release of the Android Wear SDK. You may not publicly distribute or ship any application using this Developer Preview, as this Developer Preview will no longer be supported after the official SDK is released (which will cause applications based only on the Developer Preview to break).</p>
+
+
+
+<h2 id="NotificationBuilder">Create Notifications with the Notification Builder</h2>
+
+<p>The <a href="http://developer.android.com/tools/support-library/features.html#v4">v4
+support library</a> allows you to create notifications using the latest notification features
+such as action buttons and large icons, while remaining compatible with Android 1.6 (API level
+4) and higher.</p>
+
+
+<p>For example, here's some code that creates and issues a notification using the
+{@link android.support.v4.app.NotificationCompat} APIs combined with the new
+<a href="{@docRoot}reference/android/preview/support/v4/app/NotificationManagerCompat.html">
+<code>NotificationManagerCompat</code></a> API:</p>
+
+
+<pre>
+int notificationId = 001;
+// Build intent for notification content
+Intent viewIntent = new Intent(this, ViewEventActivity.class);
+viewIntent.putExtra(EXTRA_EVENT_ID, eventId);
+PendingIntent viewPendingIntent =
+ PendingIntent.getActivity(this, 0, viewIntent, 0);
+
+NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.ic_event)
+ .setContentTitle(eventTitle)
+ .setContentText(eventLocation)
+ .setContentIntent(viewPendingIntent);
+
+// Get an instance of the NotificationManager service
+NotificationManagerCompat notificationManager =
+ NotificationManagerCompat.from(this);
+
+// Build the notification and issues it with notification manager.
+notificationManager.notify(notificationId, notificationBuilder.build());
+</pre>
+
+<p>When this notification appears on a handheld device, the user can invoke the
+{@link android.app.PendingIntent}
+specified by the {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+setContentIntent()} method by touching the notification. When this
+notification appears on an Android wearable, the user can swipe the notification to the left to
+reveal the <strong>Open</strong> action, which invokes the intent on the handheld device.</p>
+
+
+
+
+
+
+<img src="{@docRoot}wear/images/circle_email_action.png" height="200" style="float:right;clear:right;margin:0 0 20px 60px" />
+
+<h2 id="ActionButtons">Add Action Buttons</h2>
+
+<p>In addition to the primary content action defined by
+{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+setContentIntent()}, you can add other actions by passing a {@link android.app.PendingIntent} to
+the {@link android.support.v4.app.NotificationCompat.Builder#addAction
+addAction()} method.</p>
+
+<p>For example, the following code shows the same type of notification from above, but adds an
+action to view the event location on a map.</p>
+
+<pre style="clear:right">
+// Build an intent for an action to view a map
+Intent mapIntent = new Intent(Intent.ACTION_VIEW);
+Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
+mapIntent.setData(geoUri);
+PendingIntent mapPendingIntent =
+ PendingIntent.getActivity(this, 0, mapIntent, 0);
+
+NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.ic_event)
+ .setContentTitle(eventTitle)
+ .setContentText(eventLocation)
+ .setContentIntent(viewPendingIntent)
+ <b>.addAction(R.drawable.ic_map,
+ getString(R.string.map), mapPendingIntent);</b>
+</pre>
+
+<p>On a handheld device, the action appears as an
+additional button attached to the notification. On an Android wearable, the action appears as
+a large button when the user swipes the notification to the left. When the user taps the action,
+the associated {@link android.content.Intent} is invoked on the handheld device.</p>
+
+<p class="note"><strong>Tip:</strong> If your notifications includes a "Reply" action
+ (such as for a messaging app), you can enhance the behavior by enabling
+ voice input replies directly from the Android wearable. For more information, read
+ <a href="{@docRoot}wear/notifications/remote-input.html">Receiving Voice Input from a Notification</a>.
+</p>
+
+<p>For details about designing action buttons (including the icon specifications), see the
+<a href="{@docRoot}wear/design/index.html#NotifictionActions">Design Principles of Android
+Wear</a>.</p>
+
+
+<h2 id="BigView">Add a Big View</h2>
+
+<img src="{@docRoot}wear/images/06_images.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>You can insert extended text content
+to your notification by adding one of the "big view" styles to your notification. On a
+handheld device, users can see the big view content by expanding the notification,
+while on Android Wear, the big view content is visible by default.</p>
+
+<p>To add the extended content to your notification, call {@link
+android.support.v4.app.NotificationCompat.Builder#setStyle setStyle()} on the {@link
+android.support.v4.app.NotificationCompat.Builder} object, passing it an instance of either
+{@link android.support.v4.app.NotificationCompat.BigTextStyle BigTextStyle} or
+{@link android.support.v4.app.NotificationCompat.InboxStyle InboxStyle}.</p>
+
+<p>For example, the following code adds an instance of
+{@link android.support.v4.app.NotificationCompat.BigTextStyle} to the event notification,
+in order to include the complete event description (which includes more text than can fit
+into the space provided for {@link android.support.v4.app.NotificationCompat.Builder#setContentText
+setContentText()}).</p>
+
+
+<pre style="clear:right">
+// Specify the 'big view' content to display the long
+// event description that may not fit the normal content text.
+BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
+bigStyle.bigText(eventDescription);
+
+NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.ic_event)
+ .setLargeIcon(BitmapFractory.decodeResource(
+ getResources(), R.drawable.notif_background))
+ .setContentTitle(eventTitle)
+ .setContentText(eventLocation)
+ .setContentIntent(viewPendingIntent)
+ .addAction(R.drawable.ic_map,
+ getString(R.string.map), mapPendingIntent)
+ <b>.setStyle(bigStyle);</b>
+</pre>
+
+<p>Notice that you can add a large background image to any notification using the
+{@link android.support.v4.app.NotificationCompat.Builder#setLargeIcon setLargeIcon()}
+method. For more information about designing notifications with large images, see the
+<a href="{@docRoot}wear/design/index.html#Images">Design Principles of Android
+Wear</a>.</p>
+
+
+
+<h2 id="NewFeatures">Add New Features for Wearables</h2>
+
+<p>The Android Wear preview support library provides new APIs that
+ allow you to enhance the user experience for notifications on a wearable device. For example,
+ you can add additional pages of content that users can view by swiping to the left, or add the ability
+for users to deliver your app a text response using voice input.</p>
+
+<p>To use these new APIs, pass your instance of
+{@link android.support.v4.app.NotificationCompat.Builder} to the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#WearableNotifications.Builder(android.content.Context)"> <code>WearableNotifications.Builder()</code></a> constructor. You can then add new
+features to your notification using the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"
+ ><code>WearableNotifications.Builder</code></a> methods. For example:</p>
+
+<pre>
+// Create a NotificationCompat.Builder for standard notification features
+NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(mContext)
+ .setContentTitle("New mail from " + sender.toString())
+ .setContentText(subject)
+ .setSmallIcon(R.drawable.new_mail);
+
+// Create a WearablesNotification.Builder to add special functionality for wearables
+Notification notification =
+ new WearableNotifications.Builder(notificationBuilder)
+ .setHintHideIcon(true)
+ .build();
+</pre>
+
+<p>The <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setBigActionIcon(int)">
+ <code>setHintHideIcon()</code></a> method removes your app icon from the notification card.
+ This method is just one example of new notification features available from the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"
+ ><code>WearableNotifications.Builder</code></a> class.</p>
+
+<p>When you want to deliver your notifications, be certain to always use the
+ <a href="{@docRoot}reference/android/preview/support/v4/app/NotificationManagerCompat.html">
+ <code>NotificationManagerCompat</code></a> API:</p>
+
+<pre>
+// Get an instance of the NotificationManager service
+NotificationManagerCompat notificationManager =
+ NotificationManagerCompat.from(this);
+
+// Build the notification and issues it with notification manager.
+notificationManager.notify(notificationId, notification);
+</pre>
+
+<p>If you instead use the framework's {@link android.app.NotificationManager}, some
+features from <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a>
+will not work.</p>
+
+<p>To continue enhancing your notifications for wearables using
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder"
+ ><code>WearableNotifications.Builder</code></a> and other APIs in the
+ preview support library, see the following developer guides:</p>
+
+ <dl>
+ <dt><a href="{@docRoot}wear/notifications/remote-input.html">Receiving Voice Input
+from a Notification</a></dt>
+ <dd>Add an action that receives voice input from the user and delivers the
+transcribed message to your app.</dd>
+ <dt><a href="{@docRoot}wear/notifications/pages.html">Adding Pages to a Notification</a></dt>
+ <dd>Add additional pages of information that are visible when the user
+swipes to the left.</dd>
+ <dt><a href="{@docRoot}wear/notifications/stacks.html">Stacking Notifications</a></dt>
+ <dd>Place all similar notifications from your app in a stack, allowing each to be
+viewed individually without adding multiple cards to the card stream.</dd>
+ </dl>
+
+
+<div class="next-docs">
+
+<div class="col-12">
+ <h2 class="norule">You might also want to read:</h2>
+ <dl>
+ <dt><a href="{@docRoot}training/notify-user/index.html">Notifying the User</a></dt>
+ <dd>Learn more about how to create notifications.</dd>
+ <dt><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a></dt>
+ <dd>Learn everything you need to know about the {@link android.content.Intent}
+APIs, used by notificaton actions.</dd>
+ </dl>
+</div>
+</div>
+
+
+</body>
+</html>
diff --git a/docs/html/wear/notifications/pages.html b/docs/html/wear/notifications/pages.html
deleted file mode 100644
index ce568eb..0000000
--- a/docs/html/wear/notifications/pages.html
+++ /dev/null
@@ -1,500 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Adding Pages to a Notification | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Adding Pages to a Notification</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <img src="/wear/images/09_pages.png" height="200" style="float:right;margin:0 0 20px 40px" />
-<img src="/wear/images/08_pages.png" height="200" style="float:right;margin:0 0 20px 40px" />
-
-<p>When you'd like to provide more information without requiring users
-to open your app on their handheld device, you can
-add one or more pages to the notification on Android Wear. The additional pages
-appear immediately to the right of the main notification card.
-For information about when to use and how to design
-multiple pages, see the
-<a href="/wear/design/index.html#NotificationPages">Design Principles of Android
-Wear</a>.</p>
-
-
-<p>When creating a notification with multiple pages, start by creating the main notification
-(the first page) the way you'd like the notification to appear on a phone
-or tablet. Then, add pages one at a time with the
-<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPage(android.app.Notification)">
-<code>addPage()</code></a> method, or add multiple pages in a <code><a href="/reference/java/util/Collection.html">Collection</a></code> with the
-<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPages(java.util.Collection<android.app.Notification>)">
-<code>addPages()</code></a> method.</p>
-
-
-<p>For example, here's some code that adds a second page to a notification:</p>
-
-<pre>
-// Create builder for the main notification
-NotificationCompat.Builder notificationBuilder =
- new NotificationCompat.Builder(this)
- .setSmallIcon(R.drawable.new_message)
- .setContentTitle("Page 1")
- .setContentText("Short message")
- .setContentIntent(viewPendingIntent);
-
-// Create a big text style for the second page
-BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();
-secondPageStyle.setBigContentTitle("Page 2")
- .bigText("A lot of text...");
-
-// Create second page notification
-Notification secondPageNotification =
- new NotificationCompat.Builder(this)
- .setStyle(secondPageStyle)
- .build();
-
-// Create main notification and add the second page
-Notification twoPageNotification =
- new WearableNotifications.Builder(notificationBuilder)
- .addPage(secondPageNotification)
- .build();
-</pre>
-
-
-
-
-</body>
-</html>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/notifications/pages.jd b/docs/html/wear/notifications/pages.jd
new file mode 100644
index 0000000..558f7b8
--- /dev/null
+++ b/docs/html/wear/notifications/pages.jd
@@ -0,0 +1,61 @@
+page.title=Adding Pages to a Notification
+
+@jd:body
+
+
+<img src="{@docRoot}wear/images/09_pages.png" height="200" style="float:right;margin:0 0 20px 40px" />
+<img src="{@docRoot}wear/images/08_pages.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>When you'd like to provide more information without requiring users
+to open your app on their handheld device, you can
+add one or more pages to the notification on Android Wear. The additional pages
+appear immediately to the right of the main notification card.
+For information about when to use and how to design
+multiple pages, see the
+<a href="{@docRoot}wear/design/index.html#NotificationPages">Design Principles of Android
+Wear</a>.</p>
+
+
+<p>When creating a notification with multiple pages, start by creating the main notification
+(the first page) the way you'd like the notification to appear on a phone
+or tablet. Then, add pages one at a time with the
+<a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPage(android.app.Notification)">
+<code>addPage()</code></a> method, or add multiple pages in a {@link java.util.Collection} with the
+<a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPages(java.util.Collection<android.app.Notification>)">
+<code>addPages()</code></a> method.</p>
+
+
+<p>For example, here's some code that adds a second page to a notification:</p>
+
+<pre>
+// Create builder for the main notification
+NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.new_message)
+ .setContentTitle("Page 1")
+ .setContentText("Short message")
+ .setContentIntent(viewPendingIntent);
+
+// Create a big text style for the second page
+BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();
+secondPageStyle.setBigContentTitle("Page 2")
+ .bigText("A lot of text...");
+
+// Create second page notification
+Notification secondPageNotification =
+ new NotificationCompat.Builder(this)
+ .setStyle(secondPageStyle)
+ .build();
+
+// Create main notification and add the second page
+Notification twoPageNotification =
+ new WearableNotifications.Builder(notificationBuilder)
+ .addPage(secondPageNotification)
+ .build();
+</pre>
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/wear/notifications/remote-input.html b/docs/html/wear/notifications/remote-input.html
deleted file mode 100644
index c8f6621..0000000
--- a/docs/html/wear/notifications/remote-input.html
+++ /dev/null
@@ -1,652 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Receiving Voice Input from a Notification | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Receiving Voice Input from a Notification</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <img src="/wear/images/13_voicereply.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
-
-<img src="/wear/images/03_actions.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
-
-<p>If your notification includes an action to respond with text,
- such as to reply to an email, it should normally launch an activity
- on the handheld device. However, when your notification appears on an Android wearable, you can
- allow users to dictate a reply with voice input. You can also provide pre-defined text
- messages for the user to select.</p>
-
-<p>When the user replies with voice or selects one of the available
-messages, the system sends the message to your app on the connected handheld device.
-The message is attached as an extra in the <code><a href="/reference/android/content/Intent.html">Intent</a></code> you specified
-to be used for the notification action.</p>
-
-<p class="note"><strong>Note:</strong> When developing with the Android emulator,
-you must type text replies into the voice input field, so be sure you have enabled
-<strong>Hardware keyboard present</strong> in the AVD settings.</p>
-
-
-<h2 id="RemoteInput">Define the Remote Input</h2>
-
-<p>To create an action that supports voice input, first create an instance of
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
-<code>RemoteInput</code></a> using the
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> APIs.
- The
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor takes a string that the system
- will use as a key for the <code><a href="/reference/android/content/Intent.html">Intent</a></code> extra that carries the reply message
- to your app on the handheld.</p>
-
-<p>For example, here's how to create a new
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
-<code>RemoteInput</code></a> object that provides a custom
- label for the voice input prompt:</p>
-
-<pre class="prettyprint">
-// Key for the string that's delivered in the action's intent
-private static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
-
-String replyLabel = getResources().getString(R.string.reply_label);
-
-RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
- .setLabel(replyLabel)
- .build();
-</pre>
-
-
-<h3>Add Pre-defined Text Responses</h3>
-
-<img src="/wear/images/12_voicereply.png" height="200" style="float:right;margin:0 0 20px 40px" />
-
-<p>In addition to allowing voice input, you can
- provide up to five text responses that the user can select for quick replies. Call
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setChoices(java.lang.String[])"><code>setChoices()</code></a> and pass it a string array.</p>
-
-<p>For example, you may define some responses in a resource array:</p>
-
-<p class="code-caption">res/values/strings.xml</code>
-<pre class="prettyprint">
-&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;resources>
- &lt;string-array name="reply_choices">
- &lt;item>Yes&lt;/item>
- &lt;item>No&lt;/item>
- &lt;item>Maybe&lt;/item>
- &lt;/string-array>
-&lt;/resources>
-</pre>
-
-<p>Then, inflate the string array and add it to the
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a>:</p>
-
-<pre>
-String replyLabel = getResources().getString(R.string.reply_label);
-String[] replyChoices = getResources().getStringArray(R.array.reply_choices);
-
-RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
- .setLabel(replyLabel)
- .setChoices(replyChoices)
- .build();
-</pre>
-
-
-
-
-<h2 id="PrimaryAction">Receive Voice Input for the Primary Action</h2>
-
-<p>If "Reply" is your notification's primary action (defined by the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentIntent(android.app.PendingIntent)">setContentIntent()</a></code>
-method), then you should attach the
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the main action using
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
-<code>addRemoteInputForContentIntent()</code></a>. For example:</p>
-
-<pre>
-// Create intent for reply action
-Intent replyIntent = new Intent(this, ReplyActivity.class);
-PendingIntent replyPendingIntent =
- PendingIntent.getActivity(this, 0, replyIntent, 0);
-
-// Build the notification
-NotificationCompat.Builder replyNotificationBuilder =
- new NotificationCompat.Builder(this)
- .setSmallIcon(R.drawable.ic_new_message)
- .setContentTitle("Message from Travis")
- .setContentText("I love key lime pie!")
- .setContentIntent(replyPendingIntent);
-
-// Create the remote input
-RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
- .setLabel(replyLabel)
- .build();
-
-// Create wearable notification and add remote input
-Notification replyNotification =
- new WearableNotifications.Builder(replyNotificationBuilder)
- .addRemoteInputForContentIntent(replyAction)
- .build();
-</pre>
-
-
-<p>By using
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
-<code>addRemoteInputForContentIntent()</code></a> to add the
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> object to the notification's primary action,
-the button that normally appears as an "Open" action becomes the "Reply" action
-and starts the voice input UI when users select it on Android Wear.</p>
-
-
-
-<h2 id="NewAction">Receive Voice Input for a Secondary Action</h2>
-
-<p>If the "Reply" action is not your notification's primary action and you want to enable
-voice input for a secondary action, add the
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to a new action button defined by an
- <a href="/reference/android/preview/support/wearable/notifications/Action.html">
-<code>Action</code></a> object.</p>
-
-<p>You should instantiate the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
-<code>Action</code></a> with the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html"><code>Action.Builder()</code></a>
-constructor, which takes an icon and text label for the action button, plus the
-<code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code>
-the system should use to invoke your app when the user selects the action. For example:</p>
-
-<pre>
-// Create the pending intent to fire when the user selects the action
-Intent replyIntent = new Intent(this, ReplyActivity.class);
-PendingIntent pendingReplyIntent =
- PendingIntent.getActivity(this, 0, replyIntent, 0);
-
-// Create the remote input
-RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
- .setLabel(replyLabel)
- .build();
-
-// Create the notification action
-Action replyAction = new Action.Builder(R.drawable.ic_message,
- "Reply", pendingIntent)
- .addRemoteInput(remoteInput)
- .build();
-</pre>
-
-
-<p>After you add the
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
-<code>Action</code></a>, add the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
-<code>Action</code></a> to the
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a> using
- <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addAction(Action)"><code>addAction()</code></a>.
-For example:</p>
-
-<pre>
-// Create basic notification builder
-NotificationCompat.Builder replyNotificationBuilder =
- new NotificationCompat.Builder(this)
- .setContentTitle("New message");
-
-// Create the notification action and add remote input
-Action replyAction = new Action.Builder(R.drawable.ic_message,
- "Reply", pendingIntent)
- .addRemoteInput(remoteInput)
- .build();
-
-// Create wearable notification and add action
-Notification replyNotification =
- new WearableNotifications.Builder(replyNotificationBuilder)
- .addAction(replyAction)
- .build();
-</pre>
-
-<p>Now, when the user selects "Reply" from an Android wearable, the system prompts the user
- for voice input (and shows the list of pre-defined replies, if provided).
- Once the user completes a response, the system invokes
- the <code><a href="/reference/android/content/Intent.html">Intent</a></code> attached to the action and adds the
-<code>EXTRA_VOICE_REPLY</code> extra (the string
- you passed to the
- <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor)
- with the user's message as the string value.</p>
-
-
-
-
-</body>
-</html>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/notifications/remote-input.jd b/docs/html/wear/notifications/remote-input.jd
new file mode 100644
index 0000000..8243896
--- /dev/null
+++ b/docs/html/wear/notifications/remote-input.jd
@@ -0,0 +1,213 @@
+page.title=Receiving Voice Input from a Notification
+
+@jd:body
+
+<img src="{@docRoot}wear/images/13_voicereply.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
+
+<img src="{@docRoot}wear/images/03_actions.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
+
+<p>If your notification includes an action to respond with text,
+ such as to reply to an email, it should normally launch an activity
+ on the handheld device. However, when your notification appears on an Android wearable, you can
+ allow users to dictate a reply with voice input. You can also provide pre-defined text
+ messages for the user to select.</p>
+
+<p>When the user replies with voice or selects one of the available
+messages, the system sends the message to your app on the connected handheld device.
+The message is attached as an extra in the {@link android.content.Intent} you specified
+to be used for the notification action.</p>
+
+<p class="note"><strong>Note:</strong> When developing with the Android emulator,
+you must type text replies into the voice input field, so be sure you have enabled
+<strong>Hardware keyboard present</strong> in the AVD settings.</p>
+
+
+<h2 id="RemoteInput">Define the Remote Input</h2>
+
+<p>To create an action that supports voice input, first create an instance of
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.html">
+<code>RemoteInput</code></a> using the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> APIs.
+ The
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor takes a string that the system
+ will use as a key for the {@link android.content.Intent} extra that carries the reply message
+ to your app on the handheld.</p>
+
+<p>For example, here's how to create a new
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.html">
+<code>RemoteInput</code></a> object that provides a custom
+ label for the voice input prompt:</p>
+
+<pre class="prettyprint">
+// Key for the string that's delivered in the action's intent
+private static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
+
+String replyLabel = getResources().getString(R.string.reply_label);
+
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+ .setLabel(replyLabel)
+ .build();
+</pre>
+
+
+<h3>Add Pre-defined Text Responses</h3>
+
+<img src="{@docRoot}wear/images/12_voicereply.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>In addition to allowing voice input, you can
+ provide up to five text responses that the user can select for quick replies. Call
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setChoices(java.lang.String[])"><code>setChoices()</code></a> and pass it a string array.</p>
+
+<p>For example, you may define some responses in a resource array:</p>
+
+<p class="code-caption">res/values/strings.xml</code>
+<pre class="prettyprint">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string-array name="reply_choices">
+ &lt;item>Yes&lt;/item>
+ &lt;item>No&lt;/item>
+ &lt;item>Maybe&lt;/item>
+ &lt;/string-array>
+&lt;/resources>
+</pre>
+
+<p>Then, inflate the string array and add it to the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a>:</p>
+
+<pre>
+String replyLabel = getResources().getString(R.string.reply_label);
+String[] replyChoices = getResources().getStringArray(R.array.reply_choices);
+
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+ .setLabel(replyLabel)
+ .setChoices(replyChoices)
+ .build();
+</pre>
+
+
+
+
+<h2 id="PrimaryAction">Receive Voice Input for the Primary Action</h2>
+
+<p>If "Reply" is your notification's primary action (defined by the {@link
+android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()}
+method), then you should attach the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the main action using
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
+<code>addRemoteInputForContentIntent()</code></a>. For example:</p>
+
+<pre>
+// Create intent for reply action
+Intent replyIntent = new Intent(this, ReplyActivity.class);
+PendingIntent replyPendingIntent =
+ PendingIntent.getActivity(this, 0, replyIntent, 0);
+
+// Build the notification
+NotificationCompat.Builder replyNotificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.ic_new_message)
+ .setContentTitle("Message from Travis")
+ .setContentText("I love key lime pie!")
+ .setContentIntent(replyPendingIntent);
+
+// Create the remote input
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+ .setLabel(replyLabel)
+ .build();
+
+// Create wearable notification and add remote input
+Notification replyNotification =
+ new WearableNotifications.Builder(replyNotificationBuilder)
+ .addRemoteInputForContentIntent(remoteInput)
+ .build();
+</pre>
+
+
+<p>By using
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
+<code>addRemoteInputForContentIntent()</code></a> to add the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> object to the notification's primary action,
+the button that normally appears as an "Open" action becomes the "Reply" action
+and starts the voice input UI when users select it on Android Wear.</p>
+
+
+
+<h2 id="NewAction">Receive Voice Input for a Secondary Action</h2>
+
+<p>If the "Reply" action is not your notification's primary action and you want to enable
+voice input for a secondary action, add the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to a new action button defined by an
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/Action.html">
+<code>Action</code></a> object.</p>
+
+<p>You should instantiate the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
+<code>Action</code></a> with the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html"><code>Action.Builder()</code></a>
+constructor, which takes an icon and text label for the action button, plus the
+{@link android.app.PendingIntent}
+the system should use to invoke your app when the user selects the action. For example:</p>
+
+<pre>
+// Create the pending intent to fire when the user selects the action
+Intent replyIntent = new Intent(this, ReplyActivity.class);
+PendingIntent pendingReplyIntent =
+ PendingIntent.getActivity(this, 0, replyIntent, 0);
+
+// Create the remote input
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+ .setLabel(replyLabel)
+ .build();
+
+// Create the notification action
+Action replyAction = new Action.Builder(R.drawable.ic_message,
+ "Reply", pendingIntent)
+ .addRemoteInput(remoteInput)
+ .build();
+</pre>
+
+
+<p>After you add the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
+<code>Action</code></a>, add the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
+<code>Action</code></a> to the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a> using
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addAction(Action)"><code>addAction()</code></a>.
+For example:</p>
+
+<pre>
+// Create basic notification builder
+NotificationCompat.Builder replyNotificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setContentTitle("New message");
+
+// Create the notification action and add remote input
+Action replyAction = new Action.Builder(R.drawable.ic_message,
+ "Reply", pendingIntent)
+ .addRemoteInput(remoteInput)
+ .build();
+
+// Create wearable notification and add action
+Notification replyNotification =
+ new WearableNotifications.Builder(replyNotificationBuilder)
+ .addAction(replyAction)
+ .build();
+</pre>
+
+<p>Now, when the user selects "Reply" from an Android wearable, the system prompts the user
+ for voice input (and shows the list of pre-defined replies, if provided).
+ Once the user completes a response, the system invokes
+ the {@link android.content.Intent} attached to the action and adds the
+<code>EXTRA_VOICE_REPLY</code> extra (the string
+ you passed to the
+ <a href="{@docRoot}reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor)
+ with the user's message as the string value.</p>
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/wear/notifications/stacks.html b/docs/html/wear/notifications/stacks.html
deleted file mode 100644
index e4f74a0..0000000
--- a/docs/html/wear/notifications/stacks.html
+++ /dev/null
@@ -1,512 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Stacking Notifications | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Stacking Notifications</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <img src="/wear/images/11_bundles_B.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
-<img src="/wear/images/11_bundles_A.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
-
-<p>When creating notifications for a handheld device, you should always aggregate similar
-notifications into a single summary notification. For example, if your app creates notifications
-for received messages, you should not show more than one notification
-on a handheld device&mdash;when more than one is message is received, use a single notification
-to provide a summary such as "2 new messages."</p>
-
-<p>However, a summary notification is less useful on an Android wearable because users
-are not able to read details from each message on the wearable (they must open your app on the
-handheld to view more information). So for the wearable device, you should
-group all the notifications together in a stack. The stack of notifications appears as a single
-card, which users can expand to view the details from each notification separately. The new
-<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
-<code>setGroup()</code></a> method makes this possible while allowing you to still provide
-only one summary notification on the handheld device.</p>
-
-<p>For details about designing notification stacks, see the
-<a href="/wear/design/index.html#NotificationStacks">Design Principles of Android
-Wear</a>.</p>
-
-
-<h2 id="AddGroup">Add Each Notification to a Group</h2>
-
-<p>To create a stack, call <a
-href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
-<code>setGroup()</code></a> for each notification you want in the stack, passing the same
-group key. For example:</p>
-
-<pre style="clear:right">
-final static String GROUP_KEY_EMAILS = "group_key_emails";
-
-NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
- .setContentTitle("New mail from " + sender)
- .setContentText(subject)
- .setSmallIcon(R.drawable.new_mail);
-
-Notification notif = new WearableNotifications.Builder(builder)
- .setGroup(GROUP_KEY_EMAILS)
- .build();
-</pre>
-
-<p>By default, notifications appear in the order in which you added them, with the most recent
- notification visible at the top. You can define a specific position in the group
- by passing an order position as the second parameter for <a
-href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
-<code>setGroup()</code></a>.</p>
-
-
-<h2 id="AddSummary">Add a Summary Notification</h2>
-
-<p>It's important that you still provide a summary notification that appears on handheld devices.
-So in addition to adding each unique notification to the same stack group, also add a summary
-notification, but set its order position to be <a
-href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_SUMMARY"><code>GROUP_ORDER_SUMMARY</code></a>.</p>
-
-<pre>
-Notification summaryNotification = new WearableNotifications.Builder(builder)
- .setGroup(GROUP_KEY_EMAILS, WearableNotifications.GROUP_ORDER_SUMMARY)
- .build();
-</pre>
-
-<p>This notification will not appear in your stack of notifications on the wearable, but
-appears as the only notification on the handheld device.
-
-</body>
-</html>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/notifications/stacks.jd b/docs/html/wear/notifications/stacks.jd
new file mode 100644
index 0000000..7f955f6
--- /dev/null
+++ b/docs/html/wear/notifications/stacks.jd
@@ -0,0 +1,72 @@
+page.title=Stacking Notifications
+
+@jd:body
+
+<img src="{@docRoot}wear/images/11_bundles_B.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
+<img src="{@docRoot}wear/images/11_bundles_A.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
+
+<p>When creating notifications for a handheld device, you should always aggregate similar
+notifications into a single summary notification. For example, if your app creates notifications
+for received messages, you should not show more than one notification
+on a handheld device&mdash;when more than one is message is received, use a single notification
+to provide a summary such as "2 new messages."</p>
+
+<p>However, a summary notification is less useful on an Android wearable because users
+are not able to read details from each message on the wearable (they must open your app on the
+handheld to view more information). So for the wearable device, you should
+group all the notifications together in a stack. The stack of notifications appears as a single
+card, which users can expand to view the details from each notification separately. The new
+<a href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
+<code>setGroup()</code></a> method makes this possible while allowing you to still provide
+only one summary notification on the handheld device.</p>
+
+<p>For details about designing notification stacks, see the
+<a href="{@docRoot}wear/design/index.html#NotificationStacks">Design Principles of Android
+Wear</a>.</p>
+
+
+<h2 id="AddGroup">Add Each Notification to a Group</h2>
+
+<p>To create a stack, call <a
+href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
+<code>setGroup()</code></a> for each notification you want in the stack, passing the same
+group key. For example:</p>
+
+<pre style="clear:right">
+final static String GROUP_KEY_EMAILS = "group_key_emails";
+
+NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
+ .setContentTitle("New mail from " + sender)
+ .setContentText(subject)
+ .setSmallIcon(R.drawable.new_mail);
+
+Notification notif = new WearableNotifications.Builder(builder)
+ .setGroup(GROUP_KEY_EMAILS)
+ .build();
+</pre>
+
+<p>By default, notifications appear in the order in which you added them, with the most recent
+ notification visible at the top. You can define a specific position in the group
+ by passing an order position as the second parameter for <a
+href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
+<code>setGroup()</code></a>.</p>
+
+
+<h2 id="AddSummary">Add a Summary Notification</h2>
+
+<p>It's important that you still provide a summary notification that appears on handheld devices.
+So in addition to adding each unique notification to the same stack group, also add a summary
+notification, but set its order position to be <a
+href="{@docRoot}reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_SUMMARY"><code>GROUP_ORDER_SUMMARY</code></a>.</p>
+
+<pre>
+Notification summaryNotification = new WearableNotifications.Builder(builder)
+ .setGroup(GROUP_KEY_EMAILS, WearableNotifications.GROUP_ORDER_SUMMARY)
+ .build();
+</pre>
+
+<p>This notification will not appear in your stack of notifications on the wearable, but
+appears as the only notification on the handheld device.
+
+</body>
+</html>
diff --git a/docs/html/wear/preview/signup.html b/docs/html/wear/preview/signup.jd
index ca50179..8e8ec9a 100644
--- a/docs/html/wear/preview/signup.html
+++ b/docs/html/wear/preview/signup.jd
@@ -1,379 +1,8 @@
-<!DOCTYPE html>
+page.title=Sign Up for the Developer Preview
+@jd:body
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Sign Up for the Developer Preview | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Sign Up for the Developer Preview</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <p>To get started with the Android Wear Developer Preview, you must agree to the
+<p>To get started with the Android Wear Developer Preview, you must agree to the
following terms and conditions and provide the email address for your Google account.
After signing up, you’ll have access to:</p>
<ul>
@@ -538,72 +167,3 @@ This is the Android Wear Developer Preview License Agreement.
</body>
</html>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/preview/start.html b/docs/html/wear/preview/start.html
deleted file mode 100644
index b1861f5..0000000
--- a/docs/html/wear/preview/start.html
+++ /dev/null
@@ -1,693 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Get Started with the Developer Preview | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
- var toRoot = "/";
- var metaTags = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-5831155-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-</script>
-</head>
-
-<body class="gc-documentation
- " itemscope itemtype="http://schema.org/Article">
-
-
-
-<a name="top"></a>
-
- <!-- Header -->
- <div id="header">
- <div class="wrap" id="header-wrap">
- <div class="col-3 logo-wear">
- <a href="/wear/index.html">
- <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
- </a>
- </div>
-
-
- <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
- color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
-
-
- <!-- New Search -->
- <div class="menu-container">
- <div class="moremenu">
- <div id="more-btn"></div>
- </div>
- <div class="morehover" id="moremenu">
- <div class="top"></div>
- <div class="mid">
- <div class="header">Links</div>
- <ul>
- <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
- <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
- <li><a href="/about/index.html">About Android</a></li>
- </ul>
- <div class="header">Android Sites</div>
- <ul>
- <li><a href="http://www.android.com">Android.com</a></li>
- <li class="active"><a>Android Developers</a></li>
- <li><a href="http://source.android.com">Android Open Source Project</a></li>
- </ul>
-
-
-
- <div class="header">Language</div>
- <div id="language" class="locales">
- <select name="language" onChange="changeLangPref(this.value, true)">
- <option value="en">English</option>
- <option value="es">Español</option>
- <option value="ja">日本語</option>
- <option value="ko">한국어</option>
- <option value="ru">Русский</option>
- <option value="zh-cn">中文 (中国)</option>
- <option value="zh-tw">中文 (台灣)</option>
- </select>
- </div>
- <script type="text/javascript">
- <!--
- loadLangPref();
- //-->
- </script>
-
-
-
-
- <br class="clearfix" />
- </div><!-- end mid -->
- <div class="bottom"></div>
- </div><!-- end morehover -->
-
- <div class="search" id="search-container">
- <div class="search-inner">
- <div id="search-btn"></div>
- <div class="left"></div>
- <form onsubmit="return submit_search()">
- <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '/')"
-onkeyup="return search_changed(event, false, '/')" />
- </form>
- <div class="right"></div>
- <a class="close hide">close</a>
- <div class="left"></div>
- <div class="right"></div>
- </div>
- </div><!-- end search -->
-
- <div class="search_filtered_wrapper reference">
- <div class="suggest-card reference no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div>
-
- <div class="search_filtered_wrapper docs">
- <div class="suggest-card dummy no-display">&nbsp;</div>
- <div class="suggest-card develop no-display">
- <ul class="search_filtered">
- </ul>
- <div class="child-card guides no-display">
- </div>
- <div class="child-card training no-display">
- </div>
- <div class="child-card samples no-display">
- </div>
- </div>
- <div class="suggest-card design no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- <div class="suggest-card distribute no-display">
- <ul class="search_filtered">
- </ul>
- </div>
- </div><!-- end search_filtered_wrapper -->
-
- </div>
- <!-- end menu_container -->
-
-
- </div><!-- end header-wrap -->
- </div>
- <!-- /Header -->
-
-
- <div id="searchResults" class="wrap" style="display:none;">
- <h2 id="searchTitle">Results</h2>
- <div id="leftSearchControl" class="search-control">Loading...</div>
- </div>
-
-
-
-
-
- <div class="wrap clearfix" id="body-content">
- <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
- <ul class="tree-list-children">
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
- <ul>
-<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
- </ul>
-</li>
-
-<li class="nav-section">
-<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
-<ul>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
-<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
-
-<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
- </ul>
- </li>
-</ul>
-</li>
-
-
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
- </li>
-
-
-</ul>
-
-
-
- </div>
- </div> <!-- end side-nav -->
- <script>
- $(document).ready(function() {
- scrollIntoView("devdoc-nav");
- });
- </script>
-
-
-
-
-<div class="col-12" id="doc-col" >
-
-
-
-
-
- <h1 itemprop="name" >Get Started with the Developer Preview</h1>
-
-
-
-
-
-
- <div id="jd-content">
-
-
- <div class="jd-descr" itemprop="articleBody">
- <div class="cols">
-
- <div class="col-5">
-<p>The Android Wear Developer Preview includes tools and APIs that allow you to
-enhance your app notifications
-to provide an optimized user experience on Android wearables.</p>
-
-<p>With the Android Wear Developer Preview, you can:</p>
-
-<ul>
- <li>Run the Android Wear platform in the Android emulator.</li>
- <li>Connect your Android device to the emulator and view notifications from the
-device as cards on Android Wear.</li>
- <li>Try new APIs in the preview support library that enhance your app's notifications
-with features such as voice replies and notification pages.</li>
-</ul>
-
-<p>To get access to the Developer Preview tools,
-click the sign up button on the right, then follow the setup instructions below.</p>
- </div>
-
- <div class="col-7">
-<img src="/wear/images/laptop-bridge.png" width="400" height="222" alt="" />
-
-<a href="/wear/preview/signup.html" class="button" style="
- width: 370px;
- margin: 10px 0 20px;
- font-weight: bold;
- font-size: 16px;
-">Sign Up for the Developer Preview</a>
-
-<p>Signing up provides you access to:</p>
-<ul>
-<li>New notification APIs in the preview support library.</li>
-<li>Sample apps using the new notification APIs.</li>
-<li>The <em>Android Wear Preview</em> app for your mobile device, which connects
-your device to the Android Wear emulator.</li>
-</ul>
-
- </div>
-</div>
-
-
-<p class="caution"><strong>Caution:</strong>
-The current Android Wear Developer Preview is intended for <b>development and testing purposes only</b>, not for production apps. Google may change this Developer Preview significantly prior to the official release of the Android Wear SDK. You may not publicly distribute or ship any application using this Developer Preview, as this Developer Preview will no longer be supported after the official SDK is released (which will cause applications based only on the Developer Preview to break).</p>
-
-
-
-
-<h2 id="Prereq">Prerequisites</h2>
-
-<p>Before you begin the setup, you must:</p>
-
-<ol>
- <li><a href="/sdk/index.html"><b>Install the Android SDK</b></a>.
- <p>The Android SDK includes all the developer tools required to build
-apps for Android (optional IDEs are also available for download).</p></li>
- <li><a href="/wear/preview/signup.html"><b>Sign up for the Android Wear Developer Preview</b></a>.
- <p>You must sign up with a Gmail or other Google account in order to download the
-preview support library and receive access to the
-<em>Android Wear Preview</em> beta app on Google Play Store.</p></li>
-</ol>
-
-<p class="note"><strong>Note:</strong>
-If you're using the ADT plugin for Eclipse, you must update to version 22.6.1 or higher.
-If you're using Android Studio, you must update to version 0.5.1 or higher</p>
-
-
-
-<h2 id="Install">1. Install the Android Wear System Image</h2>
-
-
-<ol>
- <li>Launch <a href="/tools/help/sdk-manager.html"
- >Android SDK Manager</a>.
- <ul>
- <li>From Eclipse, select <b>Window > Android SDK Manager</b>.</li>
- <li>From Android Studio, select <b>Tools > Android > SDK Manager</b>.</li>
- </ul>
- </li>
- <li>Below Tools, verify that you have Android SDK Tools revision 22.6 or higher.
- <p>If your version of Android SDK Tools is lower than 22.6, you must update:</p>
- <ol>
- <li>Select <strong>Android SDK Tools</strong>.</li>
- <li>Click <strong>Install package</strong>.</li>
- <li>Accept the license and click <strong>Install</strong>.</li>
- <li>When the installation completes, restart Android SDK Manager.</li>
- </ol>
- </li>
-
- <li>Below Android 4.4.2, select <strong>Android Wear ARM EABI v7a System Image</strong>.
-<p class="note"><strong>Note:</strong> Android Wear is designed to support multiple processor architectures.
-</p></li>
- <li>Below Extras, ensure that you have the latest version of the
-<a href="/tools/support-library/index.html">Android Support Library</a>.
- If an update is available, select <strong>Android Support Library</strong>. If you're using Android Studio, also select <strong>Android Support Repository</strong>.</li>
- <li>Click <strong>Install packages</strong>.</li>
- <li>Accept the license and click <strong>Install</strong>.</li>
-</ol>
-
-
-
-<h2 id="SetupEmulator">2. Set Up the Android Wear Emulator</h2>
-
-<ol>
-<li>Launch the <a href="/tools/help/avd-manager.html"
- >Android Virtual Device Manager</a>.
-<ul>
-<li>From Eclipse, select <b>Window > Android Virtual Device Manager</b>.</li>
-<li>From Android Studio, select <b>Tools > Android > AVD Manager</b>.</li>
-</ul>
-</li>
-<li>Click <strong>New</strong>.</li>
-<li>For the AVD Name, enter "AndroidWearSquare" or "AndroidWearRound", depending on whether
-you want to create an emulator with a square or round display.</li>
-<li>For the Device, select <strong>Android Wear Square</strong> or
- <strong>Android Wear Round</strong>.</li>
-<li>For the Target, select <strong>Android 4.4.2 - API Level 19</strong> (or higher).</li>
-<li>For the CPU/ABI, select <strong>Android Wear ARM (armeabi-v7a)</strong>.
-<p class="note"><strong>Note:</strong> Android Wear is designed to support multiple processor architectures.
-</p></li>
-<li>For the Skin, select <strong>AndroidWearSquare</strong> or
-<strong>AndroidWearRound</strong>.</li>
-<li>Leave all other options set to their defaults and click <strong>OK</strong>.
- <p>Although real Android wearables do not provide a keyboard as an input method,
- you should keep <strong>Hardware keyboard present</strong> selected so you can
- provide text input on screens where users will instead provide voice input.</p>
-</li>
-<!--
-<li>Click <strong>Device Definitions</strong>.</li>
-<li>Select <strong>Android WearSquare</strong> then click <strong>Create AVD</strong>.</li>
-<li>Click <strong>OK</strong>.</li>
--->
-<li>In the list of AVDs, select the one you just created and click
- <strong>Start</strong>. In the following window, click <strong>Launch</strong>.</li>
-</ol>
-
-<p>The Android Wear emulator now starts. To begin testing your app's notifications,
-you must now pair the emulator to your development device
-that has the <em>Android Wear Preview</em> app installed.</p>
-
-<p class="note"><strong>Tip:</strong> To improve the emulator startup time, edit your AVD
-and enable <strong>Snapshot</strong> under Emulator Options. When you start the emulator,
-select <strong>Save to snapshot</strong> then click <strong>Launch</strong>. Once the emulator
-is running, close it to save a snapshot of the system.
-Start the AVD again, but select <strong>Launch from snapshot</strong> and
-deselect <strong>Save to snapshot</strong>.</p>
-
-<p class="caution"><strong>Caution:</strong> Do not install apps on the Android Wear emulator.
-The system does not support traditional Android apps and the result of running such apps is
-unpredictable.</p>
-
-
-
-<h2 id="SetupApp">3. Set Up the Android Wear Preview App</h2>
-
-<p>To view your app's notifications on the Android Wear emulator, you must have the
-<em>Android Wear Preview</em> app installed on your Android device (a phone or tablet).</p>
-
-<p>To receive the Android Wear Preview app, you must <a
-href="/wear/preview/signup.html">sign up for the Developer Preview</a> using the same
-Gmail or Google account you use with Google Play Store.</p>
-</p>
-
-<p class="note"><strong>Note:</strong> The <em>Android Wear Preview</em> app is compatible with
- Android 4.3 and higher and is not available for the Android emulator.</p>
-
-<p>After you've signed up for the Developer Preview,
- you'll receive a confirmation email that includes a link to opt-in to the
- <em>Android Wear Preview</em> app beta program. Once you opt-in, it may take up to 24 hours for the
- app to become available in Google Play Store.</p>
-
-<p>After you install the <em>Android Wear Preview</em> app, you can set up
- your device to communicate with the Android Wear emulator:</p>
-
-<ol>
-<li>Open the <em>Android Wear Preview</em> app. You should see a notice that the app is currently
- not enabled as a notification listener. Tap the message to open the system settings,
- then select Android Wear Preview to grant it notification access.</li>
-<li>Connect your device to your development machine over USB. Be sure that no other
- Android devices are connected to the machine.</li>
-<li>Ensure that the Android Wear emulator (created in the previous section) is running.
-The emulator should show the time and an icon that indicates no device is connected.</li>
-<li>Open a command line terminal, navigate to your Android SDK's <code>platform-tools/</code>
-directory, then execute:
-<pre style="margin-top:.5em">adb -d forward tcp:5601 tcp:5601</pre>
-<p class="note"><strong>Note:</strong> You must execute this command each time you connect your
-device over USB.</p>
-</li>
-<li>Return to the Android Wear Preview app. It should now indicate that it is connected to
- the emulator. The Android Wear emulator should now show the 'g' orb icon, indicating
- that is is connected to your device.
-</ol>
-
-<p>Now, notifications from your device also appear in the Android Wear emulator.</p>
-
-
-
-
-<h2 id="AddLibrary">4. Add the Support Library to Your Project</h2>
-
-<p>The Android Wear preview support library includes several APIs that allow you to
-optimize your app's notifications for the Android Wear user experience.</p>
-
-<p>To receive the preview support library, you must <a
-href="/wear/preview/signup.html">sign up for the Developer Preview</a>. The
-confirmation email you receive after you sign up includes a link to download a ZIP file,
-which contains the preview support library and some sample apps.</p>
-
-<p>After you download and unzip the package, add the preview support library
-sto your Android project:</p>
-
-<p><b>If you're using Eclipse:</b></p>
- <ol>
- <li>In your Android app project, create a <code>libs/</code> directory in your project root
- (the same location as the <code>AndroidManifest.xml</code> file).</li>
- <li>Copy the v4 support library JAR file from your Android SDK directory (e.g.,
- <code>&lt;sdk&gt;/extras/android/support/v4/android-support-v4.jar</code>) into your
- project <code>libs/</code> directory.
- <li>Also save the <code>wearable-preview-support.jar</code> file in the <code>libs/</code> directory.
- <li>Right click each JAR file and select <strong>Build Path &gt; Add to Build Path</strong>.</li>
- </ol>
-
- <p><b>If you're using Android Studio:</b></p>
- <ol>
- <li>In your Android app project, create a <code>libs/</code> directory in your project root
- (the same location as the <code>AndroidManifest.xml</code> file).</li>
- <li>Save the <code>wearable-preview-support.jar</code> file in the <code>libs/</code> directory.
- <li>Open the <code>build.gradle</code> file in your app module.</li>
- <li>Add a dependency rule for both the v4 support library and the Android Wear
- preview support library:
-<pre>
-dependencies {
- compile "com.android.support:support-v4:18.0.+"
- compile files('../libs/wearable-preview-support.jar')
-}
-</pre>
- </li>
- <li>Click <strong>Sync Project with Gradle Files</strong> in the toolbar.</li>
- </ol>
-
-<p>To start optimizing your notifications for Android Wear,
- read <a href="/wear/notifications/creating.html"
- >Creating Notifications for Android Wear</a>.</p>
-
-
-
-</body>
-</html>
-
- </div>
-
- <div class="content-footer layout-content-row"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-9" style="padding-top:4px">
-
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- <div class="paging-links layout-content-col col-4">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" >
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
- <div id="footerlinks">
-
- <p>
- <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
- <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
- <a href="/support.html">Support</a>
- </p>
- </div>
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
-
-<!-- Start of Tag -->
-<script type="text/javascript">
-var axel = Math.random() + "";
-var a = axel * 10000000000000;
-document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
-</script>
-<noscript>
-<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
-</noscript>
-<!-- End of Tag -->
-</body>
-</html>
-
-
-
diff --git a/docs/html/wear/preview/start.jd b/docs/html/wear/preview/start.jd
new file mode 100644
index 0000000..f8f0129
--- /dev/null
+++ b/docs/html/wear/preview/start.jd
@@ -0,0 +1,254 @@
+page.title=Get Started with the Developer Preview
+
+@jd:body
+
+
+<div class="cols">
+
+ <div class="col-5">
+<p>The Android Wear Developer Preview includes tools and APIs that allow you to
+enhance your app notifications
+to provide an optimized user experience on Android wearables.</p>
+
+<p>With the Android Wear Developer Preview, you can:</p>
+
+<ul>
+ <li>Run the Android Wear platform in the Android emulator.</li>
+ <li>Connect your Android device to the emulator and view notifications from the
+device as cards on Android Wear.</li>
+ <li>Try new APIs in the preview support library that enhance your app's notifications
+with features such as voice replies and notification pages.</li>
+</ul>
+
+<p>To get access to the Developer Preview tools,
+click the sign up button on the right, then follow the setup instructions below.</p>
+ </div>
+
+ <div class="col-7">
+<img src="/wear/images/laptop-bridge.png" width="400" height="222" alt="" />
+
+<a href="/wear/preview/signup.html" class="button" style="
+ width: 370px;
+ margin: 10px 0 20px;
+ font-weight: bold;
+ font-size: 16px;
+">Sign Up for the Developer Preview</a>
+
+<p>Signing up provides you access to:</p>
+<ul>
+<li>New notification APIs in the preview support library.</li>
+<li>Sample apps using the new notification APIs.</li>
+<li>The <em>Android Wear Preview</em> app for your mobile device, which connects
+your device to the Android Wear emulator.</li>
+</ul>
+
+ </div>
+</div>
+
+
+<p class="caution"><strong>Caution:</strong>
+The current Android Wear Developer Preview is intended for <b>development and testing purposes only</b>, not for production apps. Google may change this Developer Preview significantly prior to the official release of the Android Wear SDK. You may not publicly distribute or ship any application using this Developer Preview, as this Developer Preview will no longer be supported after the official SDK is released (which will cause applications based only on the Developer Preview to break).</p>
+
+
+
+
+<h2 id="Prereq">Prerequisites</h2>
+
+<p>Before you begin the setup, you must:</p>
+
+<ol>
+ <li><a href="{@docRoot}sdk/index.html"><b>Install the Android SDK</b></a>.
+ <p>The Android SDK includes all the developer tools required to build
+apps for Android (optional IDEs are also available for download).</p></li>
+ <li><a href="{@docRoot}wear/preview/signup.html"><b>Sign up for the Android Wear Developer Preview</b></a>.
+ <p>You must sign up with a Gmail or other Google account in order to download the
+preview support library and receive access to the
+<em>Android Wear Preview</em> beta app on Google Play Store.</p></li>
+</ol>
+
+<p class="note"><strong>Note:</strong>
+If you're using the ADT plugin for Eclipse, you must update to version 22.6.1 or higher.
+If you're using Android Studio, you must update to version 0.5.1 or higher</p>
+
+
+
+<h2 id="Install">1. Install the Android Wear System Image</h2>
+
+
+<ol>
+ <li>Launch <a href="{@docRoot}tools/help/sdk-manager.html"
+ >Android SDK Manager</a>.
+ <ul>
+ <li>From Eclipse, select <b>Window > Android SDK Manager</b>.</li>
+ <li>From Android Studio, select <b>Tools > Android > SDK Manager</b>.</li>
+ </ul>
+ </li>
+ <li>Below Tools, verify that you have Android SDK Tools revision 22.6 or higher.
+ <p>If your version of Android SDK Tools is lower than 22.6, you must update:</p>
+ <ol>
+ <li>Select <strong>Android SDK Tools</strong>.</li>
+ <li>Click <strong>Install package</strong>.</li>
+ <li>Accept the license and click <strong>Install</strong>.</li>
+ <li>When the installation completes, restart Android SDK Manager.</li>
+ </ol>
+ </li>
+
+ <li>Below Android 4.4.2, select <strong>Android Wear ARM EABI v7a System Image</strong>.
+<p class="note"><strong>Note:</strong> Android Wear is designed to support multiple processor architectures.
+</p></li>
+ <li>Below Extras, ensure that you have the latest version of the
+<a href="{@docRoot}tools/support-library/index.html">Android Support Library</a>.
+ If an update is available, select <strong>Android Support Library</strong>. If you're using Android Studio, also select <strong>Android Support Repository</strong>.</li>
+ <li>Click <strong>Install packages</strong>.</li>
+ <li>Accept the license and click <strong>Install</strong>.</li>
+</ol>
+
+
+
+<h2 id="SetupEmulator">2. Set Up the Android Wear Emulator</h2>
+
+<ol>
+<li>Launch the <a href="{@docRoot}tools/help/avd-manager.html"
+ >Android Virtual Device Manager</a>.
+<ul>
+<li>From Eclipse, select <b>Window > Android Virtual Device Manager</b>.</li>
+<li>From Android Studio, select <b>Tools > Android > AVD Manager</b>.</li>
+</ul>
+</li>
+<li>Click <strong>New</strong>.</li>
+<li>For the AVD Name, enter "AndroidWearSquare" or "AndroidWearRound", depending on whether
+you want to create an emulator with a square or round display.</li>
+<li>For the Device, select <strong>Android Wear Square</strong> or
+ <strong>Android Wear Round</strong>.</li>
+<li>For the Target, select <strong>Android 4.4.2 - API Level 19</strong> (or higher).</li>
+<li>For the CPU/ABI, select <strong>Android Wear ARM (armeabi-v7a)</strong>.
+<p class="note"><strong>Note:</strong> Android Wear is designed to support multiple processor architectures.
+</p></li>
+<li>For the Skin, select <strong>AndroidWearSquare</strong> or
+<strong>AndroidWearRound</strong>.</li>
+<li>Leave all other options set to their defaults and click <strong>OK</strong>.
+ <p>Although real Android wearables do not provide a keyboard as an input method,
+ you should keep <strong>Hardware keyboard present</strong> selected so you can
+ provide text input on screens where users will instead provide voice input.</p>
+</li>
+<!--
+<li>Click <strong>Device Definitions</strong>.</li>
+<li>Select <strong>Android WearSquare</strong> then click <strong>Create AVD</strong>.</li>
+<li>Click <strong>OK</strong>.</li>
+-->
+<li>In the list of AVDs, select the one you just created and click
+ <strong>Start</strong>. In the following window, click <strong>Launch</strong>.</li>
+</ol>
+
+<p>The Android Wear emulator now starts. To begin testing your app's notifications,
+you must now pair the emulator to your development device
+that has the <em>Android Wear Preview</em> app installed.</p>
+
+<p class="note"><strong>Tip:</strong> To improve the emulator startup time, edit your AVD
+and enable <strong>Snapshot</strong> under Emulator Options. When you start the emulator,
+select <strong>Save to snapshot</strong> then click <strong>Launch</strong>. Once the emulator
+is running, close it to save a snapshot of the system.
+Start the AVD again, but select <strong>Launch from snapshot</strong> and
+deselect <strong>Save to snapshot</strong>.</p>
+
+<p class="caution"><strong>Caution:</strong> Do not install apps on the Android Wear emulator.
+The system does not support traditional Android apps and the result of running such apps is
+unpredictable.</p>
+
+
+
+<h2 id="SetupApp">3. Set Up the Android Wear Preview App</h2>
+
+<p>To view your app's notifications on the Android Wear emulator, you must have the
+<em>Android Wear Preview</em> app installed on your Android device (a phone or tablet).</p>
+
+<p>To receive the Android Wear Preview app, you must <a
+href="{@docRoot}wear/preview/signup.html">sign up for the Developer Preview</a> using the same
+Gmail or Google account you use with Google Play Store.</p>
+</p>
+
+<p class="note"><strong>Note:</strong> The <em>Android Wear Preview</em> app is compatible with
+ Android 4.3 and higher and is not available for the Android emulator.</p>
+
+<p>After you've signed up for the Developer Preview,
+ you'll receive a confirmation email that includes a link to opt-in to the
+ <em>Android Wear Preview</em> app beta program. Once you opt-in, it may take up to 24 hours for the
+ app to become available in Google Play Store.</p>
+
+<p>After you install the <em>Android Wear Preview</em> app, you can set up
+ your device to communicate with the Android Wear emulator:</p>
+
+<ol>
+<li>Open the <em>Android Wear Preview</em> app. You should see a notice that the app is currently
+ not enabled as a notification listener. Tap the message to open the system settings,
+ then select Android Wear Preview to grant it notification access.</li>
+<li>Connect your device to your development machine over USB. Be sure that no other
+ Android devices are connected to the machine.</li>
+<li>Ensure that the Android Wear emulator (created in the previous section) is running.
+The emulator should show the time and an icon that indicates no device is connected.</li>
+<li>Open a command line terminal, navigate to your Android SDK's <code>platform-tools/</code>
+directory, then execute:
+<pre style="margin-top:.5em">adb -d forward tcp:5601 tcp:5601</pre>
+<p class="note"><strong>Note:</strong> You must execute this command each time you connect your
+device over USB.</p>
+</li>
+<li>Return to the Android Wear Preview app. It should now indicate that it is connected to
+ the emulator. The Android Wear emulator should now show the 'g' orb icon, indicating
+ that is is connected to your device.
+</ol>
+
+<p>Now, notifications from your device also appear in the Android Wear emulator.</p>
+
+
+
+
+<h2 id="AddLibrary">4. Add the Support Library to Your Project</h2>
+
+<p>The Android Wear preview support library includes several APIs that allow you to
+optimize your app's notifications for the Android Wear user experience.</p>
+
+<p>To receive the preview support library, you must <a
+href="{@docRoot}wear/preview/signup.html">sign up for the Developer Preview</a>. The
+confirmation email you receive after you sign up includes a link to download a ZIP file,
+which contains the preview support library and some sample apps.</p>
+
+<p>After you download and unzip the package, add the preview support library
+sto your Android project:</p>
+
+<p><b>If you're using Eclipse:</b></p>
+ <ol>
+ <li>In your Android app project, create a <code>libs/</code> directory in your project root
+ (the same location as the <code>AndroidManifest.xml</code> file).</li>
+ <li>Copy the v4 support library JAR file from your Android SDK directory (e.g.,
+ <code>&lt;sdk&gt;/extras/android/support/v4/android-support-v4.jar</code>) into your
+ project <code>libs/</code> directory.
+ <li>Also save the <code>wearable-preview-support.jar</code> file in the <code>libs/</code> directory.
+ <li>Right click each JAR file and select <strong>Build Path &gt; Add to Build Path</strong>.</li>
+ </ol>
+
+ <p><b>If you're using Android Studio:</b></p>
+ <ol>
+ <li>In your Android app project, create a <code>libs/</code> directory in your project root
+ (the same location as the <code>AndroidManifest.xml</code> file).</li>
+ <li>Save the <code>wearable-preview-support.jar</code> file in the <code>libs/</code> directory.
+ <li>Open the <code>build.gradle</code> file in your app module.</li>
+ <li>Add a dependency rule for both the v4 support library and the Android Wear
+ preview support library:
+<pre>
+dependencies {
+ compile "com.android.support:support-v4:18.0.+"
+ compile files('../libs/wearable-preview-support.jar')
+}
+</pre>
+ </li>
+ <li>Click <strong>Sync Project with Gradle Files</strong> in the toolbar.</li>
+ </ol>
+
+<p>To start optimizing your notifications for Android Wear,
+ read <a href="{@docRoot}wear/notifications/creating.html"
+ >Creating Notifications for Android Wear</a>.</p>
+
+
+
+</body>
+</html>
diff --git a/docs/html/wear/wear_toc.cs b/docs/html/wear/wear_toc.cs
new file mode 100644
index 0000000..65ac2e9
--- /dev/null
+++ b/docs/html/wear/wear_toc.cs
@@ -0,0 +1,74 @@
+<ul id="nav">
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/preview/start.html">Get Started
+ </a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/design/user-interface.html">UI Overview
+ </a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/design/index.html">Design Principles
+ </a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/notifications/creating.html">Creating Notifications for Android Wear
+ </a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+ </a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/notifications/pages.html">Adding Pages to a Notification
+ </a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/notifications/stacks.html">Stacking Notifications
+ </a></div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+ <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+ <ul>
+<li><a href="<?cs var:toroot ?>reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+ </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="<?cs var:toroot ?>reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="<?cs var:toroot ?>reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="<?cs var:toroot ?>reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="<?cs var:toroot ?>reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="<?cs var:toroot ?>reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="<?cs var:toroot ?>reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+ </ul>
+ </li>
+</ul>
+</li>
+
+
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>wear/license.html">License Agreement</a></div>
+ </li>
+
+
+</ul>
diff --git a/graphics/java/android/graphics/TemporaryBuffer.java b/graphics/java/android/graphics/TemporaryBuffer.java
index c5b8143..36a2275 100644
--- a/graphics/java/android/graphics/TemporaryBuffer.java
+++ b/graphics/java/android/graphics/TemporaryBuffer.java
@@ -31,7 +31,7 @@ public class TemporaryBuffer {
}
if (buf == null || buf.length < len) {
- buf = new char[ArrayUtils.idealCharArraySize(len)];
+ buf = ArrayUtils.newUnpaddedCharArray(len);
}
return buf;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index de2b68f..e320c67 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -1054,14 +1054,14 @@ public abstract class Drawable {
drawable = new LayerDrawable();
} else if (name.equals("transition")) {
drawable = new TransitionDrawable();
- } else if (name.equals("reveal")) {
- drawable = new RevealDrawable();
} else if (name.equals("touch-feedback")) {
drawable = new TouchFeedbackDrawable();
} else if (name.equals("color")) {
drawable = new ColorDrawable();
} else if (name.equals("shape")) {
drawable = new GradientDrawable();
+ } else if (name.equals("vector")) {
+ drawable = new VectorDrawable();
} else if (name.equals("scale")) {
drawable = new ScaleDrawable();
} else if (name.equals("clip")) {
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 3d48cda..3c3c841 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -839,7 +839,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
/**
* Ensures the child padding caches are large enough.
*/
- private void ensurePadding() {
+ void ensurePadding() {
final int N = mLayerState.mNum;
if (mPaddingL != null && mPaddingL.length >= N) {
return;
diff --git a/graphics/java/android/graphics/drawable/RevealDrawable.java b/graphics/java/android/graphics/drawable/RevealDrawable.java
deleted file mode 100644
index 2f96fe4..0000000
--- a/graphics/java/android/graphics/drawable/RevealDrawable.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.SparseArray;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * An extension of LayerDrawable that is intended to react to touch hotspots
- * and reveal the second layer atop the first.
- * <p>
- * It can be defined in an XML file with the <code>&lt;reveal&gt;</code> element.
- * Each Drawable in the transition is defined in a nested <code>&lt;item&gt;</code>.
- * For more information, see the guide to <a href="{@docRoot}
- * guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
- *
- * @attr ref android.R.styleable#LayerDrawableItem_left
- * @attr ref android.R.styleable#LayerDrawableItem_top
- * @attr ref android.R.styleable#LayerDrawableItem_right
- * @attr ref android.R.styleable#LayerDrawableItem_bottom
- * @attr ref android.R.styleable#LayerDrawableItem_drawable
- * @attr ref android.R.styleable#LayerDrawableItem_id
- */
-public class RevealDrawable extends LayerDrawable {
- private final Rect mTempRect = new Rect();
-
- /** Lazily-created map of touch hotspot IDs to ripples. */
- private SparseArray<Ripple> mTouchedRipples;
-
- /** Lazily-created list of actively animating ripples. */
- private ArrayList<Ripple> mActiveRipples;
-
- /** Lazily-created runnable for scheduling invalidation. */
- private Runnable mAnimationRunnable;
-
- /** Whether the animation runnable has been posted. */
- private boolean mAnimating;
-
- /** Target density, used to scale density-independent pixels. */
- private float mDensity = 1.0f;
-
- /** Paint used to control appearance of ripples. */
- private Paint mRipplePaint;
-
- /** Paint used to control reveal layer masking. */
- private Paint mMaskingPaint;
-
- /**
- * Create a new reveal drawable with the specified list of layers. At least
- * two layers are required for this drawable to work properly.
- */
- public RevealDrawable(Drawable[] layers) {
- this(new RevealState(null, null, null), layers);
- }
-
- /**
- * Create a new reveal drawable with no layers. To work correctly, at least
- * two layers must be added to this drawable.
- *
- * @see #RevealDrawable(Drawable[])
- */
- RevealDrawable() {
- this(new RevealState(null, null, null), (Resources) null, null);
- }
-
- private RevealDrawable(RevealState state, Resources res) {
- super(state, res, null);
- }
-
- private RevealDrawable(RevealState state, Resources res, Theme theme) {
- super(state, res, theme);
- }
-
- private RevealDrawable(RevealState state, Drawable[] layers) {
- super(layers, state);
- }
-
- @Override
- public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
- throws XmlPullParserException, IOException {
- super.inflate(r, parser, attrs, theme);
-
- setTargetDensity(r.getDisplayMetrics());
- setPaddingMode(PADDING_MODE_STACK);
- }
-
- @Override
- LayerState createConstantState(LayerState state, Resources res) {
- return new RevealState((RevealState) state, this, res);
- }
-
- /**
- * Set the density at which this drawable will be rendered.
- *
- * @param metrics The display metrics for this drawable.
- */
- private void setTargetDensity(DisplayMetrics metrics) {
- if (mDensity != metrics.density) {
- mDensity = metrics.density;
- invalidateSelf();
- }
- }
-
- /**
- * @hide until hotspot APIs are finalized
- */
- @Override
- public boolean supportsHotspots() {
- return true;
- }
-
- /**
- * @hide until hotspot APIs are finalized
- */
- @Override
- public void setHotspot(int id, float x, float y) {
- if (mTouchedRipples == null) {
- mTouchedRipples = new SparseArray<Ripple>();
- mActiveRipples = new ArrayList<Ripple>();
- }
-
- final Ripple ripple = mTouchedRipples.get(id);
- if (ripple == null) {
- final Rect padding = mTempRect;
- getPadding(padding);
-
- final Ripple newRipple = new Ripple(getBounds(), padding, x, y, mDensity);
- newRipple.enter();
-
- mActiveRipples.add(newRipple);
- mTouchedRipples.put(id, newRipple);
- } else {
- ripple.move(x, y);
- }
-
- scheduleAnimation();
- }
-
- /**
- * @hide until hotspot APIs are finalized
- */
- @Override
- public void removeHotspot(int id) {
- if (mTouchedRipples == null) {
- return;
- }
-
- final Ripple ripple = mTouchedRipples.get(id);
- if (ripple != null) {
- ripple.exit();
-
- mTouchedRipples.remove(id);
- scheduleAnimation();
- }
- }
-
- /**
- * @hide until hotspot APIs are finalized
- */
- @Override
- public void clearHotspots() {
- if (mTouchedRipples == null) {
- return;
- }
-
- final int n = mTouchedRipples.size();
- for (int i = 0; i < n; i++) {
- final Ripple ripple = mTouchedRipples.valueAt(i);
- ripple.exit();
- }
-
- if (n > 0) {
- mTouchedRipples.clear();
- scheduleAnimation();
- }
- }
-
- /**
- * Schedules the next animation, if necessary.
- */
- private void scheduleAnimation() {
- if (mActiveRipples == null || mActiveRipples.isEmpty()) {
- mAnimating = false;
- } else if (!mAnimating) {
- mAnimating = true;
-
- if (mAnimationRunnable == null) {
- mAnimationRunnable = new Runnable() {
- @Override
- public void run() {
- mAnimating = false;
- scheduleAnimation();
- invalidateSelf();
- }
- };
- }
-
- scheduleSelf(mAnimationRunnable, SystemClock.uptimeMillis() + 1000 / 60);
- }
- }
-
- @Override
- public void draw(Canvas canvas) {
- final int layerCount = getNumberOfLayers();
- if (layerCount == 0) {
- return;
- }
-
- getDrawable(0).draw(canvas);
-
- final Rect bounds = getBounds();
- final ArrayList<Ripple> activeRipples = mActiveRipples;
- if (layerCount == 1 || bounds.isEmpty() || activeRipples == null
- || activeRipples.isEmpty()) {
- // Nothing to reveal, we're done here.
- return;
- }
-
- if (mRipplePaint == null) {
- mRipplePaint = new Paint();
- mRipplePaint.setAntiAlias(true);
- }
-
- // Draw ripple mask into a buffer that merges using SRC_OVER.
- boolean needsMask = false;
- int layerSaveCount = -1;
- int n = activeRipples.size();
- for (int i = 0; i < n; i++) {
- final Ripple ripple = activeRipples.get(i);
- if (!ripple.active()) {
- activeRipples.remove(i);
- i--;
- n--;
- } else {
- if (layerSaveCount < 0) {
- layerSaveCount = canvas.saveLayer(
- bounds.left, bounds.top, bounds.right, bounds.bottom, null, 0);
- // Ripples must be clipped to bounds, otherwise SRC_IN will
- // miss them and we'll get artifacts.
- canvas.clipRect(bounds);
- }
-
- needsMask |= ripple.draw(canvas, mRipplePaint);
- }
- }
-
- // If a layer was saved, it contains the ripple mask. Draw the reveal
- // into another layer and composite using SRC_IN, then composite onto
- // the original canvas.
- if (layerSaveCount >= 0) {
- if (needsMask) {
- if (mMaskingPaint == null) {
- mMaskingPaint = new Paint();
- mMaskingPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
- }
-
- // TODO: When Drawable.setXfermode() is supported by all drawables,
- // we won't need an extra layer.
- canvas.saveLayer(
- bounds.left, bounds.top, bounds.right, bounds.bottom, mMaskingPaint, 0);
- getDrawable(1).draw(canvas);
- }
-
- canvas.restoreToCount(layerSaveCount);
- }
- }
-
- private static class RevealState extends LayerState {
- public RevealState(RevealState orig, RevealDrawable owner, Resources res) {
- super(orig, owner, res);
- }
-
- @Override
- public Drawable newDrawable() {
- return newDrawable(null);
- }
-
- @Override
- public Drawable newDrawable(Resources res) {
- return new RevealDrawable(this, res);
- }
-
- @Override
- public Drawable newDrawable(Resources res, Theme theme) {
- return new RevealDrawable(this, res, theme);
- }
- }
-}
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java
index 618afb8..03dd841 100644
--- a/graphics/java/android/graphics/drawable/Ripple.java
+++ b/graphics/java/android/graphics/drawable/Ripple.java
@@ -43,34 +43,16 @@ class Ripple {
/** Resistance factor when constraining outside touches. */
private static final float OUTSIDE_RESISTANCE = 0.7f;
- /** Duration for animating the trailing edge of the ripple. */
- private static final int EXIT_DURATION = 600;
-
- /** Duration for animating the leading edge of the ripple. */
- private static final int ENTER_DURATION = 400;
-
- /** Minimum elapsed time between start of enter and exit animations. */
- private static final int EXIT_MIN_DELAY = 200;
-
- /** Duration for animating between inside and outside touch. */
- private static final int OUTSIDE_DURATION = 300;
-
- /** Duration for animating pulses. */
- private static final int PULSE_DURATION = 400;
-
- /** Interval between pulses while inside and fully entered. */
- private static final int PULSE_INTERVAL = 400;
-
/** Minimum alpha value during a pulse animation. */
private static final int PULSE_MIN_ALPHA = 128;
- /** Delay before pulses start. */
- private static final int PULSE_DELAY = 500;
-
private final Rect mBounds;
private final Rect mPadding;
- private final int mMinRadius;
- private final int mOutsideRadius;
+
+ private RippleAnimator mAnimator;
+
+ private int mMinRadius;
+ private int mOutsideRadius;
/** Center x-coordinate. */
private float mX;
@@ -80,15 +62,18 @@ class Ripple {
/** Whether the center is within the parent bounds. */
private boolean mInside;
+
+ /** Enter state. A value in [0...1] or -1 if not set. */
+ private float mEnterState = -1;
- /** When the ripple started appearing. */
- private long mEnterTime = -1;
+ /** Exit state. A value in [0...1] or -1 if not set. */
+ private float mExitState = -1;
- /** When the ripple started vanishing. */
- private long mExitTime = -1;
+ /** Outside state. A value in [0...1] or -1 if not set. */
+ private float mOutsideState = -1;
- /** When the ripple last transitioned between inside and outside touch. */
- private long mOutsideTime = -1;
+ /** Pulse state. A value in [0...1] or -1 if not set. */
+ private float mPulseState = -1;
/**
* Creates a new ripple with the specified parent bounds, padding, initial
@@ -105,6 +90,14 @@ class Ripple {
mMinRadius = (int) (density * STARTING_RADIUS_DP + 0.5f);
mOutsideRadius = (int) (density * OUTSIDE_RADIUS_DP + 0.5f);
}
+
+ public void setMinRadius(int minRadius) {
+ mMinRadius = minRadius;
+ }
+
+ public void setOutsideRadius(int outsideRadius) {
+ mOutsideRadius = outsideRadius;
+ }
/**
* Updates the center coordinates.
@@ -115,49 +108,18 @@ class Ripple {
final boolean inside = mBounds.contains((int) x, (int) y);
if (mInside != inside) {
- mOutsideTime = AnimationUtils.currentAnimationTimeMillis();
+ if (mAnimator != null) {
+ mAnimator.outside();
+ }
mInside = inside;
}
}
- /**
- * Starts the enter animation.
- */
- public void enter() {
- mEnterTime = AnimationUtils.currentAnimationTimeMillis();
- }
-
- /**
- * Starts the exit animation. If {@link #enter()} was called recently, the
- * animation may be postponed.
- */
- public void exit() {
- final long minTime = mEnterTime + EXIT_MIN_DELAY;
- mExitTime = Math.max(minTime, AnimationUtils.currentAnimationTimeMillis());
- }
-
- /**
- * Returns whether this ripple is currently animating.
- */
- public boolean active() {
- final long currentTime = AnimationUtils.currentAnimationTimeMillis();
- return mEnterTime >= 0 && mEnterTime <= currentTime
- && (mExitTime < 0 || currentTime <= mExitTime + EXIT_DURATION);
- }
-
- /**
- * Constrains a value within a specified asymptotic margin outside a minimum
- * and maximum.
- */
- private static float looseConstrain(float value, float min, float max, float margin,
- float factor) {
- if (value < min) {
- return min - Math.min(margin, (float) Math.pow(min - value, factor));
- } else if (value > max) {
- return max + Math.min(margin, (float) Math.pow(value - max, factor));
- } else {
- return value;
+ public RippleAnimator animate() {
+ if (mAnimator == null) {
+ mAnimator = new RippleAnimator(this);
}
+ return mAnimator;
}
public boolean draw(Canvas c, Paint p) {
@@ -167,17 +129,10 @@ class Ripple {
final float dY = Math.max(mY, bounds.bottom - mY);
final int maxRadius = (int) Math.ceil(Math.sqrt(dX * dX + dY * dY));
- // Track three states:
- // - Enter: touch begins, affects outer radius
- // - Outside: touch moves outside bounds, affects maximum outer radius
- // - Exit: touch ends, affects inner radius
- final long currentTime = AnimationUtils.currentAnimationTimeMillis();
- final float enterState = mEnterTime < 0 ? 0 : INTERPOLATOR.getInterpolation(
- MathUtils.constrain((currentTime - mEnterTime) / (float) ENTER_DURATION, 0, 1));
- final float outsideState = mOutsideTime < 0 ? 1 : INTERPOLATOR.getInterpolation(
- MathUtils.constrain((currentTime - mOutsideTime) / (float) OUTSIDE_DURATION, 0, 1));
- final float exitState = mExitTime < 0 ? 0 : INTERPOLATOR.getInterpolation(
- MathUtils.constrain((currentTime - mExitTime) / (float) EXIT_DURATION, 0, 1));
+ final float enterState = mEnterState;
+ final float exitState = mExitState;
+ final float outsideState = mOutsideState;
+ final float pulseState = mPulseState;
final float insideRadius = MathUtils.lerp(mMinRadius, maxRadius, enterState);
final float outerRadius = MathUtils.lerp(mOutsideRadius, insideRadius,
mInside ? outsideState : 1 - outsideState);
@@ -189,35 +144,28 @@ class Ripple {
outerRadius * OUTSIDE_MARGIN, OUTSIDE_RESISTANCE);
// Compute maximum alpha, taking pulse into account when active.
- final long pulseTime = (currentTime - mEnterTime - ENTER_DURATION - PULSE_DELAY);
final int maxAlpha;
- if (pulseTime < 0) {
+ if (pulseState < 0 || pulseState >= 1) {
maxAlpha = 255;
} else {
- final float pulseState = (pulseTime % (PULSE_INTERVAL + PULSE_DURATION))
- / (float) PULSE_DURATION;
- if (pulseState >= 1) {
- maxAlpha = 255;
+ final float pulseAlpha;
+ if (pulseState > 0.5) {
+ // Pulsing in to max alpha.
+ pulseAlpha = MathUtils.lerp(PULSE_MIN_ALPHA, 255, (pulseState - .5f) * 2);
} else {
- final float pulseAlpha;
- if (pulseState > 0.5) {
- // Pulsing in to max alpha.
- pulseAlpha = MathUtils.lerp(PULSE_MIN_ALPHA, 255, (pulseState - .5f) * 2);
- } else {
- // Pulsing out to min alpha.
- pulseAlpha = MathUtils.lerp(255, PULSE_MIN_ALPHA, pulseState * 2f);
- }
+ // Pulsing out to min alpha.
+ pulseAlpha = MathUtils.lerp(255, PULSE_MIN_ALPHA, pulseState * 2f);
+ }
- if (exitState > 0) {
- // Animating exit, interpolate pulse with exit state.
- maxAlpha = (int) (MathUtils.lerp(255, pulseAlpha, exitState) + 0.5f);
- } else if (mInside) {
- // No animation, no need to interpolate.
- maxAlpha = (int) (pulseAlpha + 0.5f);
- } else {
- // Animating inside, interpolate pulse with inside state.
- maxAlpha = (int) (MathUtils.lerp(pulseAlpha, 255, outsideState) + 0.5f);
- }
+ if (exitState > 0) {
+ // Animating exit, interpolate pulse with exit state.
+ maxAlpha = (int) (MathUtils.lerp(255, pulseAlpha, exitState) + 0.5f);
+ } else if (mInside) {
+ // No animation, no need to interpolate.
+ maxAlpha = (int) (pulseAlpha + 0.5f);
+ } else {
+ // Animating inside, interpolate pulse with inside state.
+ maxAlpha = (int) (MathUtils.lerp(pulseAlpha, 255, outsideState) + 0.5f);
}
}
@@ -260,4 +208,109 @@ class Ripple {
final int maxRadius = (int) Math.ceil(Math.sqrt(dX * dX + dY * dY));
bounds.set(x - maxRadius, y - maxRadius, x + maxRadius, y + maxRadius);
}
+
+ /**
+ * Constrains a value within a specified asymptotic margin outside a minimum
+ * and maximum.
+ */
+ private static float looseConstrain(float value, float min, float max, float margin,
+ float factor) {
+ if (value < min) {
+ return min - Math.min(margin, (float) Math.pow(min - value, factor));
+ } else if (value > max) {
+ return max + Math.min(margin, (float) Math.pow(value - max, factor));
+ } else {
+ return value;
+ }
+ }
+
+ public static class RippleAnimator {
+ /** Duration for animating the trailing edge of the ripple. */
+ private static final int EXIT_DURATION = 600;
+
+ /** Duration for animating the leading edge of the ripple. */
+ private static final int ENTER_DURATION = 400;
+
+ /** Minimum elapsed time between start of enter and exit animations. */
+ private static final int EXIT_MIN_DELAY = 200;
+
+ /** Duration for animating between inside and outside touch. */
+ private static final int OUTSIDE_DURATION = 300;
+
+ /** Duration for animating pulses. */
+ private static final int PULSE_DURATION = 400;
+
+ /** Interval between pulses while inside and fully entered. */
+ private static final int PULSE_INTERVAL = 400;
+
+ /** Delay before pulses start. */
+ private static final int PULSE_DELAY = 500;
+
+ /** The target ripple being animated. */
+ private final Ripple mTarget;
+
+ /** When the ripple started appearing. */
+ private long mEnterTime = -1;
+
+ /** When the ripple started vanishing. */
+ private long mExitTime = -1;
+
+ /** When the ripple last transitioned between inside and outside touch. */
+ private long mOutsideTime = -1;
+
+ public RippleAnimator(Ripple target) {
+ mTarget = target;
+ }
+
+ /**
+ * Starts the enter animation.
+ */
+ public void enter() {
+ mEnterTime = AnimationUtils.currentAnimationTimeMillis();
+ }
+
+ /**
+ * Starts the exit animation. If {@link #enter()} was called recently, the
+ * animation may be postponed.
+ */
+ public void exit() {
+ final long minTime = mEnterTime + EXIT_MIN_DELAY;
+ mExitTime = Math.max(minTime, AnimationUtils.currentAnimationTimeMillis());
+ }
+
+ /**
+ * Starts the outside transition animation.
+ */
+ public void outside() {
+ mOutsideTime = AnimationUtils.currentAnimationTimeMillis();
+ }
+
+ /**
+ * Returns whether this ripple is currently animating.
+ */
+ public boolean isRunning() {
+ final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+ return mEnterTime >= 0 && mEnterTime <= currentTime
+ && (mExitTime < 0 || currentTime <= mExitTime + EXIT_DURATION);
+ }
+
+ public void update() {
+ // Track three states:
+ // - Enter: touch begins, affects outer radius
+ // - Outside: touch moves outside bounds, affects maximum outer radius
+ // - Exit: touch ends, affects inner radius
+ final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+ mTarget.mEnterState = mEnterTime < 0 ? 0 : INTERPOLATOR.getInterpolation(
+ MathUtils.constrain((currentTime - mEnterTime) / (float) ENTER_DURATION, 0, 1));
+ mTarget.mExitState = mExitTime < 0 ? 0 : INTERPOLATOR.getInterpolation(
+ MathUtils.constrain((currentTime - mExitTime) / (float) EXIT_DURATION, 0, 1));
+ mTarget.mOutsideState = mOutsideTime < 0 ? 1 : INTERPOLATOR.getInterpolation(
+ MathUtils.constrain((currentTime - mOutsideTime) / (float) OUTSIDE_DURATION, 0, 1));
+
+ // Pulse is a little more complicated.
+ final long pulseTime = (currentTime - mEnterTime - ENTER_DURATION - PULSE_DELAY);
+ mTarget.mPulseState = pulseTime < 0 ? -1
+ : (pulseTime % (PULSE_INTERVAL + PULSE_DURATION)) / (float) PULSE_DURATION;
+ }
+ }
}
diff --git a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
index 47a9374..b66d86d 100644
--- a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
+++ b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
@@ -25,6 +25,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
+import android.graphics.drawable.Ripple.RippleAnimator;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.SystemClock;
@@ -43,7 +44,13 @@ import java.util.ArrayList;
/**
* Documentation pending.
*/
-public class TouchFeedbackDrawable extends DrawableWrapper {
+public class TouchFeedbackDrawable extends LayerDrawable {
+ private static final PorterDuffXfermode DST_ATOP = new PorterDuffXfermode(Mode.DST_ATOP);
+ private static final PorterDuffXfermode DST_IN = new PorterDuffXfermode(Mode.DST_IN);
+
+ /** The maximum number of ripples supported. */
+ private static final int MAX_RIPPLES = 10;
+
private final Rect mTempRect = new Rect();
private final Rect mPaddingRect = new Rect();
@@ -58,8 +65,9 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
/** Lazily-created map of touch hotspot IDs to ripples. */
private SparseArray<Ripple> mTouchedRipples;
- /** Lazily-created list of actively animating ripples. */
- private ArrayList<Ripple> mActiveRipples;
+ /** Lazily-created array of actively animating ripples. */
+ private Ripple[] mActiveRipples;
+ private int mActiveRipplesCount = 0;
/** Lazily-created runnable for scheduling invalidation. */
private Runnable mAnimationRunnable;
@@ -76,43 +84,14 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
/** Whether the animation runnable has been posted. */
private boolean mAnimating;
- /** The drawable to use as the mask. */
- private Drawable mMask;
-
TouchFeedbackDrawable() {
- this(new TouchFeedbackState(null), null, null);
- }
-
- private void setConstantState(TouchFeedbackState wrapperState, Resources res) {
- super.setConstantState(wrapperState, res);
-
- // Load a new mask drawable from the constant state.
- if (wrapperState == null || wrapperState.mMaskState == null) {
- mMask = null;
- } else if (res != null) {
- mMask = wrapperState.mMaskState.newDrawable(res);
- } else {
- mMask = wrapperState.mMaskState.newDrawable();
- }
-
- if (res != null) {
- mDensity = res.getDisplayMetrics().density;
- }
+ this(new TouchFeedbackState(null, null, null), null, null);
}
@Override
public int getOpacity() {
- return mActiveRipples != null && !mActiveRipples.isEmpty() ?
- PixelFormat.TRANSLUCENT : PixelFormat.TRANSPARENT;
- }
-
- @Override
- protected void onBoundsChange(Rect bounds) {
- super.onBoundsChange(bounds);
-
- if (mMask != null) {
- mMask.setBounds(bounds);
- }
+ // Worst-case scenario.
+ return PixelFormat.TRANSLUCENT;
}
@Override
@@ -138,7 +117,7 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
*/
@Override
public boolean isProjected() {
- return mState.mProjected;
+ return getNumberOfLayers() == 0;
}
@Override
@@ -149,59 +128,25 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
- super.inflate(r, parser, attrs, theme);
-
final TypedArray a = obtainAttributes(
r, theme, attrs, R.styleable.TouchFeedbackDrawable);
- inflateStateFromTypedArray(r, a);
+ inflateStateFromTypedArray(a);
a.recycle();
-
- inflateChildElements(r, parser, attrs, theme);
-
- setTargetDensity(r.getDisplayMetrics());
- }
-
- private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
- Theme theme) throws XmlPullParserException, IOException {
- int type;
- while ((type = parser.next()) == XmlPullParser.TEXT) {
- // Find the next non-text element.
- }
-
- if (type == XmlPullParser.START_TAG) {
- final Drawable dr = Drawable.createFromXmlInner(r, parser, attrs);
- setDrawable(dr, r);
- }
- }
- /**
- * Sets the wrapped drawable and update the constant state.
- *
- * @param drawable
- * @param res
- */
- void setMaskDrawable(Drawable drawable, Resources res) {
- mMask = drawable;
-
- if (drawable != null) {
- // Nobody cares if the mask has a callback.
- drawable.setCallback(null);
+ super.inflate(r, parser, attrs, theme);
- mState.mMaskState = drawable.getConstantState();
- } else {
- mState.mMaskState = null;
- }
+ setTargetDensity(r.getDisplayMetrics());
}
/**
* Initializes the constant state from the values in the typed array.
*/
- private void inflateStateFromTypedArray(Resources r, TypedArray a) {
+ private void inflateStateFromTypedArray(TypedArray a) {
final TouchFeedbackState state = mState;
// Extract the theme attributes, if any.
final int[] themeAttrs = a.extractThemeAttrs();
- state.mThemeAttrs = themeAttrs;
+ state.mTouchThemeAttrs = themeAttrs;
if (themeAttrs == null || themeAttrs[R.styleable.TouchFeedbackDrawable_tint] == 0) {
mState.mTint = a.getColorStateList(R.styleable.TouchFeedbackDrawable_tint);
@@ -219,34 +164,6 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
if (themeAttrs == null || themeAttrs[R.styleable.TouchFeedbackDrawable_pinned] == 0) {
mState.mPinned = a.getBoolean(R.styleable.TouchFeedbackDrawable_pinned, false);
}
-
- Drawable mask = mMask;
- if (themeAttrs == null || themeAttrs[R.styleable.TouchFeedbackDrawable_mask] == 0) {
- mask = a.getDrawable(R.styleable.TouchFeedbackDrawable_mask);
- }
-
- Drawable dr = super.getDrawable();
- if (themeAttrs == null || themeAttrs[R.styleable.TouchFeedbackDrawable_drawable] == 0) {
- final int drawableRes = a.getResourceId(R.styleable.TouchFeedbackDrawable_drawable, 0);
- if (drawableRes != 0) {
- dr = r.getDrawable(drawableRes);
- }
- }
-
- // If neither a mask not a bottom layer was specified, assume we're
- // projecting onto a parent surface.
- mState.mProjected = mask == null && dr == null;
-
- if (dr != null) {
- setDrawable(dr, r);
- } else {
- // For now at least, we MUST have a wrapped drawable.
- setDrawable(new ColorDrawable(Color.TRANSPARENT), r);
- }
-
- if (mask != null) {
- setMaskDrawable(mask, r);
- }
}
/**
@@ -271,7 +188,7 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
"Can't apply theme to <touch-feedback> with no constant state");
}
- final int[] themeAttrs = state.mThemeAttrs;
+ final int[] themeAttrs = state.mTouchThemeAttrs;
if (themeAttrs != null) {
final TypedArray a = t.resolveAttributes(
themeAttrs, R.styleable.TouchFeedbackDrawable, 0, 0);
@@ -298,39 +215,11 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
if (a.hasValue(R.styleable.TouchFeedbackDrawable_pinned)) {
mState.mPinned = a.getBoolean(R.styleable.TouchFeedbackDrawable_pinned, false);
}
-
- Drawable mask = mMask;
- if (a.hasValue(R.styleable.TouchFeedbackDrawable_mask)) {
- mask = a.getDrawable(R.styleable.TouchFeedbackDrawable_mask);
- }
-
- Drawable dr = super.getDrawable();
- if (a.hasValue(R.styleable.TouchFeedbackDrawable_drawable)) {
- final int drawableRes = a.getResourceId(R.styleable.TouchFeedbackDrawable_drawable, 0);
- if (drawableRes != 0) {
- dr = a.getResources().getDrawable(drawableRes);
- }
- }
-
- // If neither a mask not a bottom layer was specified, assume we're
- // projecting onto a parent surface.
- mState.mProjected = mask == null && dr == null;
-
- if (dr != null) {
- setDrawable(dr, a.getResources());
- } else {
- // For now at least, we MUST have a wrapped drawable.
- setDrawable(new ColorDrawable(Color.TRANSPARENT), a.getResources());
- }
-
- if (mask != null) {
- setMaskDrawable(mask, a.getResources());
- }
}
@Override
public boolean canApplyTheme() {
- return mState != null && mState.mThemeAttrs != null;
+ return super.canApplyTheme() || mState != null && mState.mTouchThemeAttrs != null;
}
/**
@@ -351,7 +240,7 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
public void setHotspot(int id, float x, float y) {
if (mTouchedRipples == null) {
mTouchedRipples = new SparseArray<Ripple>();
- mActiveRipples = new ArrayList<Ripple>();
+ mActiveRipples = new Ripple[MAX_RIPPLES];
}
final Ripple ripple = mTouchedRipples.get(id);
@@ -366,9 +255,9 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
}
final Ripple newRipple = new Ripple(bounds, padding, x, y, mDensity);
- newRipple.enter();
+ newRipple.animate().enter();
- mActiveRipples.add(newRipple);
+ mActiveRipples[mActiveRipplesCount++] = newRipple;
mTouchedRipples.put(id, newRipple);
} else if (!mState.mPinned) {
ripple.move(x, y);
@@ -388,7 +277,7 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
final Ripple ripple = mTouchedRipples.get(id);
if (ripple != null) {
- ripple.exit();
+ ripple.animate().exit();
mTouchedRipples.remove(id);
scheduleAnimation();
@@ -406,8 +295,7 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
final int n = mTouchedRipples.size();
for (int i = 0; i < n; i++) {
- final Ripple ripple = mTouchedRipples.valueAt(i);
- ripple.exit();
+ mTouchedRipples.valueAt(i).animate().exit();
}
if (n > 0) {
@@ -420,7 +308,7 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
* Schedules the next animation, if necessary.
*/
private void scheduleAnimation() {
- if (mActiveRipples == null || mActiveRipples.isEmpty()) {
+ if (mActiveRipplesCount == 0) {
mAnimating = false;
} else if (!mAnimating) {
mAnimating = true;
@@ -442,53 +330,68 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
@Override
public void draw(Canvas canvas) {
- // The lower layer always draws normally.
- super.draw(canvas);
-
- if (mActiveRipples == null || mActiveRipples.size() == 0) {
- // No ripples to draw.
- return;
- }
-
- final ArrayList<Ripple> activeRipples = mActiveRipples;
- final Drawable mask = mMask == null && !mState.mProjected ? getDrawable() : null;
- final Rect bounds = mask == null ? null : mask.getBounds();
+ final boolean projected = getNumberOfLayers() == 0;
+ final Ripple[] activeRipples = mActiveRipples;
+ final int ripplesCount = mActiveRipplesCount;
+ final Rect bounds = getBounds();
- // Draw ripples into a layer that merges using SRC_IN.
- boolean hasRipples = false;
+ // Draw ripples.
+ boolean drewRipples = false;
int rippleRestoreCount = -1;
- int n = activeRipples.size();
- for (int i = 0; i < n; i++) {
- final Ripple ripple = activeRipples.get(i);
- if (!ripple.active()) {
- // TODO: Mark and sweep is more efficient.
- activeRipples.remove(i);
- i--;
- n--;
+ int activeRipplesCount = 0;
+ for (int i = 0; i < ripplesCount; i++) {
+ final Ripple ripple = activeRipples[i];
+ final RippleAnimator animator = ripple.animate();
+ animator.update();
+ if (!animator.isRunning()) {
+ activeRipples[i] = null;
} else {
- // If we're masking the ripple layer, make sure we have a layer first.
- if (mask != null && rippleRestoreCount < 0) {
+ // If we're masking the ripple layer, make sure we have a layer
+ // first. This will merge SRC_OVER (directly) onto the canvas.
+ if (!projected && rippleRestoreCount < 0) {
rippleRestoreCount = canvas.saveLayer(bounds.left, bounds.top,
- bounds.right, bounds.bottom, getMaskingPaint(SRC_ATOP), 0);
+ bounds.right, bounds.bottom, null, 0);
canvas.clipRect(bounds);
}
- hasRipples |= ripple.draw(canvas, getRipplePaint());
+ drewRipples |= ripple.draw(canvas, getRipplePaint());
+
+ activeRipples[activeRipplesCount] = activeRipples[i];
+ activeRipplesCount++;
+ }
+ }
+ mActiveRipplesCount = activeRipplesCount;
+
+ // TODO: Use the masking layer first, if there is one.
+
+ // If we have ripples and content, we need a masking layer. This will
+ // merge DST_ATOP onto (effectively under) the ripple layer.
+ if (drewRipples && !projected && rippleRestoreCount >= 0) {
+ canvas.saveLayer(bounds.left, bounds.top,
+ bounds.right, bounds.bottom, getMaskingPaint(DST_ATOP), 0);
+ }
+
+ Drawable mask = null;
+ final ChildDrawable[] array = mLayerState.mChildren;
+ final int N = mLayerState.mNum;
+ for (int i = 0; i < N; i++) {
+ if (array[i].mId != R.id.mask) {
+ array[i].mDrawable.draw(canvas);
+ } else {
+ mask = array[i].mDrawable;
}
}
// If we have ripples, mask them.
- if (mask != null && hasRipples) {
+ if (mask != null && drewRipples) {
+ // TODO: This will also mask the lower layer, which is bad.
canvas.saveLayer(bounds.left, bounds.top, bounds.right,
bounds.bottom, getMaskingPaint(DST_IN), 0);
mask.draw(canvas);
}
- // Composite the layers if needed:
- // 1. Mask DST_IN
- // 2. Ripples SRC_ATOP
- // 3. Lower n/a
- if (rippleRestoreCount > 0) {
+ // Composite the layers if needed.
+ if (rippleRestoreCount >= 0) {
canvas.restoreToCount(rippleRestoreCount);
}
}
@@ -503,9 +406,6 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
}
return mRipplePaint;
}
-
- private static final PorterDuffXfermode SRC_ATOP = new PorterDuffXfermode(Mode.SRC_ATOP);
- private static final PorterDuffXfermode DST_IN = new PorterDuffXfermode(Mode.DST_IN);
private Paint getMaskingPaint(PorterDuffXfermode mode) {
if (mMaskingPaint == null) {
@@ -521,15 +421,12 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
final Rect drawingBounds = mDrawingBounds;
dirtyBounds.set(drawingBounds);
drawingBounds.setEmpty();
-
final Rect rippleBounds = mTempRect;
- final ArrayList<Ripple> activeRipples = mActiveRipples;
- if (activeRipples != null) {
- final int N = activeRipples.size();
- for (int i = 0; i < N; i++) {
- activeRipples.get(i).getBounds(rippleBounds);
- drawingBounds.union(rippleBounds);
- }
+ final Ripple[] activeRipples = mActiveRipples;
+ final int N = mActiveRipplesCount;
+ for (int i = 0; i < N; i++) {
+ activeRipples[i].getBounds(rippleBounds);
+ drawingBounds.union(rippleBounds);
}
dirtyBounds.union(drawingBounds);
@@ -539,34 +436,30 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
@Override
public ConstantState getConstantState() {
- // TODO: Can we just rely on super.getConstantState()?
return mState;
}
- static class TouchFeedbackState extends WrapperState {
- int[] mThemeAttrs;
- ConstantState mMaskState;
+ static class TouchFeedbackState extends LayerState {
+ int[] mTouchThemeAttrs;
ColorStateList mTint;
Mode mTintMode;
boolean mPinned;
- boolean mProjected;
- public TouchFeedbackState(TouchFeedbackState orig) {
- super(orig);
+ public TouchFeedbackState(
+ TouchFeedbackState orig, TouchFeedbackDrawable owner, Resources res) {
+ super(orig, owner, res);
if (orig != null) {
- mThemeAttrs = orig.mThemeAttrs;
+ mTouchThemeAttrs = orig.mTouchThemeAttrs;
mTint = orig.mTint;
mTintMode = orig.mTintMode;
- mMaskState = orig.mMaskState;
mPinned = orig.mPinned;
- mProjected = orig.mProjected;
}
}
@Override
public boolean canApplyTheme() {
- return mThemeAttrs != null;
+ return mTouchThemeAttrs != null || super.canApplyTheme();
}
@Override
@@ -586,13 +479,33 @@ public class TouchFeedbackDrawable extends DrawableWrapper {
}
private TouchFeedbackDrawable(TouchFeedbackState state, Resources res, Theme theme) {
- if (theme != null && state.canApplyTheme()) {
- mState = new TouchFeedbackState(state);
- applyTheme(theme);
+ boolean needsTheme = false;
+
+ final TouchFeedbackState ns;
+ if (theme != null && state != null && state.canApplyTheme()) {
+ ns = new TouchFeedbackState(state, this, res);
+ needsTheme = true;
+ } else if (state == null) {
+ ns = new TouchFeedbackState(null, this, res);
} else {
- mState = state;
+ ns = state;
+ }
+
+ if (res != null) {
+ mDensity = res.getDisplayMetrics().density;
+ }
+
+ mState = ns;
+ mLayerState = ns;
+
+ if (ns.mNum > 0) {
+ ensurePadding();
+ }
+
+ if (needsTheme) {
+ applyTheme(theme);
}
- setConstantState(state, res);
+ setPaddingMode(PADDING_MODE_STACK);
}
}
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
new file mode 100644
index 0000000..f3dd2fc
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -0,0 +1,1955 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.graphics.drawable;
+
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.Resources.Theme;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.location.Address;
+import android.net.ParseException;
+import android.sax.StartElementListener;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+
+import com.android.internal.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+/**
+ * This lets you create a drawable based on an XML vector graphic
+ * It can be defined in an XML file with the <code>&lt;vector></code> element.
+ * <p/>
+ * The vector drawable has 6 elements:
+ * <p/>
+ * <dl>
+ * <dt><code>&lt;vector></code></dt><dd>
+ * The attribute <code>android:trigger</code> which defines a state change that
+ * will drive the animation </dd>
+ * <dt><code>&lt;size></code></dt>
+ * <dd>Used to defined the intrinsic Width Height size of the drawable using
+ * <code>android:width</code> and <code>android:height</code> </dd>
+ * <dt><code>&lt;viewport></code></dt>
+ * <dd>Used to defined the size of the virtual canvas the paths are drawn on.
+ * The size is defined using the attributes <code>android:viewportHeight
+ * </code> <code>android:viewportWidth</code></dd>
+ * <dt><code>&lt;group></code></dt>
+ * <dd>Defines a "key frame" in the animation if there is only one group the
+ * drawable is static 2D image that has no animation.</dd>
+ * <dt><code>&lt;path></code></dt>
+ * <dd>Defines paths to be drawn. The path elements must be within a group
+ * <dl>
+ * <dt><code>android:name</code>
+ * <dd>Defines the name of the path.</dd></dt>
+ * <dt><code>android:pathData</code>
+ * <dd>Defines path string.</dd></dt>
+ * <dt><code>android:fill</code>
+ * <dd>Defines the color to fill the path (none if not present).</dd></dt>
+ * <dt><code>android:stroke</code>
+ * <dd>Defines the color to draw the path outline (none if not present).</dd></dt>
+ * <dt><code>android:strokeWidth</code>
+ * <dd>The width a path stroke</dd></dt>
+ * <dt><code>android:strokeOpacity</code>
+ * <dd>The opacity of a path stroke</dd></dt>
+ * <dt><code>android:rotation</code>
+ * <dd>The amount to rotation the path stroke.</dd></dt>
+ * <dt><code>android:pivotX</code>
+ * <dd>The X coordinate of the center of rotation of a path</dd></dt>
+ * <dt><code>android:pivotY</code>
+ * <dd>The Y coordinate of the center of rotation of a path</dd></dt>
+ * <dt><code>android:fillOpacity</code>
+ * <dd>The opacity to fill the path with</dd></dt>
+ * <dt><code>android:trimPathStart</code>
+ * <dd>The fraction of the path to trim from the start from 0 to 1</dd></dt>
+ * <dt><code>android:trimPathEnd</code>
+ * <dd>The fraction of the path to trim from the end from 0 to 1</dd></dt>
+ * <dt><code>android:trimPathOffset</code>
+ * <dd>Shift trim region (allows showed region to include the start and end) from 0 to 1</dd></dt>
+ * <dt><code>android:clipToPath</code>
+ * <dd>Path will set the clip path</dd></dt>
+ * <dt><code>android:strokeLineCap</code>
+ * <dd>Sets the linecap for a stroked path: butt, round, square</dd></dt>
+ * <dt><code>android:strokeLineJoin</code>
+ * <dd>Sets the lineJoin for a stroked path: miter,round,bevel</dd></dt>
+ * <dt><code>android:strokeMiterLimit</code>
+ * <dd>Sets the Miter limit for a stroked path</dd></dt>
+ * <dt><code>android:state_pressed</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_focused</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_selected</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_window_focused</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_enabled</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_activated</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_accelerated</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_hovered</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_checked</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * <dt><code>android:state_checkable</code>
+ * <dd>Sets a condition to be met to draw path</dd></dt>
+ * </dl>
+ * </dd>
+ * <dt><code>&lt;animation></code></dt>
+ * <dd>Used to customize the transition between two paths
+ * <dl>
+ * <dt><code>android:sequence</code>
+ * <dd>Configures this animation sequence between the named paths.</dd></dt>
+ * <dt><code>android:limitTo</code>
+ * <dd>Limits an animation to only interpolate the selected variable
+ * unlimited, path, rotation, trimPathStart, trimPathEnd, trimPathOffset</dd></dt>
+ * <dt><code>android:repeatCount</code>
+ * <dd>Number of times to loop this aspect of the animation</dd></dt>
+ * <dt><code>android:durations</code>
+ * <dd>The duration of each step in the animation in milliseconds
+ * Must contain the number of named paths - 1</dd></dt>
+ * <dt><code>android:startDelay</code>
+ * <dd></dd></dt>
+ * <dt><code>android:repeatStyle</code>
+ * <dd>when repeating how does it repeat back and forth or a to b: forward, inAndOut</dd></dt>
+ * <dt><code>android:animate</code>
+ * <dd>linear, accelerate, decelerate, easing</dd></dt>
+ * </dl>
+ * </dd>
+ */
+public class VectorDrawable extends Drawable {
+ private static final String LOGTAG = "VectorDrawable";
+ public static final int INFINITE = ValueAnimator.INFINITE;
+ private static final String SHAPE_SIZE = "size";
+ private static final String SHAPE_VIEWPORT = "viewport";
+ private static final String SHAPE_GROUP = "group";
+ private static final String SHAPE_PATH = "path";
+ private static final String SHAPE_TRANSITION = "transition";
+ private static final String SHAPE_ANIMATION = "animation";
+ private static final String SHAPE_VECTOR = "vector";
+
+ private static final int LINECAP_BUTT = 0;
+ private static final int LINECAP_ROUND = 1;
+ private static final int LINECAP_SQUARE = 2;
+ private static final int LINEJOIN_MITER = 0;
+ private static final int LINEJOIN_ROUND = 1;
+ private static final int LINEJOIN_BEVEL = 2;
+ private static final int DEFAULT_DURATION = 1000;
+ private static final long DEFAULT_INFINITE_DURATION = 60 * 60 * 1000;
+ private VectorDrawableState mVectorState;
+ private int mAlpha = 0xFF;
+
+ public VectorDrawable() {
+ mVectorState = new VectorDrawableState();
+ mVectorState.mBasicAnimator = ObjectAnimator.ofFloat(this, "AnimationFraction", 0, 1);
+ setDuration(DEFAULT_DURATION);
+ }
+
+ private VectorDrawable(VectorDrawableState state) {
+ mVectorState = new VectorDrawableState(state);
+ mVectorState.mBasicAnimator = ObjectAnimator.ofFloat(this, "AnimationFraction", 0, 1);
+ long duration = mVectorState.mVAnimatedPath.getTotalAnimationDuration();
+ if (duration == -1) { // if it set to infinite set to 1 hour
+ duration = DEFAULT_INFINITE_DURATION; // TODO define correct approach for infinite
+ mVectorState.mBasicAnimator.setFloatValues(0, duration / 1000);
+ mVectorState.mBasicAnimator.setInterpolator(new LinearInterpolator());
+ }
+ setDuration(duration);
+ }
+
+ final static class VectorDrawableState extends ConstantState {
+ int mChangingConfigurations;
+ ValueAnimator mBasicAnimator;
+ VAnimatedPath mVAnimatedPath = new VAnimatedPath();
+ Rect mPadding;
+ int mIntrinsicHeight;
+ int mIntrinsicWidth;
+
+ public VectorDrawableState(){
+ }
+
+ public VectorDrawableState(VectorDrawableState copy){
+ mChangingConfigurations = copy.mChangingConfigurations;
+ mVAnimatedPath = new VAnimatedPath(copy.mVAnimatedPath);
+ mPadding = new Rect(copy.mPadding);
+ mIntrinsicHeight = copy.mIntrinsicHeight;
+ mIntrinsicWidth = copy.mIntrinsicWidth;
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return new VectorDrawable(this);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see android.graphics.drawable.Drawable#getConstantState()
+ */
+ @Override
+ public ConstantState getConstantState() {
+ return mVectorState;
+ }
+
+ /**
+ * start the animation
+ */
+ public void start() {
+ mVectorState.mBasicAnimator.start();
+ }
+
+ /**
+ * Stop the animation.
+ */
+ public void stop() {
+ mVectorState.mBasicAnimator.end();
+ }
+
+ /**
+ * Get the current time point in the animation
+ *
+ * @return the current point on the animation
+ */
+ public float geAnimationFraction() {
+ return mVectorState.mVAnimatedPath.getValue();
+ }
+
+ /**
+ * set the time point in the animation
+ *
+ * @param value the point along the animation typically between 0 and 1
+ */
+ public void setAnimationFraction(float value) {
+ mVectorState.mVAnimatedPath.setAnimationFraction(value);
+ invalidateSelf();
+ }
+
+ /**
+ * set the amount of time the animation will take
+ *
+ * @param duration amount of time in milliseconds
+ */
+ public void setDuration(long duration) {
+ mVectorState.mBasicAnimator.setDuration(duration);
+ }
+
+ /**
+ * Defines what this animation should do when it reaches the end. This setting is applied only
+ * when the repeat count is either greater than 0 or {@link #INFINITE}.
+ */
+ public void setRepeatMode(int mode) {
+ mVectorState.mBasicAnimator.setRepeatMode(mode);
+ }
+
+ /**
+ * Sets animation to repeat
+ *
+ * @param repeat True if this drawable repeats its animation
+ */
+ public void setRepeatCount(int repeat) {
+ mVectorState.mBasicAnimator.setRepeatCount(repeat);
+ }
+
+ /**
+ * @return True if this drawable repeats its animation
+ */
+ public int getRepeatCount() {
+ return mVectorState.mBasicAnimator.getRepeatCount();
+ }
+
+ @Override
+ public boolean isStateful() {
+ return true;
+ }
+
+ @Override
+ protected boolean onStateChange(int[] state) {
+ mVectorState.mVAnimatedPath.setState(state);
+ int direction = mVectorState.mVAnimatedPath.getTrigger(state);
+ if (direction>0) {
+ animateForward();
+ } else if (direction<0) {
+ animateBackward();
+ }
+ super.onStateChange(state);
+ invalidateSelf();
+ return true;
+ }
+
+ private void animateForward(){
+ if (!mVectorState.mBasicAnimator.isStarted()) {
+ mVectorState.mBasicAnimator.setFloatValues(0,1);
+ start();
+ }
+ }
+
+ private void animateBackward(){
+ if (!mVectorState.mBasicAnimator.isStarted()) {
+ mVectorState.mBasicAnimator.setFloatValues(.99f,0);
+ start();
+ }
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ mVectorState.mVAnimatedPath.draw(canvas);
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ // TODO correct handling of transparent
+ if (mAlpha != alpha) {
+ mAlpha = alpha;
+ invalidateSelf();
+ }
+ }
+
+ /**
+ * Not implemented yet
+ * @hide
+ */
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ // TODO: support color filter
+ }
+
+ /**
+ * Returns a {@link android.graphics.PixelFormat graphics.PixelFormat}
+ * value of TRANSLUCENT.
+ */
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ /**
+ * Sets padding for this shape, defined by a Rect object. Define the padding in the Rect object
+ * as: left, top, right, bottom.
+ */
+ public void setPadding(Rect padding) {
+ setPadding(padding.left, padding.top, padding.right, padding.bottom);
+ }
+
+ /**
+ * Sets padding for the shape.
+ *
+ * @param left padding for the left side (in pixels)
+ * @param top padding for the top (in pixels)
+ * @param right padding for the right side (in pixels)
+ * @param bottom padding for the bottom (in pixels)
+ */
+ public void setPadding(int left, int top, int right, int bottom) {
+ if ((left | top | right | bottom) == 0) {
+ mVectorState.mPadding = null;
+ } else {
+ if (mVectorState.mPadding == null) {
+ mVectorState.mPadding = new Rect();
+ }
+ mVectorState.mPadding.set(left, top, right, bottom);
+ }
+ invalidateSelf();
+ }
+
+ /**
+ * Sets the intrinsic (default) width for this shape.
+ *
+ * @param width the intrinsic width (in pixels)
+ */
+ public void setIntrinsicWidth(int width) {
+ if (mVectorState.mIntrinsicWidth != width) {
+ mVectorState.mIntrinsicWidth = width;
+ invalidateSelf();
+ }
+ }
+
+ /**
+ * Sets the intrinsic (default) height for this shape.
+ *
+ * @param height the intrinsic height (in pixels)
+ */
+ public void setIntrinsicHeight(int height) {
+ if (mVectorState.mIntrinsicHeight != height) {
+ mVectorState.mIntrinsicHeight = height;
+ invalidateSelf();
+ }
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mVectorState.mIntrinsicWidth;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mVectorState.mIntrinsicHeight;
+ }
+
+ @Override
+ public boolean getPadding(Rect padding) {
+ if (mVectorState.mPadding != null) {
+ padding.set(mVectorState.mPadding);
+ return true;
+ } else {
+ return super.getPadding(padding);
+ }
+ }
+
+ /** @hide */
+ public static VectorDrawable create(Resources resources, int rid) {
+ try {
+ VectorDrawable drawable = new VectorDrawable();
+ XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ XmlPullParser xpp = resources.getXml(rid);
+ AttributeSet attrs = Xml.asAttributeSet(xpp);
+ drawable.inflate(resources, xpp, attrs);
+ drawable.setAnimationFraction(0);
+ return drawable;
+ } catch (XmlPullParserException e) {
+ Log.e(LOGTAG, "parser error", e);
+ } catch (IOException e) {
+ Log.e(LOGTAG, "parser error", e);
+ }
+ return null;
+ }
+
+ @Override
+ public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
+ throws XmlPullParserException, IOException {
+ setAnimatedPath(inflateInternal(res, parser, attrs));
+ }
+
+ private VAnimatedPath inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+ boolean noSizeTag = true;
+ boolean noViewportTag = true;
+ boolean noGroupTag = true;
+ boolean noPathTag = true;
+ final VAnimatedPath animatedPath = new VAnimatedPath();
+ VectorDrawable.VGroup currentGroup = null;
+
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ String tagName = parser.getName();
+ if (SHAPE_PATH.equals(tagName)) {
+ VectorDrawable.VPath p = new VPath(res, attrs);
+ currentGroup.add(p);
+ noPathTag = false;
+ } else if (SHAPE_ANIMATION.equals(tagName)) {
+ VectorDrawable.VAnimation anim =
+ new VAnimation(res, attrs, animatedPath.mGroupList);
+ animatedPath.addAnimation(anim);
+ } else if (SHAPE_SIZE.equals(tagName)) {
+ animatedPath.parseSize(res, attrs);
+ noSizeTag = false;
+ } else if (SHAPE_VIEWPORT.equals(tagName)) {
+ animatedPath.parseViewport(res, attrs);
+ noViewportTag = false;
+ } else if (SHAPE_GROUP.equals(tagName)) {
+ currentGroup = new VectorDrawable.VGroup();
+ animatedPath.mGroupList.add(currentGroup);
+ noGroupTag = false;
+ } else if (SHAPE_VECTOR.equals(tagName)) {
+ TypedArray a = res.obtainAttributes(attrs, R.styleable.VectorDrawable);
+ animatedPath.setTrigger(a.getInteger(R.styleable.VectorDrawable_trigger, 0));
+ a.recycle();
+ }
+ }
+ eventType = parser.next();
+ }
+ if (noSizeTag || noViewportTag || noGroupTag || noPathTag) {
+ StringBuffer tag = new StringBuffer();
+ if (noSizeTag) {
+ tag.append("size");
+ }
+ if (noViewportTag){
+ if (tag.length()>0) {
+ tag.append(" & ");
+ }
+ tag.append("size");
+ }
+ if (noGroupTag){
+ if (tag.length()>0) {
+ tag.append(" & ");
+ }
+ tag.append("group");
+ }
+ if (noPathTag){
+ if (tag.length()>0) {
+ tag.append(" or ");
+ }
+ tag.append("path");
+ }
+ throw new XmlPullParserException("no "+tag+" defined");
+ }
+ // post parse cleanup
+ animatedPath.parseFinish();
+ return animatedPath;
+ }
+
+ private void setAnimatedPath(VAnimatedPath animatedPath) {
+ mVectorState.mVAnimatedPath = animatedPath;
+ setIntrinsicWidth((int) mVectorState.mVAnimatedPath.mBaseWidth);
+ setIntrinsicHeight((int) mVectorState.mVAnimatedPath.mBaseHeight);
+ long duration = mVectorState.mVAnimatedPath.getTotalAnimationDuration();
+ if (duration == -1) { // if it set to infinite set to 1 hour
+ duration = DEFAULT_INFINITE_DURATION; // TODO define correct approach for infinite
+ mVectorState.mBasicAnimator.setFloatValues(0, duration / 1000);
+ mVectorState.mBasicAnimator.setInterpolator(new LinearInterpolator());
+ }
+ setDuration(duration);
+
+ setAnimationFraction(0);
+ }
+
+ @Override
+ public boolean setVisible(boolean visible, boolean restart) {
+ boolean changed = super.setVisible(visible, restart);
+ if (visible) {
+ if (changed || restart) {
+ setAnimationFraction(0);
+ }
+ } else {
+ stop();
+ }
+ return changed;
+ }
+
+ private static class VAnimatedPath {
+ private static final String LOGTAG = "VAnimatedPath";
+
+ private ArrayList<VAnimation> mCurrentAnimList = null;
+ private VPath[] mCurrentPaths;
+ private float mAnimationValue = 0; // value goes from 0 to 1
+ private Paint mStrokePaint = null;
+ private Paint mFillPaint = null;
+ private PathMeasure mPathMeasure;
+ private Path mPath = new Path();
+ private Path mRenderPath = new Path();
+ private Matrix mMatrix = new Matrix();
+ private long mTotalDuration;
+ private int[] mCurrentState = new int[0];
+ private int mTrigger;
+ private boolean mTriggerState;
+ ArrayList<VGroup> mGroupList = new ArrayList<VGroup>();
+ float mBaseWidth = 1;
+ float mBaseHeight = 1;
+ float mViewportWidth;
+ float mViewportHeight;
+
+ public VAnimatedPath() {
+ setup();
+ }
+ public VAnimatedPath(VAnimatedPath copy) {
+ setup();
+ mCurrentAnimList = new ArrayList<VAnimation>(copy.mCurrentAnimList);
+ mGroupList = new ArrayList<VGroup>(copy.mGroupList);
+ if (copy.mCurrentPaths != null) {
+ mCurrentPaths = new VPath[copy.mCurrentPaths.length];
+ for (int i = 0; i < mCurrentPaths.length; i++) {
+ mCurrentPaths[i] = new VPath(copy.mCurrentPaths[i]);
+ }
+ }
+ mAnimationValue = copy.mAnimationValue; // time goes from 0 to 1
+
+ mBaseWidth = copy.mBaseWidth;
+ mBaseHeight = copy.mBaseHeight;
+ mViewportWidth = copy.mViewportHeight;
+ mViewportHeight = copy.mViewportHeight;
+ mTotalDuration = copy.mTotalDuration;
+ mTrigger = copy.mTrigger;
+ mCurrentState = new int[0];
+ }
+
+ public void setTrigger(int trigger){
+ int []lut = { 0,
+ R.attr.state_pressed,
+ R.attr.state_focused,
+ R.attr.state_hovered,
+ R.attr.state_selected,
+ R.attr.state_checkable,
+ R.attr.state_checked,
+ R.attr.state_activated,
+ R.attr.state_focused
+ };
+ mTrigger = lut[trigger];
+ }
+
+ private void setup(){
+ mStrokePaint = new Paint();
+ mStrokePaint.setStyle(Paint.Style.STROKE);
+ mStrokePaint.setAntiAlias(true);
+ mFillPaint = new Paint();
+ mFillPaint.setStyle(Paint.Style.FILL);
+ mFillPaint.setAntiAlias(true);
+ }
+
+ public long getTotalAnimationDuration() {
+ mTotalDuration = 0;
+ int size = mCurrentAnimList.size();
+ for (int i = 0; i < size; i++) {
+ VAnimation vAnimation = mCurrentAnimList.get(i);
+ long t = vAnimation.getTotalDuration();
+ if (t == -1) {
+ mTotalDuration = -1;
+ return -1;
+ }
+ mTotalDuration = Math.max(mTotalDuration, t);
+ }
+
+ return mTotalDuration;
+ }
+
+ public float getValue() {
+ return mAnimationValue;
+ }
+
+ /**
+ * @param value the point along the animations to show typically between 0.0f and 1.0f
+ * @return true if you need to keep repeating
+ */
+ public boolean setAnimationFraction(float value) {
+ int len = mCurrentPaths.length;
+ getTotalAnimationDuration();
+ long animationTime = (long) (value * mTotalDuration);
+
+ for (int i = 0; i < len; i++) {
+ VPath path = mCurrentPaths[i];
+ animationTime =
+ (long) ((mTotalDuration == -1) ? value * 1000 : mTotalDuration * value);
+ int size = mCurrentAnimList.size();
+ for (int j = 0; j < size; j++) {
+ VAnimation vAnimation = mCurrentAnimList.get(j);
+ if (vAnimation.doesAdjustPath(path)) {
+ mCurrentPaths[i] = vAnimation.getPathAtTime(animationTime, path);
+ }
+ }
+ }
+ this.mAnimationValue = value;
+ if (mTotalDuration == -1) {
+ return true;
+ } else {
+ return animationTime < mTotalDuration;
+ }
+ }
+
+ public void draw(Canvas canvas) {
+ int w = canvas.getWidth();
+ int h = canvas.getHeight();
+ float scale = w / mViewportWidth;
+ scale = Math.min(h / mViewportHeight, scale);
+
+ if (mCurrentPaths == null) {
+ Log.e(LOGTAG,"mCurrentPaths == null");
+ return;
+ }
+
+ for (int i = 0; i < mCurrentPaths.length; i++) {
+ if (mCurrentPaths[i] != null && mCurrentPaths[i].isVisible(mCurrentState)) {
+ drawPath(mCurrentPaths[i], canvas, w, h);
+ }
+ }
+ }
+
+ private void drawPath(VPath vPath, Canvas canvas, int w, int h) {
+ float scale = w / mViewportWidth;
+ scale = Math.min(h / mViewportHeight, scale);
+
+ vPath.toPath(mPath);
+ Path path = mPath;
+
+ if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) {
+ float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f;
+ float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f;
+
+ if (mPathMeasure == null) {
+ mPathMeasure = new PathMeasure();
+ }
+ mPathMeasure.setPath(mPath, false);
+
+ float len = mPathMeasure.getLength();
+ start = start * len;
+ end = end * len;
+ path.reset();
+ if (start > end) {
+ mPathMeasure.getSegment(start, len, path, true);
+ mPathMeasure.getSegment(0f, end, path, true);
+ } else {
+ mPathMeasure.getSegment(start, end, path, true);
+ }
+ path.rLineTo(0, 0); // fix bug in measure
+ }
+
+ mRenderPath.reset();
+ mMatrix.reset();
+
+ mMatrix.postRotate(vPath.mRotate, vPath.mPivotX, vPath.mPivotY);
+ mMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f);
+ mMatrix.postTranslate(w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f);
+
+ mRenderPath.addPath(path, mMatrix);
+
+ if (vPath.mClip) {
+ canvas.clipPath(mRenderPath, Region.Op.REPLACE);
+ }
+ if (vPath.mFillColor != 0) {
+ mFillPaint.setColor(vPath.mFillColor);
+ int alpha = 0xFF & (vPath.mFillColor >> 24);
+ mFillPaint.setAlpha(alpha);
+ canvas.drawPath(mRenderPath, mFillPaint);
+ }
+ if (vPath.mStrokeColor != 0) {
+ if (vPath.mStrokelineJoin != null) {
+ mStrokePaint.setStrokeJoin(vPath.mStrokelineJoin);
+ }
+ if (vPath.mStrokelineCap != null) {
+ mStrokePaint.setStrokeCap(vPath.mStrokelineCap);
+ }
+ mStrokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale);
+ mStrokePaint.setColor(vPath.mStrokeColor);
+ mStrokePaint.setAlpha(0xFF & (vPath.mStrokeColor >> 24));
+ mStrokePaint.setStrokeWidth(vPath.mStrokeWidth * scale);
+ canvas.drawPath(mRenderPath, mStrokePaint);
+ }
+ }
+
+ /**
+ * Ensure there is at least one animation for every path in group (linking them by names)
+ * Build the "current" path based on the first group
+ * TODO: improve memory use & performance or move to C++
+ */
+ public void parseFinish() {
+ HashMap<String, VAnimation> newAnimations = new HashMap<String, VAnimation>();
+ for (VGroup group : mGroupList) {
+ for (VPath vPath : group.getPaths()) {
+ if (!vPath.mAnimated) {
+ VAnimation ap = null;
+
+ if (!newAnimations.containsKey(vPath.getID())) {
+ newAnimations.put(vPath.getID(), ap = new VAnimation());
+ } else {
+ ap = newAnimations.get(vPath.getID());
+ }
+ ap.addPath(vPath);
+ vPath.mAnimated = true;
+ }
+ }
+ }
+ if (mCurrentAnimList == null) {
+ mCurrentAnimList = new ArrayList<VectorDrawable.VAnimation>();
+ }
+ mCurrentAnimList.addAll(newAnimations.values());
+ Collection<VPath> paths = mGroupList.get(0).getPaths();
+ mCurrentPaths = paths.toArray(new VPath[paths.size()]);
+ for (int i = 0; i < mCurrentPaths.length; i++) {
+ mCurrentPaths[i] = new VPath(mCurrentPaths[i]);
+ }
+ }
+
+ public void setState(int[] state) {
+ mCurrentState = Arrays.copyOf(state, state.length);
+ }
+
+ int getTrigger(int []state){
+ if (mTrigger == 0) return 0;
+ for (int i = 0; i < state.length; i++) {
+ if (state[i] == mTrigger){
+ if (mTriggerState)
+ return 0;
+ mTriggerState = true;
+ return 1;
+ }
+ }
+ if (mTriggerState) {
+ mTriggerState = false;
+ return -1;
+ }
+ return 0;
+ }
+
+ public void addAnimation(VAnimation anim) {
+ if (mCurrentAnimList == null) {
+ mCurrentAnimList = new ArrayList<VectorDrawable.VAnimation>();
+ }
+ mCurrentAnimList.add(anim);
+ }
+
+ private void parseViewport(Resources r, AttributeSet attrs)
+ throws XmlPullParserException {
+ TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport);
+ mViewportWidth = a.getFloat(R.styleable.VectorDrawableViewport_viewportWidth, 0);
+ mViewportHeight = a.getFloat(R.styleable.VectorDrawableViewport_viewportHeight, 0);
+ if (mViewportWidth == 0 || mViewportHeight == 0) {
+ throw new XmlPullParserException(a.getPositionDescription()+
+ "<viewport> tag requires viewportWidth & viewportHeight to be set");
+ }
+ a.recycle();
+ }
+
+ private void parseSize(Resources r, AttributeSet attrs)
+ throws XmlPullParserException {
+ TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize);
+ mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, 0);
+ mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, 0);
+ if (mBaseWidth == 0 || mBaseHeight == 0) {
+ throw new XmlPullParserException(a.getPositionDescription()+
+ "<size> tag requires width & height to be set");
+ }
+ a.recycle();
+ }
+ }
+
+ private static class VAnimation {
+ private static final String LOGTAG = "VAnimation";
+ private VPath[] mPaths = new VPath[0];
+
+ public enum Style {
+ INTERPOLATE, CROSSFADE, WIPE
+ }
+ Interpolator mAnimInterpolator = new AccelerateDecelerateInterpolator();
+ private Style mStyle;
+ private int mLimitProperty = 0;
+ private long[] mDuration = {DEFAULT_DURATION};
+ private long mStartOffset;
+ private long mRepeat = 1;
+ private HashSet<String>mSeqMap = new HashSet<String>();
+ private long mWipeDirection;
+ private int mMode = 0; // forward = 0 inAndOut = 1;
+ private int mInterpolatorType;
+ private String mId;
+ private final static int DIRECTION_FORWARD = 0;
+ private final static int DIRECTION_IN_AND_OUT = 1;
+
+ public VAnimation() {
+ }
+
+ public boolean doesAdjustPath(VPath path) {
+ return mSeqMap.contains(path.getID());
+ }
+
+ public VAnimation(Resources r, AttributeSet attrs, ArrayList<VGroup> groups)
+ throws XmlPullParserException {
+ String value;
+ String[] sp;
+ int name;
+
+ TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableAnimation);
+
+ value = a.getString(R.styleable.VectorDrawableAnimation_sequence);
+ if (value != null) {
+ sp = value.split(",");
+ VectorDrawable.VPath[] paths = new VectorDrawable.VPath[sp.length];
+
+ for (int j = 0; j < sp.length; j++) {
+ mSeqMap.add(sp[j].trim());
+ VectorDrawable.VPath path = groups.get(j).get(sp[j]);
+ path.mAnimated = true;
+ paths[j] = path;
+ }
+ setPaths(paths);
+ }
+
+ setLimitProperty(a.getInt(R.styleable.VectorDrawableAnimation_limitTo, 0));
+
+ name = R.styleable.VectorDrawableAnimation_durations;
+ value = a.getString(name);
+ if (value != null) {
+ long totalDuration = 0;
+ sp = value.split(",");
+ long[] dur = new long[sp.length];
+ for (int j = 0; j < dur.length; j++) {
+ dur[j] = Long.parseLong(sp[j]);
+ totalDuration += dur[j];
+ }
+ if (totalDuration == 0){
+ throw new XmlPullParserException(a.getPositionDescription()+
+ "total duration must not be zero");
+ }
+ setDuration(dur);
+ }
+
+ setRepeat(a.getInt(R.styleable.VectorDrawableAnimation_repeatCount, 1));
+
+ setStartOffset(a.getInt(R.styleable.VectorDrawableAnimation_startDelay, 0));
+
+ setMode(a.getInt(R.styleable.VectorDrawableAnimation_repeatStyle, 0));
+
+ fixMissingParameters();
+ a.recycle();
+ }
+
+ public String getId() {
+ if (mId == null) {
+ mId = mPaths[0].getID();
+ for (int i = 1; i < mPaths.length; i++) {
+ mId += mPaths[i].getID();
+ }
+ }
+ return mId;
+ }
+
+ public String getPathName() {
+ return mPaths[0].getID();
+ }
+
+ public Style getStyle() {
+ return mStyle;
+ }
+
+ public void setStyle(Style style) {
+ this.mStyle = style;
+ }
+
+ public int getLimitProperty() {
+ return mLimitProperty;
+ }
+
+ public void setLimitProperty(int limitProperty) {
+ this.mLimitProperty = limitProperty;
+ }
+
+ public long[] getDuration() {
+ return mDuration;
+ }
+
+ public void setDuration(long[] duration) {
+ this.mDuration = duration;
+ }
+
+ public long getRepeat() {
+ return mRepeat;
+ }
+
+ public void setRepeat(long repeat) {
+ this.mRepeat = repeat;
+ }
+
+ public long getStartOffset() {
+ return mStartOffset;
+ }
+
+ public void setStartOffset(long startOffset) {
+ this.mStartOffset = startOffset;
+ }
+
+ public long getWipeDirection() {
+ return mWipeDirection;
+ }
+
+ public void setWipeDirection(long wipeDirection) {
+ this.mWipeDirection = wipeDirection;
+ }
+
+ public int getMode() {
+ return mMode;
+ }
+
+ public void setMode(int mode) {
+ this.mMode = mode;
+ }
+
+ public int getInterpolator() {
+ return mInterpolatorType;
+ }
+
+ public void setInterpolator(int interpolator) {
+ this.mInterpolatorType = interpolator;
+ }
+
+ /**
+ * compute the total time in milliseconds
+ *
+ * @return the total time in milliseconds the animation will take
+ */
+ public long getTotalDuration() {
+ long total = mStartOffset;
+ if (getRepeat() == -1) {
+ return -1;
+ }
+ for (int i = 0; i < mDuration.length; i++) {
+ if (mRepeat > 1) {
+ total += mDuration[i] * mRepeat;
+ } else {
+ total += mDuration[i];
+ }
+ }
+ return total;
+ }
+
+ public void setPaths(VPath[] paths) {
+ this.mPaths = paths;
+ }
+
+ public void addPath(VPath path) {
+ mPaths = Arrays.copyOf(mPaths, mPaths.length + 1);
+ mPaths[mPaths.length - 1] = path;
+ }
+
+ public boolean containsPath(String pathid) {
+ for (int i = 0; i < mPaths.length; i++) {
+ if (mPaths[i].getID().equals(pathid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void interpolate(VPath p1, VPath p2, float time, VPath dest) {
+ dest.interpolate(time, p1, p2, dest, mLimitProperty);
+ }
+
+ public VPath getPathAtTime(long milliseconds, VPath dest) {
+ if (mPaths.length == 1) {
+ dest.copyFrom(mPaths[0]);
+ return dest;
+ }
+ long point = milliseconds - mStartOffset;
+ if (point < 0) {
+ point = 0;
+ }
+ float time = 0;
+ long sum = mDuration[0];
+ for (int i = 1; i < mDuration.length; i++) {
+ sum += mDuration[i];
+ }
+
+ if (mRepeat > 1) {
+ time = point / (float) (sum * mRepeat);
+ time = mAnimInterpolator.getInterpolation(time);
+
+ if (mMode == DIRECTION_IN_AND_OUT) {
+ point = ((long) (time * sum * 2 * mRepeat)) % (sum * 2);
+ if (point > sum) {
+ point = sum * 2 - point;
+ }
+ } else {
+ point = ((long) (time * sum * mRepeat)) % sum;
+ }
+ } else if (mRepeat == 1) {
+ time = point / (float) (sum * mRepeat);
+ time = mAnimInterpolator.getInterpolation(time);
+ if (mMode == DIRECTION_IN_AND_OUT) {
+ point = ((long) (time * sum * 2 * mRepeat));
+ if (point > sum) {
+ point = sum * 2 - point;
+ }
+ } else {
+ point = Math.min(((long) (time * sum * mRepeat)), sum);
+ }
+
+ } else { // repeat = -1
+ if (mMode == DIRECTION_IN_AND_OUT) {
+ point = point % (sum * 2);
+ if (point > sum) {
+ point = sum * 2 - point;
+ }
+ time = point / (float) sum;
+ } else {
+ point = point % sum;
+ time = point / (float) sum;
+ }
+ }
+
+ int transition = 0;
+ while (point > mDuration[transition]) {
+ point -= mDuration[transition++];
+ }
+ if (mPaths.length > (transition + 1)) {
+ if (mPaths[transition].getID() != dest.getID()) {
+ dest.copyFrom(mPaths[transition]);
+ }
+ interpolate(mPaths[transition], mPaths[transition + 1],
+ point / (float) mDuration[transition], dest);
+ } else {
+ interpolate(mPaths[transition], mPaths[transition], 0, dest);
+ }
+ return dest;
+ }
+
+ void fixMissingParameters() {
+ // fix missing points
+ float rotation = Float.NaN;
+ float rotationY = Float.NaN;
+ float rotationX = Float.NaN;
+ for (int i = 0; i < mPaths.length; i++) {
+ if (mPaths[i].mPivotX > 0) {
+ rotationX = mPaths[i].mPivotX;
+ }
+ if (mPaths[i].mPivotY > 0) {
+ rotationY = mPaths[i].mPivotY;
+ }
+ if (mPaths[i].mRotate > 0) {
+ rotation = mPaths[i].mRotate;
+ }
+ }
+ if (rotation > 0) {
+ for (int i = 0; i < mPaths.length; i++) {
+ if (mPaths[i].mPivotX == 0) {
+ mPaths[i].mPivotX = rotationX;
+ }
+ if (mPaths[i].mPivotY == 0) {
+ mPaths[i].mPivotY = rotationY;
+ }
+ }
+ }
+ }
+ }
+
+ private static class VGroup {
+ private HashMap<String, VPath> mVGPathMap = new HashMap<String, VPath>();
+ private ArrayList<VPath> mVGList = new ArrayList<VPath>();
+
+ public void add(VPath path) {
+ String id = path.getID();
+ mVGPathMap.put(id, path);
+ mVGList.add(path);
+ }
+
+ public VPath get(String name) {
+ return mVGPathMap.get(name);
+ }
+
+ /**
+ * Must return in order of adding
+ * @return ordered list of paths
+ */
+ public Collection<VPath> getPaths() {
+ return mVGList;
+ }
+
+ public int size() {
+ return mVGPathMap.size();
+ }
+ }
+
+ private static class VPath {
+ private static final int LIMIT_ALL = 0;
+ private static final int LIMIT_PATH = 1;
+ private static final int LIMIT_ROTATE = 2;
+ private static final int LIMIT_TRIM_PATH_START = 3;
+ private static final int LIMIT_TRIM_PATH_OFFSET = 5;
+ private static final int LIMIT_TRIM_PATH_END = 4;
+ private static final int STATE_UNDEFINED=0;
+ private static final int STATE_TRUE=1;
+ private static final int STATE_FALSE=2;
+ private static final int MAX_STATES = 10;
+ private VNode[] mNode = null;
+ private String mId;
+ int mStrokeColor = 0;
+ float mStrokeWidth = 0;
+ float mStrokeOpacity = Float.NaN;
+ int mFillColor = 0;
+ int mFillRule;
+ float mFillOpacity = Float.NaN;
+ float mRotate = 0;
+ float mPivotX = 0;
+ float mPivotY = 0;
+ float mTrimPathStart = 0;
+ float mTrimPathEnd = 1;
+ float mTrimPathOffset = 0;
+ boolean mAnimated = false;
+ boolean mClip = false;
+ public Paint.Cap mStrokelineCap = null;
+ public Paint.Join mStrokelineJoin = null;
+ float mStrokeMiterlimit = 4;
+ private int[] mCheckState = new int[MAX_STATES];
+ private boolean[] mCheckValue = new boolean[MAX_STATES];
+ private int mNumberOfStates = 0;
+ private int mNumberOfTrue = 0;
+
+ public void addStateFilter(int state, boolean condition) {
+ int k = 0;
+ while (k < mNumberOfStates) {
+ if (mCheckState[mNumberOfStates] == state)
+ break;
+ k++;
+ }
+ mCheckState[k] = state;
+ mCheckValue[k] = condition;
+ if (k==mNumberOfStates){
+ mNumberOfStates++;
+ }
+ if (condition) {
+ mNumberOfTrue++;
+ }
+ }
+
+ int getState(int state){
+ for (int i = 0; i < mNumberOfStates; i++) {
+ if (mCheckState[mNumberOfStates] == state){
+ return (mCheckValue[i])?STATE_TRUE:STATE_FALSE;
+ }
+ }
+ return STATE_UNDEFINED;
+ }
+ /**
+ * @return the name of the path
+ */
+ public String getName() {
+ return mId;
+ }
+
+ public void toPath(Path path) {
+ path.reset();
+ if (mNode != null) {
+ VNode.createPath(mNode, path);
+ }
+ }
+
+ public VPath() {
+ mId = this.toString(); // to ensure paths have unique names
+ }
+
+ public VPath(VPath p) {
+ copyFrom(p);
+ }
+
+ public String getID(){
+ return mId;
+ }
+
+ public VPath(Resources r, AttributeSet attrs) {
+ TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawablePath);
+ mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, false);
+ mId = a.getString(R.styleable.VectorDrawablePath_name);
+ mNode = parsePath(a.getString(R.styleable.VectorDrawablePath_pathData));
+ mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, 0);
+ mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, Float.NaN);
+
+ if (!Float.isNaN(mFillOpacity)) {
+ mFillColor &= 0x00FFFFFF;
+ mFillColor |= ((int) (0xFF * mFillOpacity)) << 24;
+ }
+ mRotate = a.getFloat(R.styleable.VectorDrawablePath_rotation, 0);
+ mPivotX = a.getFloat(R.styleable.VectorDrawablePath_pivotX, 0);
+ mPivotY = a.getFloat(R.styleable.VectorDrawablePath_pivotY, 0);
+ int lineCap = a.getInt(R.styleable.VectorDrawablePath_strokeLineCap, 0);
+ switch (lineCap) {
+ case LINECAP_BUTT:
+ mStrokelineCap = Paint.Cap.BUTT;
+ break;
+ case LINECAP_ROUND:
+ mStrokelineCap = Paint.Cap.ROUND;
+ break;
+ case LINECAP_SQUARE:
+ mStrokelineCap = Paint.Cap.SQUARE;
+ break;
+ }
+ int lineJoin = a.getInt(R.styleable.VectorDrawablePath_strokeLineJoin, 0);
+ switch (lineJoin) {
+ case LINEJOIN_MITER:
+ mStrokelineJoin = Paint.Join.MITER;
+ break;
+ case LINEJOIN_ROUND:
+ mStrokelineJoin = Paint.Join.ROUND;
+ break;
+ case LINEJOIN_BEVEL:
+ mStrokelineJoin = Paint.Join.BEVEL;
+ break;
+ }
+ mStrokeMiterlimit = a.getFloat(R.styleable.VectorDrawablePath_strokeMiterLimit,
+ mStrokeMiterlimit);
+ mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor);
+ mStrokeOpacity = a.getFloat(R.styleable.VectorDrawablePath_strokeOpacity, Float.NaN);
+ if (!Float.isNaN(mStrokeOpacity)) {
+ mStrokeColor &= 0x00FFFFFF;
+ mStrokeColor |= ((int) (0xFF * mStrokeOpacity)) << 24;
+ }
+ mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, 0);
+ mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, 1);
+ mTrimPathOffset = a.getFloat(R.styleable.VectorDrawablePath_trimPathOffset, 0);
+ mTrimPathStart = a.getFloat(R.styleable.VectorDrawablePath_trimPathStart, 0);
+ int[] states = {R.styleable.VectorDrawablePath_state_activated,
+ R.styleable.VectorDrawablePath_state_checkable,
+ R.styleable.VectorDrawablePath_state_checked,
+ R.styleable.VectorDrawablePath_state_enabled,
+ R.styleable.VectorDrawablePath_state_focused,
+ R.styleable.VectorDrawablePath_state_hovered,
+ R.styleable.VectorDrawablePath_state_pressed,
+ R.styleable.VectorDrawablePath_state_selected,
+ R.styleable.VectorDrawablePath_state_window_focused};
+ for (int state : states) {
+ if (a.hasValue(state)) {
+ addStateFilter(state, a.getBoolean(state, false));
+ }
+ }
+ a.recycle();
+ }
+
+ private static int nextStart(String s, int end) {
+ char c;
+
+ while (end < s.length()) {
+ c = s.charAt(end);
+ if (((c - 'A') * (c - 'Z') <= 0) || (((c - 'a') * (c - 'z') <= 0))) {
+ return end;
+ }
+ end++;
+ }
+ return end;
+ }
+
+ private void addNode(ArrayList<VectorDrawable.VNode> list, char cmd, float[] val) {
+ list.add(new VectorDrawable.VNode(cmd, val));
+ }
+
+ /**
+ * parse the floats in the string
+ * this is an optimized version of
+ * parseFloat(s.split(",|\\s"));
+ *
+ * @param s the string containing a command and list of floats
+ * @return array of floats
+ */
+ private static float[] getFloats(String s) {
+ if (s.charAt(0) == 'z' | s.charAt(0) == 'Z') {
+ return new float[0];
+ }
+ try {
+ float[] tmp = new float[s.length()];
+ int count = 0;
+ int pos = 1, end;
+ while ((end = extract(s, pos)) >= 0) {
+ if (pos < end) {
+ tmp[count++] = Float.parseFloat(s.substring(pos, end));
+ }
+ pos = end + 1;
+ }
+ // handle the final float if there is one
+ if (pos < s.length()) {
+ tmp[count++] = Float.parseFloat(s.substring(pos, s.length()));
+ }
+ return Arrays.copyOf(tmp, count);
+ } catch (NumberFormatException e){
+ Log.e(LOGTAG,"error in parsing \""+s+"\"");
+ throw e;
+ }
+ }
+
+ /**
+ * calculate the position of the next comma or space
+ * @param s the string to search
+ * @param start the position to start searching
+ * @return the position of the next comma or space or -1 if none found
+ */
+ private static int extract(String s, int start) {
+ int space = s.indexOf(' ', start);
+ int comma = s.indexOf(',', start);
+ if (space == -1) {
+ return comma;
+ }
+ if (comma == -1) {
+ return space;
+ }
+ return (comma > space) ? space : comma;
+ }
+
+ private VectorDrawable.VNode[] parsePath(String value) {
+ int start = 0;
+ int end = 1;
+
+ ArrayList<VectorDrawable.VNode> list = new ArrayList<VectorDrawable.VNode>();
+ while (end < value.length()) {
+ end = nextStart(value, end);
+ String s = value.substring(start, end);
+ float[] val = getFloats(s);
+ addNode(list, s.charAt(0), val);
+
+ start = end;
+ end++;
+ }
+ if ((end - start) == 1 && start < value.length()) {
+
+ addNode(list, value.charAt(start), new float[0]);
+ }
+ return list.toArray(new VectorDrawable.VNode[list.size()]);
+ }
+
+ public void copyFrom(VPath p1) {
+ mNode = new VNode[p1.mNode.length];
+ for (int i = 0; i < mNode.length; i++) {
+ mNode[i] = new VNode(p1.mNode[i]);
+ }
+ mId = p1.mId;
+ mStrokeColor = p1.mStrokeColor;
+ mFillColor = p1.mFillColor;
+ mStrokeWidth = p1.mStrokeWidth;
+ mRotate = p1.mRotate;
+ mPivotX = p1.mPivotX;
+ mPivotY = p1.mPivotY;
+ mAnimated = p1.mAnimated;
+ mTrimPathStart = p1.mTrimPathStart;
+ mTrimPathEnd = p1.mTrimPathEnd;
+ mTrimPathOffset = p1.mTrimPathOffset;
+ mStrokelineCap = p1.mStrokelineCap;
+ mStrokelineJoin = p1.mStrokelineJoin;
+ mStrokeMiterlimit = p1.mStrokeMiterlimit;
+ mNumberOfStates = p1.mNumberOfStates;
+ for (int i = 0; i < mNumberOfStates; i++) {
+ mCheckState[i] = p1.mCheckState[i];
+ mCheckValue[i] = p1.mCheckValue[i];
+ }
+
+ mFillRule = p1.mFillRule;
+ }
+
+ public static VPath interpolate(float t, VPath p1, VPath p2, VPath returnPath, int limit) {
+ if (limit == LIMIT_ALL || limit == LIMIT_PATH) {
+ if (returnPath.mNode == null || returnPath.mNode.length != p1.mNode.length) {
+ returnPath.mNode = new VNode[p1.mNode.length];
+ }
+ for (int i = 0; i < returnPath.mNode.length; i++) {
+ if (returnPath.mNode[i] == null) {
+ returnPath.mNode[i] = new VNode(p1.mNode[i], p2.mNode[i], t);
+ } else {
+ returnPath.mNode[i].interpolate(p1.mNode[i], p2.mNode[i], t);
+ }
+ }
+ }
+ float t1 = 1 - t;
+ switch (limit) {
+ case LIMIT_ALL:
+ returnPath.mRotate = t1 * p1.mRotate + t * p2.mRotate;
+ returnPath.mPivotX = t1 * p1.mPivotX + t * p2.mPivotX;
+ returnPath.mPivotY = t1 * p1.mPivotY + t * p2.mPivotY;
+ returnPath.mClip = p1.mClip | p2.mClip;
+
+ returnPath.mTrimPathStart = t1 * p1.mTrimPathStart + t * p2.mTrimPathStart;
+ returnPath.mTrimPathEnd = t1 * p1.mTrimPathEnd + t * p2.mTrimPathEnd;
+ returnPath.mTrimPathOffset = t1 * p1.mTrimPathOffset + t * p2.mTrimPathOffset;
+ returnPath.mStrokeMiterlimit =
+ t1 * p1.mStrokeMiterlimit + t * p2.mStrokeMiterlimit;
+ returnPath.mStrokelineCap = p1.mStrokelineCap;
+ if (returnPath.mStrokelineCap == null) {
+ returnPath.mStrokelineCap = p2.mStrokelineCap;
+ }
+ returnPath.mStrokelineJoin = p1.mStrokelineJoin;
+ if (returnPath.mStrokelineJoin == null) {
+ returnPath.mStrokelineJoin = p2.mStrokelineJoin;
+ }
+ returnPath.mFillRule = p1.mFillRule;
+
+ returnPath.mStrokeColor = rgbInterpolate(t, p1.mStrokeColor, p2.mStrokeColor);
+ returnPath.mFillColor = rgbInterpolate(t, p1.mFillColor, p2.mFillColor);
+ returnPath.mStrokeWidth = t1 * p1.mStrokeWidth + t * p2.mStrokeWidth;
+ returnPath.mNumberOfStates = p1.mNumberOfStates;
+ for (int i = 0; i < returnPath.mNumberOfStates; i++) {
+ returnPath.mCheckState[i] = p1.mCheckState[i];
+ returnPath.mCheckValue[i] = p1.mCheckValue[i];
+ }
+ for (int i = 0; i < p2.mNumberOfStates; i++) {
+ returnPath.addStateFilter(p2.mCheckState[i], p2.mCheckValue[i]);
+ }
+
+ int count = 0;
+ for (int i = 0; i < returnPath.mNumberOfStates; i++) {
+ if (returnPath.mCheckValue[i]) {
+ count++;
+ }
+ }
+ returnPath.mNumberOfTrue = count;
+ break;
+ case LIMIT_ROTATE:
+ returnPath.mRotate = t1 * p1.mRotate + t * p2.mRotate;
+ break;
+ case LIMIT_TRIM_PATH_END:
+ returnPath.mTrimPathEnd = t1 * p1.mTrimPathEnd + t * p2.mTrimPathEnd;
+ break;
+ case LIMIT_TRIM_PATH_OFFSET:
+ returnPath.mTrimPathOffset = t1 * p1.mTrimPathOffset + t * p2.mTrimPathOffset;
+ break;
+ case LIMIT_TRIM_PATH_START:
+ returnPath.mTrimPathStart = t1 * p1.mTrimPathStart + t * p2.mTrimPathStart;
+ break;
+ }
+ return returnPath;
+ }
+
+ private static int rgbInterpolate(float t, int color1, int color2) {
+ int ret;
+ if (color1 == color2) {
+ return color2;
+ }
+ if (color1 == 0) {
+ return color2;
+ }
+ if (color2 == 0) {
+ return color1;
+ }
+
+ float t1 = 1 - t;
+ ret = 0xFF & (((int) ((color1 & 0xFF) * t1 + (color2 & 0xFF) * t)));
+ color1 >>= 8;
+ color2 >>= 8;
+
+ ret |= 0xFF00 & (((int) ((color1 & 0xFF) * t1 + (color2 & 0xFF) * t)) << 8);
+ color1 >>= 8;
+ color2 >>= 8;
+ ret |= 0xFF0000 & (((int) ((color1 & 0xFF) * t1 + (color2 & 0xFF) * t)) << 16);
+ color1 >>= 8;
+ color2 >>= 8;
+ ret |= 0xFF000000 & (((int) ((color1 & 0xFF) * t1 + (color2 & 0xFF) * t)) << 24);
+
+ return ret;
+ }
+
+ public boolean isVisible(int[] state) {
+ int match = 0;
+ for (int i = 0; i < state.length; i++) {
+ int v = getState(state[i]);
+ if (v != STATE_UNDEFINED) {
+ if (v==STATE_TRUE) {
+ match++;
+ } else {
+ return false;
+ }
+ }
+ }
+ return match == mNumberOfTrue;
+ }
+ }
+
+ private static class VNode {
+ char type;
+ float[] params;
+ private static float[] current = new float[4];
+ public VNode(char type, float[] params) {
+ this.type = type;
+ this.params = params;
+ }
+
+ public VNode(VNode n) {
+ this.type = n.type;
+ this.params = Arrays.copyOf(n.params, n.params.length);
+ }
+
+ public VNode(VNode n1, VNode n2, float t) {
+ this.type = n1.type;
+ this.params = new float[n1.params.length];
+ interpolate(n1, n2, t);
+ }
+
+ private boolean match(VNode n) {
+ if (n.type != type) {
+ return false;
+ }
+ return (params.length == n.params.length);
+ }
+
+ public void interpolate(VNode n1, VNode n2, float t) {
+ for (int i = 0; i < n1.params.length; i++) {
+ params[i] = n1.params[i] * (1 - t) + n2.params[i] * t;
+ }
+ }
+
+ private void nodeListToPath(VNode[] node, Path path) {
+ float[] current = new float[4];
+ for (int i = 0; i < node.length; i++) {
+ addCommand(path, current, node[i].type, node[i].params);
+ }
+ }
+
+ public static void createPath(VNode[] node, Path path) {
+ Arrays.fill(current,0);
+ for (int i = 0; i < node.length; i++) {
+ addCommand(path, current, node[i].type, node[i].params);
+ }
+ }
+
+ private static void addCommand(Path path, float[] current, char cmd, float[] val) {
+
+ int incr = 2;
+ float currentX = current[0];
+ float currentY = current[1];
+ float ctrlPointX = current[2];
+ float ctrlPointY = current[3];
+
+ switch (cmd) {
+ case 'z':
+ case 'Z':
+ path.close();
+ return;
+ case 'm':
+ case 'M':
+ case 'l':
+ case 'L':
+ case 't':
+ case 'T':
+ incr = 2;
+ break;
+ case 'h':
+ case 'H':
+ case 'v':
+ case 'V':
+ incr = 1;
+ break;
+ case 'c':
+ case 'C':
+ incr = 6;
+ break;
+ case 's':
+ case 'S':
+ case 'q':
+ case 'Q':
+ incr = 4;
+ break;
+ case 'a':
+ case 'A':
+ incr = 7;
+ break;
+ }
+ for (int k = 0; k < val.length; k += incr) {
+ // TODO: build test to prove all permutations work
+ switch (cmd) {
+ case 'm': // moveto - Start a new sub-path (relative)
+ path.rMoveTo(val[k + 0], val[k + 1]);
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ break;
+ case 'M': // moveto - Start a new sub-path
+ path.moveTo(val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ break;
+ case 'l': // lineto - Draw a line from the current point (relative)
+ path.rLineTo(val[k + 0], val[k + 1]);
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ break;
+ case 'L': // lineto - Draw a line from the current point
+ path.lineTo(val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ break;
+ case 'z': // closepath - Close the current subpath
+ case 'Z': // closepath - Close the current subpath
+ path.close();
+ break;
+ case 'h': // horizontal lineto - Draws a horizontal line (relative)
+ path.rLineTo(val[k + 0], 0);
+ currentX += val[k + 0];
+ break;
+ case 'H': // horizontal lineto - Draws a horizontal line
+ path.lineTo(val[k + 0], currentY);
+ currentX = val[k + 0];
+ break;
+ case 'v': // vertical lineto - Draws a vertical line from the current point (r)
+ path.rLineTo(0, val[k + 0]);
+ currentY += val[k + 0];
+ break;
+ case 'V': // vertical lineto - Draws a vertical line from the current point
+ path.lineTo(currentX, val[k + 0]);
+ currentY = val[k + 0];
+ break;
+ case 'c': // curveto - Draws a cubic Bézier curve (relative)
+ path.rCubicTo(val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3],
+ val[k + 4],
+ val[k + 5]);
+
+ ctrlPointX = currentX + val[k + 2];
+ ctrlPointY = currentY + val[k + 3];
+ currentX += val[k + 4];
+ currentY += val[k + 5];
+
+ break;
+ case 'C': // curveto - Draws a cubic Bézier curve
+ path.cubicTo(val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3],
+ val[k + 4],
+ val[k + 5]);
+ currentX = val[k + 4];
+ currentY = val[k + 5];
+ ctrlPointX = val[k + 2];
+ ctrlPointY = val[k + 3];
+
+ break;
+ case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
+ path.rCubicTo(currentX - ctrlPointX, currentY - ctrlPointY,
+ val[k + 0], val[k + 1],
+ val[k + 2], val[k + 3]);
+
+ ctrlPointX = currentX + val[k + 0];
+ ctrlPointY = currentY + val[k + 1];
+ currentX += val[k + 2];
+ currentY += val[k + 3];
+ break;
+ case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
+ path.cubicTo(2 * currentX - ctrlPointX,
+ 2 * currentY - ctrlPointY,
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3]);
+ currentX = val[k + 2];
+ currentY = val[k + 3];
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ break;
+ case 'q': // Draws a quadratic Bézier (relative)
+ path.rQuadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ currentX += val[k + 2];
+ currentY += val[k + 3];
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ break;
+ case 'Q': // Draws a quadratic Bézier
+ path.quadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ currentX = val[k + 2];
+ currentY = val[k + 3];
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ break;
+ case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
+ path.rQuadTo(currentX - ctrlPointX, currentY - ctrlPointY,
+ val[k + 0], val[k + 1]);
+ ctrlPointX = ctrlPointX + currentX;
+ ctrlPointY = ctrlPointY + currentY;
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+
+ break;
+ case 'T': // Draws a quadratic Bézier curve (reflective control point)
+ path.quadTo(currentX * 2 - ctrlPointX, currentY * 2 - ctrlPointY,
+ val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1]; // TODO: Check this logic
+ ctrlPointX = -(val[k + 0] - currentX);
+ ctrlPointY = -(val[k + 1] - currentY);
+ break;
+ case 'a': // Draws an elliptical arc
+ // (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
+ drawArc(path,
+ currentX,
+ currentY,
+ val[k + 5] + currentX,
+ val[k + 6] + currentY,
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
+ val[k + 4] != 0);
+ currentX += val[k + 5];
+ currentY += val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
+
+ break;
+ case 'A': // Draws an elliptical arc
+ drawArc(path,
+ currentX,
+ currentY,
+ val[k + 5],
+ val[k + 6],
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
+ val[k + 4] != 0);
+ currentX = val[k + 5];
+ currentY = val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
+ break;
+ }
+ }
+ current[0] = currentX;
+ current[1] = currentY;
+ current[2] = ctrlPointX;
+ current[3] = ctrlPointY;
+ }
+
+ private static void drawArc(Path p,
+ float x0,
+ float y0,
+ float x1,
+ float y1,
+ float a,
+ float b,
+ float theta,
+ boolean isMoreThanHalf,
+ boolean isPositiveArc) {
+
+ /* Convert rotation angle from degrees to radians */
+ double thetaD = Math.toRadians(theta);
+ /* Pre-compute rotation matrix entries */
+ double cosTheta = Math.cos(thetaD);
+ double sinTheta = Math.sin(thetaD);
+ /* Transform (x0, y0) and (x1, y1) into unit space */
+ /* using (inverse) rotation, followed by (inverse) scale */
+ double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
+ double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
+ double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
+ double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
+
+ /* Compute differences and averages */
+ double dx = x0p - x1p;
+ double dy = y0p - y1p;
+ double xm = (x0p + x1p) / 2;
+ double ym = (y0p + y1p) / 2;
+ /* Solve for intersecting unit circles */
+ double dsq = dx * dx + dy * dy;
+ if (dsq == 0.0) {
+ Log.w(LOGTAG, " Points are coincident");
+ return; /* Points are coincident */
+ }
+ double disc = 1.0 / dsq - 1.0 / 4.0;
+ if (disc < 0.0) {
+ Log.w(LOGTAG, "Points are too far apart " + dsq);
+ float adjust = (float) (Math.sqrt(dsq) / 1.99999);
+ drawArc(p, x0, y0, x1, y1, a * adjust,
+ b * adjust, theta, isMoreThanHalf, isPositiveArc);
+ return; /* Points are too far apart */
+ }
+ double s = Math.sqrt(disc);
+ double sdx = s * dx;
+ double sdy = s * dy;
+ double cx;
+ double cy;
+ if (isMoreThanHalf == isPositiveArc) {
+ cx = xm - sdy;
+ cy = ym + sdx;
+ } else {
+ cx = xm + sdy;
+ cy = ym - sdx;
+ }
+
+ double eta0 = Math.atan2((y0p - cy), (x0p - cx));
+
+ double eta1 = Math.atan2((y1p - cy), (x1p - cx));
+
+ double sweep = (eta1 - eta0);
+ if (isPositiveArc != (sweep >= 0)) {
+ if (sweep > 0) {
+ sweep -= 2 * Math.PI;
+ } else {
+ sweep += 2 * Math.PI;
+ }
+ }
+
+ cx *= a;
+ cy *= b;
+ double tcx = cx;
+ cx = cx * cosTheta - cy * sinTheta;
+ cy = tcx * sinTheta + cy * cosTheta;
+
+ arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
+ }
+
+ /**
+ * Converts an arc to cubic Bezier segments and records them in p.
+ *
+ * @param p The target for the cubic Bezier segments
+ * @param cx The x coordinate center of the ellipse
+ * @param cy The y coordinate center of the ellipse
+ * @param a The radius of the ellipse in the horizontal direction
+ * @param b The radius of the ellipse in the vertical direction
+ * @param e1x E(eta1) x coordinate of the starting point of the arc
+ * @param e1y E(eta2) y coordinate of the starting point of the arc
+ * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
+ * @param start The start angle of the arc on the ellipse
+ * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
+ */
+ private static void arcToBezier(Path p,
+ double cx,
+ double cy,
+ double a,
+ double b,
+ double e1x,
+ double e1y,
+ double theta,
+ double start,
+ double sweep) {
+ // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
+ // and http://www.spaceroots.org/documents/ellipse/node22.html
+
+ // Maximum of 45 degrees per cubic Bezier segment
+ int numSegments = Math.abs((int) Math.ceil(sweep * 4 / Math.PI));
+
+ double eta1 = start;
+ double cosTheta = Math.cos(theta);
+ double sinTheta = Math.sin(theta);
+ double cosEta1 = Math.cos(eta1);
+ double sinEta1 = Math.sin(eta1);
+ double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+ double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
+
+ double anglePerSegment = sweep / numSegments;
+ for (int i = 0; i < numSegments; i++) {
+ double eta2 = eta1 + anglePerSegment;
+ double sinEta2 = Math.sin(eta2);
+ double cosEta2 = Math.cos(eta2);
+ double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
+ double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
+ double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
+ double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
+ double tanDiff2 = Math.tan((eta2 - eta1) / 2);
+ double alpha =
+ Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
+ double q1x = e1x + alpha * ep1x;
+ double q1y = e1y + alpha * ep1y;
+ double q2x = e2x - alpha * ep2x;
+ double q2y = e2y - alpha * ep2y;
+
+ p.cubicTo((float) q1x,
+ (float) q1y,
+ (float) q2x,
+ (float) q2y,
+ (float) e2x,
+ (float) e2y);
+ eta1 = eta2;
+ e1x = e2x;
+ e1y = e2y;
+ ep1x = ep2x;
+ ep1y = ep2y;
+ }
+ }
+
+ }
+}
diff --git a/libs/androidfw/BackupData.cpp b/libs/androidfw/BackupData.cpp
index a5b9416..d16d5498 100644
--- a/libs/androidfw/BackupData.cpp
+++ b/libs/androidfw/BackupData.cpp
@@ -79,7 +79,7 @@ BackupDataWriter::write_padding_for(int n)
paddingSize = padding_extra(n);
if (paddingSize > 0) {
uint32_t padding = 0xbcbcbcbc;
- if (DEBUG) ALOGI("writing %d padding bytes for %d", paddingSize, n);
+ if (DEBUG) ALOGI("writing %zd padding bytes for %d", paddingSize, n);
amt = write(m_fd, &padding, paddingSize);
if (amt != paddingSize) {
m_status = errno;
@@ -113,7 +113,7 @@ BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
k = key;
}
if (DEBUG) {
- ALOGD("Writing header: prefix='%s' key='%s' dataSize=%d", m_keyPrefix.string(),
+ ALOGD("Writing header: prefix='%s' key='%s' dataSize=%zu", m_keyPrefix.string(),
key.string(), dataSize);
}
@@ -126,7 +126,7 @@ BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
header.keyLen = tolel(keyLen);
header.dataSize = tolel(dataSize);
- if (DEBUG) ALOGI("writing entity header, %d bytes", sizeof(entity_header_v1));
+ if (DEBUG) ALOGI("writing entity header, %zu bytes", sizeof(entity_header_v1));
amt = write(m_fd, &header, sizeof(entity_header_v1));
if (amt != sizeof(entity_header_v1)) {
m_status = errno;
@@ -134,7 +134,7 @@ BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
}
m_pos += amt;
- if (DEBUG) ALOGI("writing entity header key, %d bytes", keyLen+1);
+ if (DEBUG) ALOGI("writing entity header key, %zd bytes", keyLen+1);
amt = write(m_fd, k.string(), keyLen+1);
if (amt != keyLen+1) {
m_status = errno;
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
index ab837ad..52dce9f 100644
--- a/libs/androidfw/BackupHelpers.cpp
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -639,7 +639,7 @@ int write_tarfile(const String8& packageName, const String8& domain,
// size header -- calc len in digits by actually rendering the number
// to a string - brute force but simple
- snprintf(sizeStr, sizeof(sizeStr), "%lld", s.st_size);
+ snprintf(sizeStr, sizeof(sizeStr), "%lld", (long long)s.st_size);
p += write_pax_header_entry(p, "size", sizeStr);
// fullname was generated above with the ustar paths
@@ -661,7 +661,7 @@ int write_tarfile(const String8& packageName, const String8& domain,
// [ 124 : 12 ] size of pax extended header data
memset(paxHeader + 124, 0, 12);
- snprintf(paxHeader + 124, 12, "%011o", p - paxData);
+ snprintf(paxHeader + 124, 12, "%011o", (unsigned int)(p - paxData));
// Checksum and write the pax block header
calc_tar_checksum(paxHeader);
@@ -681,7 +681,10 @@ int write_tarfile(const String8& packageName, const String8& domain,
if (!isdir) {
off64_t toWrite = s.st_size;
while (toWrite > 0) {
- size_t toRead = (toWrite < BUFSIZE) ? toWrite : BUFSIZE;
+ size_t toRead = toWrite;
+ if (toRead > BUFSIZE) {
+ toRead = BUFSIZE;
+ }
ssize_t nRead = read(fd, buf, toRead);
if (nRead < 0) {
err = errno;
@@ -1095,8 +1098,8 @@ backup_helper_test_four()
if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
|| states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
|| states[i].size != state.size || states[i].crc32 != states[i].crc32) {
- fprintf(stderr, "state %zu expected={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n"
- " actual={%d/%d, 0x%08x, %04o, 0x%08x, %3zu} '%s'\n", i,
+ fprintf(stderr, "state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\n"
+ " actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\n", i,
states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
states[i].crc32, name.length(), filenames[i].string(),
state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
@@ -1194,7 +1197,7 @@ int
test_read_header_and_entity(BackupDataReader& reader, const char* str)
{
int err;
- int bufSize = strlen(str)+1;
+ size_t bufSize = strlen(str)+1;
char* buf = (char*)malloc(bufSize);
String8 string;
int cookie = 0x11111111;
@@ -1229,9 +1232,9 @@ test_read_header_and_entity(BackupDataReader& reader, const char* str)
err = EINVAL;
goto finished;
}
- if ((int)actualSize != bufSize) {
- fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08zx\n", bufSize,
- actualSize);
+ if (actualSize != bufSize) {
+ fprintf(stderr, "ReadEntityHeader expected dataSize %zu got %zu\n",
+ bufSize, actualSize);
err = EINVAL;
goto finished;
}
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index 2b74a33..166863c 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -210,8 +210,8 @@ uint32_t CursorWindow::alloc(size_t size, bool aligned) {
uint32_t offset = mHeader->freeOffset + padding;
uint32_t nextFreeOffset = offset + size;
if (nextFreeOffset > mSize) {
- ALOGW("Window is full: requested allocation %d bytes, "
- "free space %d bytes, window size %d bytes",
+ ALOGW("Window is full: requested allocation %zu bytes, "
+ "free space %zu bytes, window size %zu bytes",
size, freeSpace(), mSize);
return 0;
}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 04ca81e..7616ab0 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -6251,12 +6251,12 @@ void ResTable::print(bool inclValues) const
uintptr_t esize = dtohs(ent->size);
if ((esize&0x3) != 0) {
- printf("NON-INTEGER ResTable_entry SIZE: 0x%x\n", esize);
+ printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void *)esize);
continue;
}
if ((thisOffset+esize) > typeSize) {
- printf("ResTable_entry OUT OF BOUNDS: 0x%x+0x%x+0x%x (size is 0x%x)\n",
- entriesStart, thisOffset, esize, typeSize);
+ printf("ResTable_entry OUT OF BOUNDS: 0x%x+0x%x+%p (size is 0x%x)\n",
+ entriesStart, thisOffset, (void *)esize, typeSize);
continue;
}
diff --git a/libs/common_time/common_time_server.cpp b/libs/common_time/common_time_server.cpp
index 21e706f..3e11987 100644
--- a/libs/common_time/common_time_server.cpp
+++ b/libs/common_time/common_time_server.cpp
@@ -590,7 +590,7 @@ static void hexDumpToString(const uint8_t* src, size_t src_len,
for (i = 0; (i < src_len) && (offset < dst_len); ++i) {
int res;
if (0 == (i % 16)) {
- res = snprintf(dst + offset, dst_len - offset, "\n%04x :", i);
+ res = snprintf(dst + offset, dst_len - offset, "\n%04zx :", i);
if (res < 0)
break;
offset += res;
diff --git a/libs/common_time/utils.cpp b/libs/common_time/utils.cpp
index ed2c77d..ddcdfe7 100644
--- a/libs/common_time/utils.cpp
+++ b/libs/common_time/utils.cpp
@@ -56,7 +56,7 @@ LogRing::LogRing(const char* header, size_t entries)
, mHeader(header) {
mRingBuffer = new Entry[mSize];
if (NULL == mRingBuffer)
- ALOGE("Failed to allocate log ring with %u entries.", mSize);
+ ALOGE("Failed to allocate log ring with %zu entries.", mSize);
}
LogRing::~LogRing() {
@@ -150,7 +150,7 @@ void LogRing::dumpLog(int fd) {
localtime_r(&mRingBuffer[ndx].first_ts.tv_sec, &t);
strftime(timebuf, sizeof(timebuf), kTimeFmt, &t);
- res = snprintf(buf, sizeof(buf), "[%2d] %s.%03ld :: %s%s\n",
+ res = snprintf(buf, sizeof(buf), "[%2zu] %s.%03ld :: %s%s\n",
i, timebuf,
mRingBuffer[ndx].first_ts.tv_usec / 1000,
mRingBuffer[ndx].s.string(),
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 4de755d..52be531 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -54,6 +54,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
# RenderThread stuff
LOCAL_SRC_FILES += \
renderthread/CanvasContext.cpp \
+ renderthread/DrawFrameTask.cpp \
renderthread/RenderProxy.cpp \
renderthread/RenderTask.cpp \
renderthread/RenderThread.cpp
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 7380bbf..5b4e03f 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -29,7 +29,6 @@ DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* rendere
, mNeedsGLContextAttach(false)
, mUpdateTexImage(false)
, mLayer(layer)
- , mRenderer(renderer)
, mCaches(Caches::getInstance()) {
mWidth = mLayer->layer.getWidth();
mHeight = mLayer->layer.getHeight();
@@ -45,7 +44,6 @@ DeferredLayerUpdater::~DeferredLayerUpdater() {
if (mLayer) {
mCaches.resourceCache.decrementRefcount(mLayer);
}
- delete mRenderer;
}
void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
@@ -76,7 +74,7 @@ bool DeferredLayerUpdater::apply() {
}
mLayer->setBlend(mBlend);
mDisplayList->updateProperties();
- mLayer->updateDeferred(mRenderer, mDisplayList,
+ mLayer->updateDeferred(mDisplayList,
mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
mDirtyRect.setEmpty();
mDisplayList = 0;
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index cf745ee..10fa264 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -109,7 +109,6 @@ private:
bool mUpdateTexImage;
Layer* mLayer;
- OpenGLRenderer* mRenderer;
Caches& mCaches;
void doUpdateTexImage();
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 549b786..9e367fc 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -21,6 +21,8 @@
#define LOG_TAG "OpenGLRenderer"
#endif
+#include <SkPath.h>
+#include <SkPathOps.h>
#include <SkXfermode.h>
#include <private/hwui/DrawGlInfo.h>
@@ -1550,20 +1552,27 @@ private:
*/
class DrawShadowOp : public DrawOp {
public:
- DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, const SkPath* outline,
- float fallbackWidth, float fallbackHeight)
- : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ),
- mAlpha(alpha), mOutline(outline),
- mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight) {}
+ DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha,
+ float fallbackWidth, float fallbackHeight,
+ const SkPath* outline, const SkPath* revealClip)
+ : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), mAlpha(alpha),
+ mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight),
+ mOutline(outline), mRevealClip(revealClip) {}
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- if (mOutline->isEmpty()) {
- SkPath fakeOutline;
- fakeOutline.addRect(0, 0, mFallbackWidth, mFallbackHeight);
- return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &fakeOutline);
+ SkPath casterPerimeter;
+ if (!mOutline || mOutline->isEmpty()) {
+ casterPerimeter.addRect(0, 0, mFallbackWidth, mFallbackHeight);
+ } else {
+ casterPerimeter = *mOutline;
+ }
+
+ if (mRevealClip) {
+ // intersect the outline with the convex reveal clip
+ Op(casterPerimeter, *mRevealClip, kIntersect_PathOp, &casterPerimeter);
}
- return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, mOutline);
+ return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &casterPerimeter);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1576,9 +1585,12 @@ private:
const mat4 mTransformXY;
const mat4 mTransformZ;
const float mAlpha;
- const SkPath* mOutline;
const float mFallbackWidth;
const float mFallbackHeight;
+
+ // these point at convex SkPaths owned by RenderProperties, or null
+ const SkPath* mOutline;
+ const SkPath* mRevealClip;
};
class DrawLayerOp : public DrawOp {
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index bd9bfe9..4457c61 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -58,6 +58,7 @@ Layer::~Layer() {
delete[] mesh;
delete deferredList;
+ delete renderer;
}
uint32_t Layer::computeIdealWidth(uint32_t layerWidth) {
@@ -68,6 +69,13 @@ uint32_t Layer::computeIdealHeight(uint32_t layerHeight) {
return uint32_t(ceilf(layerHeight / float(LAYER_SIZE)) * LAYER_SIZE);
}
+void Layer::requireRenderer() {
+ if (!renderer) {
+ renderer = new LayerRenderer(this);
+ renderer->initProperties();
+ }
+}
+
bool Layer::resize(const uint32_t width, const uint32_t height) {
uint32_t desiredWidth = computeIdealWidth(width);
uint32_t desiredHeight = computeIdealWidth(height);
@@ -207,7 +215,6 @@ void Layer::defer() {
}
void Layer::cancelDefer() {
- renderer = NULL;
displayList = NULL;
deferredUpdateScheduled = false;
if (deferredList) {
@@ -226,7 +233,6 @@ void Layer::flush() {
deferredList->flush(*renderer, dirtyRect);
renderer->finish();
- renderer = NULL;
dirtyRect.setEmpty();
displayList = NULL;
@@ -241,7 +247,6 @@ void Layer::render() {
renderer->drawDisplayList(displayList, dirtyRect, RenderNode::kReplayFlag_ClipChildren);
renderer->finish();
- renderer = NULL;
dirtyRect.setEmpty();
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index d8440ea..b428404 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -84,9 +84,9 @@ public:
regionRect.translate(layer.left, layer.top);
}
- void updateDeferred(OpenGLRenderer* renderer, RenderNode* displayList,
+ void updateDeferred(RenderNode* displayList,
int left, int top, int right, int bottom) {
- this->renderer = renderer;
+ requireRenderer();
this->displayList = displayList;
const Rect r(left, top, right, bottom);
dirtyRect.unionWith(r);
@@ -300,6 +300,8 @@ public:
bool hasDrawnSinceUpdate;
private:
+ void requireRenderer();
+
Caches& caches;
/**
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index cdd789d..d808735 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1919,6 +1919,7 @@ status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty,
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
// compute 3d ordering
+ displayList->updateProperties();
displayList->computeOrdering();
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
status = startFrame();
@@ -3202,7 +3203,7 @@ static void mapPointFakeZ(Vector3& point, const mat4& transformXY, const mat4& t
}
status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ,
- float casterAlpha, const SkPath* casterOutline) {
+ float casterAlpha, const SkPath* casterPerimeter) {
if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
// TODO: use quickRejectWithScissor. For now, always force enable scissor.
@@ -3214,7 +3215,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
// tessellate caster outline into a 2d polygon
Vector<Vertex> casterVertices2d;
const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value
- PathTessellator::approximatePathOutlineVertices(*casterOutline,
+ PathTessellator::approximatePathOutlineVertices(*casterPerimeter,
casterRefinementThresholdSquared, casterVertices2d);
if (casterVertices2d.size() == 0) {
@@ -3256,7 +3257,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
// We only have ortho projection, so we can just ignore the Z in caster for
// simple rejection calculation.
Rect localClip = mSnapshot->getLocalClip();
- Rect casterBounds(casterOutline->getBounds());
+ Rect casterBounds(casterPerimeter->getBounds());
casterTransformXY.mapRect(casterBounds);
bool isCasterOpaque = (casterAlpha == 1.0f);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 059c64f..054767e 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -210,7 +210,7 @@ public:
virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
status_t drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ,
- float casterAlpha, const SkPath* casterOutline);
+ float casterAlpha, const SkPath* casterPerimeter);
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index 4e496e7..530be30 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -58,7 +58,6 @@ public:
mShouldClip = clip;
}
-
bool willClip() const {
// only round rect outlines can be used for clipping
return mShouldClip && (mType == kOutlineType_RoundRect);
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index d3daec8..675b215 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -107,6 +107,23 @@ void RenderNode::updateProperties() {
}
}
+bool RenderNode::hasFunctors() {
+ if (!mDisplayListData) return false;
+
+ if (mDisplayListData->functorCount) {
+ return true;
+ }
+
+ for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
+ RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
+ if (childNode->hasFunctors()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/*
* For property operations, we pass a savecount of 0, since the operations aren't part of the
* displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
@@ -152,18 +169,21 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
}
SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
- 0, 0, properties().getWidth(), properties().getHeight(), properties().getAlpha() * 255, saveFlags);
+ 0, 0, properties().getWidth(), properties().getHeight(),
+ properties().getAlpha() * 255, saveFlags);
handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
}
if (clipToBoundsNeeded) {
- ClipRectOp* op = new (handler.allocator()) ClipRectOp(0, 0,
- properties().getWidth(), properties().getHeight(), SkRegion::kIntersect_Op);
+ ClipRectOp* op = new (handler.allocator()) ClipRectOp(
+ 0, 0, properties().getWidth(), properties().getHeight(), SkRegion::kIntersect_Op);
handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
- if (CC_UNLIKELY(properties().getOutline().willClip())) {
- ClipPathOp* op = new (handler.allocator()) ClipPathOp(properties().getOutline().getPath(),
- SkRegion::kIntersect_Op);
+
+ if (CC_UNLIKELY(properties().hasClippingPath())) {
+ // TODO: optimize for round rect/circle clipping
+ const SkPath* path = properties().getClippingPath();
+ ClipPathOp* op = new (handler.allocator()) ClipPathOp(path, SkRegion::kIntersect_Op);
handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
}
@@ -408,10 +428,15 @@ void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTransl
mat4 shadowMatrixZ(casterOp->mTransformFromParent);
caster->applyViewPropertyTransforms(shadowMatrixZ, true);
+ const SkPath* outlinePath = caster->properties().getOutline().getPath();
+ const RevealClip& revealClip = caster->properties().getRevealClip();
+ const SkPath* revealClipPath = revealClip.hasConvexClip()
+ ? revealClip.getPath() : NULL; // only pass the reveal clip's path if it's convex
+
DisplayListOp* shadowOp = new (alloc) DrawShadowOp(
- shadowMatrixXY, shadowMatrixZ,
- caster->properties().getAlpha(), caster->properties().getOutline().getPath(),
- caster->properties().getWidth(), caster->properties().getHeight());
+ shadowMatrixXY, shadowMatrixZ, caster->properties().getAlpha(),
+ caster->properties().getWidth(), caster->properties().getHeight(),
+ outlinePath, revealClipPath);
handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
@@ -498,7 +523,8 @@ void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level)
setViewProperties<T>(renderer, handler, level + 1);
- bool quickRejected = properties().getClipToBounds() && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
+ bool quickRejected = properties().getClipToBounds()
+ && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
if (!quickRejected) {
Vector<ZDrawDisplayListOpPair> zTranslatedNodes;
buildZSortedChildList(zTranslatedNodes);
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 756c944..291d03d 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -139,6 +139,9 @@ public:
ANDROID_API void updateProperties();
+ // Returns true if this RenderNode or any of its children have functors
+ bool hasFunctors();
+
private:
typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index ca291a6..3975a76 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -22,6 +22,8 @@
#include <SkCanvas.h>
#include <SkMatrix.h>
+#include <SkPath.h>
+#include <SkPathOps.h>
#include "Matrix.h"
@@ -51,13 +53,15 @@ RenderProperties::PrimitiveFields::PrimitiveFields()
RenderProperties::ComputedFields::ComputedFields()
: mTransformMatrix(NULL)
, mTransformCamera(NULL)
- , mTransformMatrix3D(NULL) {
+ , mTransformMatrix3D(NULL)
+ , mClipPath(NULL) {
}
RenderProperties::ComputedFields::~ComputedFields() {
delete mTransformMatrix;
delete mTransformCamera;
delete mTransformMatrix3D;
+ delete mClipPath;
}
RenderProperties::RenderProperties()
@@ -80,6 +84,7 @@ RenderProperties& RenderProperties::operator=(const RenderProperties& other) {
// Update the computed fields
updateMatrix();
+ updateClipPath();
}
return *this;
}
@@ -181,5 +186,39 @@ void RenderProperties::updateMatrix() {
}
}
+void RenderProperties::updateClipPath() {
+ const SkPath* outlineClipPath = mPrimitiveFields.mOutline.willClip()
+ ? mPrimitiveFields.mOutline.getPath() : NULL;
+ const SkPath* revealClipPath = mPrimitiveFields.mRevealClip.getPath();
+
+ if (!outlineClipPath && !revealClipPath) {
+ // mComputedFields.mClipPath doesn't need to be updated, since it won't be used
+ return;
+ }
+
+ if (mComputedFields.mClipPath == NULL) {
+ mComputedFields.mClipPath = new SkPath();
+ }
+ SkPath* clipPath = mComputedFields.mClipPath;
+ mComputedFields.mClipPathOp = SkRegion::kIntersect_Op;
+
+ if (outlineClipPath && revealClipPath) {
+ SkPathOp op = kIntersect_PathOp;
+ if (mPrimitiveFields.mRevealClip.isInverseClip()) {
+ op = kDifference_PathOp; // apply difference step in the Op below, instead of draw time
+ }
+
+ Op(*outlineClipPath, *revealClipPath, op, clipPath);
+ } else if (outlineClipPath) {
+ *clipPath = *outlineClipPath;
+ } else {
+ *clipPath = *revealClipPath;
+ if (mPrimitiveFields.mRevealClip.isInverseClip()) {
+ // apply difference step at draw time
+ mComputedFields.mClipPathOp = SkRegion::kDifference_Op;
+ }
+ }
+}
+
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 504196d..061e469 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -22,8 +22,10 @@
#include <SkCamera.h>
#include <SkMatrix.h>
+#include <SkRegion.h>
#include "Rect.h"
+#include "RevealClip.h"
#include "Outline.h"
#define TRANSLATION 0x0001
@@ -34,7 +36,6 @@
class SkBitmap;
class SkPaint;
-class SkRegion;
namespace android {
namespace uirenderer {
@@ -415,6 +416,10 @@ public:
return mPrimitiveFields.mOutline;
}
+ const RevealClip& getRevealClip() const {
+ return mPrimitiveFields.mRevealClip;
+ }
+
bool getProjectBackwards() const {
return mPrimitiveFields.mProjectBackwards;
}
@@ -423,10 +428,29 @@ public:
ANDROID_API void updateMatrix();
+ ANDROID_API void updateClipPath();
+
+ // signals that mComputedFields.mClipPath is up to date, and should be used for clipping
+ bool hasClippingPath() const {
+ return mPrimitiveFields.mOutline.willClip() || mPrimitiveFields.mRevealClip.willClip();
+ }
+
+ const SkPath* getClippingPath() const {
+ return hasClippingPath() ? mComputedFields.mClipPath : NULL;
+ }
+
+ SkRegion::Op getClippingPathOp() const {
+ return mComputedFields.mClipPathOp;
+ }
+
Outline& mutableOutline() {
return mPrimitiveFields.mOutline;
}
+ RevealClip& mutableRevealClip() {
+ return mPrimitiveFields.mRevealClip;
+ }
+
private:
void onTranslationUpdate() {
mPrimitiveFields.mMatrixDirty = true;
@@ -442,6 +466,7 @@ private:
PrimitiveFields();
Outline mOutline;
+ RevealClip mRevealClip;
bool mClipToBounds;
bool mProjectBackwards;
bool mProjectionReceiver;
@@ -483,6 +508,8 @@ private:
Matrix4* mTransformMatrix;
Sk3DView* mTransformCamera;
SkMatrix* mTransformMatrix3D;
+ SkPath* mClipPath; // TODO: remove this, create new ops for efficient/special case clipping
+ SkRegion::Op mClipPathOp;
} mComputedFields;
};
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 5562f34..13a3e8e 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -31,9 +31,9 @@ void ResourceCache::logCache() {
ALOGD("ResourceCache: cacheReport:");
for (size_t i = 0; i < mCache->size(); ++i) {
ResourceReference* ref = mCache->valueAt(i);
- ALOGD(" ResourceCache: mCache(%d): resource, ref = 0x%p, 0x%p",
+ ALOGD(" ResourceCache: mCache(%zu): resource, ref = 0x%p, 0x%p",
i, mCache->keyAt(i), mCache->valueAt(i));
- ALOGD(" ResourceCache: mCache(%d): refCount, recycled, destroyed, type = %d, %d, %d, %d",
+ ALOGD(" ResourceCache: mCache(%zu): refCount, recycled, destroyed, type = %d, %d, %d, %d",
i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType);
}
}
diff --git a/libs/hwui/RevealClip.h b/libs/hwui/RevealClip.h
new file mode 100644
index 0000000..ece8498
--- /dev/null
+++ b/libs/hwui/RevealClip.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef REVEALCLIP_H
+#define REVEALCLIP_H
+
+#include <SkPath.h>
+
+#include "Rect.h"
+
+namespace android {
+namespace uirenderer {
+
+class RevealClip {
+public:
+ RevealClip()
+ : mShouldClip(false)
+ , mInverseClip(false)
+ , mX(0)
+ , mY(0)
+ , mRadius(0) {}
+
+ void set(bool shouldClip, bool inverseClip, float x, float y, float radius) {
+ mShouldClip = shouldClip;
+ mInverseClip = inverseClip;
+ mX = x;
+ mY = y;
+ mRadius = radius;
+
+ mPath.rewind();
+ if (mShouldClip) {
+ mPath.addCircle(x, y, radius);
+ }
+ }
+
+ bool hasConvexClip() const {
+ return mShouldClip && !mInverseClip;
+ }
+
+ bool isInverseClip() const {
+ return mInverseClip;
+ }
+
+ bool willClip() const {
+ return mShouldClip;
+ }
+
+ const SkPath* getPath() const {
+ if (!mShouldClip) return NULL;
+
+ return &mPath;
+ }
+
+private:
+ bool mShouldClip;
+ bool mInverseClip;
+ float mX;
+ float mY;
+ float mRadius;
+ SkPath mPath;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* REVEALCLIP_H */
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b3b4173..8ebffc2 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -392,8 +392,6 @@ void CanvasContext::drawDisplayList(RenderNode* displayList, Rect* dirty) {
LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
"drawDisplayList called on a context with no canvas or surface!");
- displayList->updateProperties();
-
EGLint width, height;
mGlobalContext->beginFrame(mEglSurface, &width, &height);
if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
new file mode 100644
index 0000000..1e9089a
--- /dev/null
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define ATRACE_TAG ATRACE_TAG_VIEW
+
+#include "DrawFrameTask.h"
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include "../DisplayList.h"
+#include "../RenderNode.h"
+#include "CanvasContext.h"
+#include "RenderThread.h"
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+DrawFrameTask::DrawFrameTask() : mContext(0), mRenderNode(0) {
+}
+
+DrawFrameTask::~DrawFrameTask() {
+}
+
+void DrawFrameTask::setContext(CanvasContext* context) {
+ mContext = context;
+}
+
+void DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
+ SetDisplayListData setter;
+ setter.targetNode = renderNode;
+ setter.newData = newData;
+ mDisplayListDataUpdates.push(setter);
+}
+
+void DrawFrameTask::addLayer(DeferredLayerUpdater* layer) {
+ mLayers.push(layer);
+}
+
+void DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) {
+ for (size_t i = 0; i < mLayers.size(); i++) {
+ if (mLayers[i] == layer) {
+ mLayers.removeAt(i);
+ break;
+ }
+ }
+}
+
+void DrawFrameTask::setRenderNode(RenderNode* renderNode) {
+ mRenderNode = renderNode;
+}
+
+void DrawFrameTask::setDirty(int left, int top, int right, int bottom) {
+ mDirty.set(left, top, right, bottom);
+}
+
+void DrawFrameTask::drawFrame(RenderThread* renderThread) {
+ LOG_ALWAYS_FATAL_IF(!mRenderNode, "Cannot drawFrame with no render node!");
+ LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
+
+ AutoMutex _lock(mLock);
+ renderThread->queue(this);
+ mSignal.wait(mLock);
+
+ // Reset the single-frame data
+ mDirty.setEmpty();
+ mRenderNode = 0;
+}
+
+void DrawFrameTask::run() {
+ ATRACE_NAME("DrawFrame");
+
+ syncFrameState();
+
+ // Grab a copy of everything we need
+ Rect dirtyCopy(mDirty);
+ RenderNode* renderNode = mRenderNode;
+ CanvasContext* context = mContext;
+
+ // This is temporary until WebView has a solution for syncing frame state
+ bool canUnblockUiThread = !requiresSynchronousDraw(renderNode);
+
+ // From this point on anything in "this" is *UNSAFE TO ACCESS*
+ if (canUnblockUiThread) {
+ unblockUiThread();
+ }
+
+ drawRenderNode(context, renderNode, &dirtyCopy);
+
+ if (!canUnblockUiThread) {
+ unblockUiThread();
+ }
+}
+
+void DrawFrameTask::syncFrameState() {
+ ATRACE_CALL();
+
+ for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) {
+ const SetDisplayListData& setter = mDisplayListDataUpdates[i];
+ setter.targetNode->setData(setter.newData);
+ }
+ mDisplayListDataUpdates.clear();
+
+ mContext->processLayerUpdates(&mLayers);
+ mRenderNode->updateProperties();
+}
+
+void DrawFrameTask::unblockUiThread() {
+ AutoMutex _lock(mLock);
+ mSignal.signal();
+}
+
+void DrawFrameTask::drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty) {
+ ATRACE_CALL();
+
+ if (dirty->bottom == -1 && dirty->left == -1
+ && dirty->top == -1 && dirty->right == -1) {
+ dirty = 0;
+ }
+ context->drawDisplayList(renderNode, dirty);
+}
+
+bool DrawFrameTask::requiresSynchronousDraw(RenderNode* renderNode) {
+ return renderNode->hasFunctors();
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
new file mode 100644
index 0000000..5450dd5
--- /dev/null
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef DRAWFRAMETASK_H
+#define DRAWFRAMETASK_H
+
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <utils/Vector.h>
+
+#include "RenderTask.h"
+
+#include "../Rect.h"
+
+namespace android {
+namespace uirenderer {
+
+class DeferredLayerUpdater;
+class DisplayListData;
+class RenderNode;
+
+namespace renderthread {
+
+class CanvasContext;
+class RenderThread;
+
+struct SetDisplayListData {
+ RenderNode* targetNode;
+ DisplayListData* newData;
+};
+
+/*
+ * This is a special Super Task. It is re-used multiple times by RenderProxy,
+ * and contains state (such as layer updaters & new DisplayListDatas) that is
+ * tracked across many frames not just a single frame.
+ * It is the sync-state task, and will kick off the post-sync draw
+ */
+class DrawFrameTask : public RenderTask {
+public:
+ DrawFrameTask();
+ virtual ~DrawFrameTask();
+
+ void setContext(CanvasContext* context);
+
+ void setDisplayListData(RenderNode* renderNode, DisplayListData* newData);
+ void addLayer(DeferredLayerUpdater* layer);
+ void removeLayer(DeferredLayerUpdater* layer);
+
+ void setRenderNode(RenderNode* renderNode);
+ void setDirty(int left, int top, int right, int bottom);
+ void drawFrame(RenderThread* renderThread);
+
+ virtual void run();
+
+private:
+ void syncFrameState();
+ void unblockUiThread();
+ static void drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty);
+
+ // This checks to see if there are any drawGlFunctors which would require
+ // a synchronous drawRenderNode()
+ static bool requiresSynchronousDraw(RenderNode* renderNode);
+
+ Mutex mLock;
+ Condition mSignal;
+
+ CanvasContext* mContext;
+
+ /*********************************************
+ * Single frame data
+ *********************************************/
+ RenderNode* mRenderNode;
+ Rect mDirty;
+ Vector<SetDisplayListData> mDisplayListDataUpdates;
+
+ /*********************************************
+ * Multi frame data
+ *********************************************/
+ Vector<DeferredLayerUpdater*> mLayers;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* DRAWFRAMETASK_H */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 93360fc..16b93c3 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -61,6 +61,7 @@ RenderProxy::RenderProxy(bool translucent)
SETUP_TASK(createContext);
args->translucent = translucent;
mContext = (CanvasContext*) postAndWait(task);
+ mDrawFrameTask.setContext(mContext);
}
RenderProxy::~RenderProxy() {
@@ -77,7 +78,10 @@ void RenderProxy::destroyContext() {
SETUP_TASK(destroyContext);
args->context = mContext;
mContext = 0;
- post(task);
+ mDrawFrameTask.setContext(0);
+ // This is also a fence as we need to be certain that there are no
+ // outstanding mDrawFrame tasks posted before it is destroyed
+ postAndWait(task);
}
}
@@ -117,41 +121,15 @@ void RenderProxy::setup(int width, int height) {
post(task);
}
-CREATE_BRIDGE3(setDisplayListData, CanvasContext* context, RenderNode* displayList,
- DisplayListData* newData) {
- args->context->setDisplayListData(args->displayList, args->newData);
- return NULL;
-}
-
-void RenderProxy::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
- SETUP_TASK(setDisplayListData);
- args->context = mContext;
- args->displayList = displayList;
- args->newData = newData;
- post(task);
-}
-
-CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, RenderNode* displayList,
- Rect dirty, const Vector<DeferredLayerUpdater*>* layerUpdates) {
- Rect* dirty = &args->dirty;
- if (dirty->bottom == -1 && dirty->left == -1 &&
- dirty->top == -1 && dirty->right == -1) {
- dirty = 0;
- }
- args->context->processLayerUpdates(args->layerUpdates);
- args->context->drawDisplayList(args->displayList, dirty);
- return NULL;
+void RenderProxy::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
+ mDrawFrameTask.setDisplayListData(renderNode, newData);
}
void RenderProxy::drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom) {
- SETUP_TASK(drawDisplayList);
- args->context = mContext;
- args->displayList = displayList;
- args->dirty.set(dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
- args->layerUpdates = &mLayers;
- // TODO: Switch to post() once some form of thread safety strategy is in place
- postAndWait(task);
+ mDrawFrameTask.setRenderNode(displayList);
+ mDrawFrameTask.setDirty(dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
+ mDrawFrameTask.drawFrame(&mRenderThread);
}
CREATE_BRIDGE1(destroyCanvas, CanvasContext* context) {
@@ -205,9 +183,7 @@ CREATE_BRIDGE2(createDisplayListLayer, int width, int height) {
Layer* layer = LayerRenderer::createRenderLayer(args->width, args->height);
if (!layer) return 0;
- OpenGLRenderer* renderer = new LayerRenderer(layer);
- renderer->initProperties();
- return new DeferredLayerUpdater(layer, renderer);
+ return new DeferredLayerUpdater(layer);
}
DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) {
@@ -216,7 +192,7 @@ DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height)
args->height = height;
void* retval = postAndWait(task);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
- mLayers.push(layer);
+ mDrawFrameTask.addLayer(layer);
return layer;
}
@@ -230,7 +206,7 @@ DeferredLayerUpdater* RenderProxy::createTextureLayer() {
SETUP_TASK(createTextureLayer);
void* retval = postAndWait(task);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
- mLayers.push(layer);
+ mDrawFrameTask.addLayer(layer);
return layer;
}
@@ -254,12 +230,7 @@ bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
}
void RenderProxy::destroyLayer(DeferredLayerUpdater* layer) {
- for (size_t i = 0; i < mLayers.size(); i++) {
- if (mLayers[i] == layer) {
- mLayers.removeAt(i);
- break;
- }
- }
+ mDrawFrameTask.removeLayer(layer);
SETUP_TASK(destroyLayer);
args->layer = layer->detachBackingLayer();
post(task);
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 73e9805..ee7a4c7 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -28,6 +28,8 @@
#include <utils/StrongPointer.h>
#include <utils/Vector.h>
+#include "DrawFrameTask.h"
+
namespace android {
namespace uirenderer {
@@ -60,7 +62,7 @@ public:
ANDROID_API bool initialize(EGLNativeWindowType window);
ANDROID_API void updateSurface(EGLNativeWindowType window);
ANDROID_API void setup(int width, int height);
- ANDROID_API void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
+ ANDROID_API void setDisplayListData(RenderNode* renderNode, DisplayListData* newData);
ANDROID_API void drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
ANDROID_API void destroyCanvas();
@@ -79,11 +81,11 @@ private:
RenderThread& mRenderThread;
CanvasContext* mContext;
+ DrawFrameTask mDrawFrameTask;
+
Mutex mSyncMutex;
Condition mSyncCondition;
- Vector<DeferredLayerUpdater*> mLayers;
-
void destroyContext();
MethodInvokeRenderTask* createTask(RunnableMethod method);
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
index 06b477f..57c0320 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
+++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
@@ -32,7 +32,7 @@
struct usb_device *sDevice = NULL;
static void* read_thread(void* arg) {
- int endpoint = (int)arg;
+ int endpoint = (int)(uintptr_t)arg;
int ret = 0;
while (sDevice && ret >= 0) {
@@ -52,7 +52,7 @@ static void* read_thread(void* arg) {
}
static void* write_thread(void* arg) {
- int endpoint = (int)arg;
+ int endpoint = (int)(uintptr_t)arg;
int ret = 0;
while (ret >= 0) {
@@ -136,11 +136,11 @@ static int usb_device_added(const char *devname, void* client_data) {
}
if ((ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
- pthread_create(&th, NULL, read_thread, (void *)ep1->bEndpointAddress);
- pthread_create(&th, NULL, write_thread, (void *)ep2->bEndpointAddress);
+ pthread_create(&th, NULL, read_thread, (void *)(uintptr_t)ep1->bEndpointAddress);
+ pthread_create(&th, NULL, write_thread, (void *)(uintptr_t)ep2->bEndpointAddress);
} else {
- pthread_create(&th, NULL, read_thread, (void *)ep2->bEndpointAddress);
- pthread_create(&th, NULL, write_thread, (void *)ep1->bEndpointAddress);
+ pthread_create(&th, NULL, read_thread, (void *)(uintptr_t)ep2->bEndpointAddress);
+ pthread_create(&th, NULL, write_thread, (void *)(uintptr_t)ep1->bEndpointAddress);
}
} else {
printf("Found possible android device - attempting to switch to accessory mode\n");
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index 1016dd4..f688d81 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -32,6 +32,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
+import android.media.PlayerRecord.RemotePlaybackState;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -73,8 +74,7 @@ public class MediaFocusControl implements OnFinished {
private boolean mIsRinging = false;
private final PowerManager.WakeLock mMediaEventWakeLock;
- //FIXME should be private
- protected final MediaEventHandler mEventHandler;
+ private final MediaEventHandler mEventHandler;
private final Context mContext;
private final ContentResolver mContentResolver;
private final VolumeController mVolumeController;
@@ -120,6 +120,9 @@ public class MediaFocusControl implements OnFinished {
mHasRemotePlayback = false;
mMainRemoteIsActive = false;
+
+ PlayerRecord.setMediaFocusControl(this);
+
postReevaluateRemote();
}
@@ -251,7 +254,7 @@ public class MediaFocusControl implements OnFinished {
currentUser);
if (DEBUG_RC) { Log.d(TAG, " > enabled list: " + enabledNotifListeners); }
synchronized(mAudioFocusLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
// check whether the "enable" status of each RCD with a notification listener
// has changed
final String[] enabledComponents;
@@ -330,6 +333,7 @@ public class MediaFocusControl implements OnFinished {
private static final int MSG_RCC_UPDATE_METADATA = 9;
private static final int MSG_RCDISPLAY_INIT_INFO = 10;
private static final int MSG_REEVALUATE_RCD = 11;
+ private static final int MSG_UNREGISTER_MEDIABUTTONINTENT = 12;
// sendMsg() flags
/** If the msg is already queued, replace it with this one. */
@@ -351,8 +355,7 @@ public class MediaFocusControl implements OnFinished {
handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delay);
}
- //FIXME should be private
- protected class MediaEventHandler extends Handler {
+ private class MediaEventHandler extends Handler {
MediaEventHandler(Looper looper) {
super(looper);
}
@@ -370,7 +373,7 @@ public class MediaFocusControl implements OnFinished {
case MSG_RCDISPLAY_UPDATE:
// msg.obj is guaranteed to be non null
- onRcDisplayUpdate( (MediaController) msg.obj, msg.arg1);
+ onRcDisplayUpdate( (PlayerRecord) msg.obj, msg.arg1);
break;
case MSG_REEVALUATE_REMOTE:
@@ -390,7 +393,7 @@ public class MediaFocusControl implements OnFinished {
case MSG_RCC_NEW_PLAYBACK_STATE:
onNewPlaybackStateForRcc(msg.arg1 /* rccId */,
msg.arg2 /* state */,
- (MediaController.RccPlaybackState)msg.obj /* newState */);
+ (PlayerRecord.RccPlaybackState)msg.obj /* newState */);
break;
case MSG_RCC_SEEK_REQUEST:
@@ -416,6 +419,10 @@ public class MediaFocusControl implements OnFinished {
case MSG_REEVALUATE_RCD:
onReevaluateRemoteControlDisplays();
break;
+
+ case MSG_UNREGISTER_MEDIABUTTONINTENT:
+ unregisterMediaButtonIntent( (PendingIntent) msg.obj );
+ break;
}
}
}
@@ -465,7 +472,7 @@ public class MediaFocusControl implements OnFinished {
exFocusOwner.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS);
exFocusOwner.release();
// clear RCD
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
clearRemoteControlDisplay_syncAfRcs();
}
}
@@ -529,7 +536,7 @@ public class MediaFocusControl implements OnFinished {
// notify the new top of the stack it gained focus
notifyTopOfAudioFocusStack();
// there's a new top of the stack, let the remote control know
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
}
@@ -576,7 +583,7 @@ public class MediaFocusControl implements OnFinished {
// notify the new top of the stack it gained focus.
notifyTopOfAudioFocusStack();
// there's a new top of the stack, let the remote control know
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
}
@@ -688,7 +695,7 @@ public class MediaFocusControl implements OnFinished {
clientId, afdh, callingPackageName, Binder.getCallingUid()));
// there's a new top of the stack, let the remote control know
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
}//synchronized(mAudioFocusLock)
@@ -752,7 +759,7 @@ public class MediaFocusControl implements OnFinished {
}
// event filtering for telephony
synchronized(mRingingLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
if ((mMediaReceiverForCalls != null) &&
(mIsRinging || (mAudioService.getMode() == AudioSystem.MODE_IN_CALL))) {
dispatchMediaKeyEventForCalls(keyEvent, needWakeLock);
@@ -805,15 +812,15 @@ public class MediaFocusControl implements OnFinished {
}
Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
- synchronized(mMCStack) {
- if (!mMCStack.empty()) {
+ synchronized(mPRStack) {
+ if (!mPRStack.empty()) {
// send the intent that was registered by the client
try {
- mMCStack.peek().mMediaIntent.send(mContext,
+ mPRStack.peek().getMediaButtonIntent().send(mContext,
needWakeLock ? WAKELOCK_RELEASE_ON_FINISHED : 0 /*code*/,
keyIntent, this, mEventHandler);
} catch (CanceledException e) {
- Log.e(TAG, "Error sending pending intent " + mMCStack.peek());
+ Log.e(TAG, "Error sending pending intent " + mPRStack.peek());
e.printStackTrace();
}
} else {
@@ -1023,7 +1030,7 @@ public class MediaFocusControl implements OnFinished {
};
/**
- * Synchronization on mCurrentRcLock always inside a block synchronized on mMCStack
+ * Synchronization on mCurrentRcLock always inside a block synchronized on mPRStack
*/
private final Object mCurrentRcLock = new Object();
/**
@@ -1052,47 +1059,6 @@ public class MediaFocusControl implements OnFinished {
*/
private int mCurrentRcClientGen = 0;
- /**
- * Inner class to monitor remote control client deaths, and remove the client for the
- * remote control stack if necessary.
- */
- protected class RcClientDeathHandler implements IBinder.DeathRecipient {
- //FIXME should be private
- final protected IBinder mCb; // To be notified of client's death
- final private PendingIntent mMediaIntent;
-
- RcClientDeathHandler(IBinder cb, PendingIntent pi) {
- mCb = cb;
- mMediaIntent = pi;
- }
-
- public void binderDied() {
- Log.w(TAG, " RemoteControlClient died");
- // remote control client died, make sure the displays don't use it anymore
- // by setting its remote control client to null
- registerRemoteControlClient(mMediaIntent, null/*rcClient*/, null/*ignored*/);
- // the dead client was maybe handling remote playback, reevaluate
- postReevaluateRemote();
- }
-
- public IBinder getBinder() {
- return mCb;
- }
- }
-
- protected class RemotePlaybackState {
- int mRccId;
- int mVolume;
- int mVolumeMax;
- int mVolumeHandling;
-
- private RemotePlaybackState(int id, int vol, int volMax) {
- mRccId = id;
- mVolume = vol;
- mVolumeMax = volMax;
- mVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
- }
- }
/**
* Internal cache for the playback information of the RemoteControlClient whose volume gets to
@@ -1116,10 +1082,10 @@ public class MediaFocusControl implements OnFinished {
/**
* The stack of remote control event receivers.
* Code sections and methods that modify the remote control event receiver stack are
- * synchronized on mMCStack, but also BEFORE on mFocusLock as any change in either
+ * synchronized on mPRStack, but also BEFORE on mFocusLock as any change in either
* stack, audio focus or RC, can lead to a change in the remote control display
*/
- private final Stack<MediaController> mMCStack = new Stack<MediaController>();
+ private final Stack<PlayerRecord> mPRStack = new Stack<PlayerRecord>();
/**
* The component the telephony package can register so telephony calls have priority to
@@ -1133,17 +1099,10 @@ public class MediaFocusControl implements OnFinished {
*/
private void dumpRCStack(PrintWriter pw) {
pw.println("\nRemote Control stack entries (last is top of stack):");
- synchronized(mMCStack) {
- Iterator<MediaController> stackIterator = mMCStack.iterator();
+ synchronized(mPRStack) {
+ Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- MediaController mcse = stackIterator.next();
- pw.println(" pi: " + mcse.mMediaIntent +
- " -- pack: " + mcse.mCallingPackageName +
- " -- ercvr: " + mcse.mReceiverComponent +
- " -- client: " + mcse.mRcClient +
- " -- uid: " + mcse.mCallingUid +
- " -- type: " + mcse.mPlaybackType +
- " state: " + mcse.mPlaybackState);
+ stackIterator.next().dump(pw, true);
}
}
}
@@ -1155,18 +1114,10 @@ public class MediaFocusControl implements OnFinished {
*/
private void dumpRCCStack(PrintWriter pw) {
pw.println("\nRemote Control Client stack entries (last is top of stack):");
- synchronized(mMCStack) {
- Iterator<MediaController> stackIterator = mMCStack.iterator();
+ synchronized(mPRStack) {
+ Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- MediaController mcse = stackIterator.next();
- pw.println(" uid: " + mcse.mCallingUid +
- " -- id: " + mcse.mRccId +
- " -- type: " + mcse.mPlaybackType +
- " -- state: " + mcse.mPlaybackState +
- " -- vol handling: " + mcse.mPlaybackVolumeHandling +
- " -- vol: " + mcse.mPlaybackVolume +
- " -- volMax: " + mcse.mPlaybackVolumeMax +
- " -- volObs: " + mcse.mRemoteVolumeObs);
+ stackIterator.next().dump(pw, false);
}
synchronized(mCurrentRcLock) {
pw.println("\nCurrent remote control generation ID = " + mCurrentRcClientGen);
@@ -1191,7 +1142,7 @@ public class MediaFocusControl implements OnFinished {
*/
private void dumpRCDList(PrintWriter pw) {
pw.println("\nRemote Control Display list entries:");
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
while (displayIterator.hasNext()) {
final DisplayInfoForServer di = displayIterator.next();
@@ -1210,47 +1161,49 @@ public class MediaFocusControl implements OnFinished {
* Pre-condition: packageName != null
*/
private void cleanupMediaButtonReceiverForPackage(String packageName, boolean removeAll) {
- synchronized(mMCStack) {
- if (mMCStack.empty()) {
+ synchronized(mPRStack) {
+ if (mPRStack.empty()) {
return;
} else {
final PackageManager pm = mContext.getPackageManager();
- MediaController oldTop = mMCStack.peek();
- Iterator<MediaController> stackIterator = mMCStack.iterator();
+ PlayerRecord oldTop = mPRStack.peek();
+ Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
// iterate over the stack entries
// (using an iterator on the stack so we can safely remove an entry after having
// evaluated it, traversal order doesn't matter here)
while(stackIterator.hasNext()) {
- MediaController mcse = stackIterator.next();
- if (removeAll && packageName.equals(mcse.mMediaIntent.getCreatorPackage())) {
+ PlayerRecord prse = stackIterator.next();
+ if (removeAll
+ && packageName.equals(prse.getMediaButtonIntent().getCreatorPackage()))
+ {
// a stack entry is from the package being removed, remove it from the stack
stackIterator.remove();
- mcse.destroy();
- } else if (mcse.mReceiverComponent != null) {
+ prse.destroy();
+ } else if (prse.getMediaButtonReceiver() != null) {
try {
// Check to see if this receiver still exists.
- pm.getReceiverInfo(mcse.mReceiverComponent, 0);
+ pm.getReceiverInfo(prse.getMediaButtonReceiver(), 0);
} catch (PackageManager.NameNotFoundException e) {
// Not found -- remove it!
stackIterator.remove();
- mcse.destroy();
+ prse.destroy();
}
}
}
- if (mMCStack.empty()) {
+ if (mPRStack.empty()) {
// no saved media button receiver
mEventHandler.sendMessage(
mEventHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
null));
- } else if (oldTop != mMCStack.peek()) {
+ } else if (oldTop != mPRStack.peek()) {
// the top of the stack has changed, save it in the system settings
// by posting a message to persist it; only do this however if it has
// a concrete component name (is not a transient registration)
- MediaController mcse = mMCStack.peek();
- if (mcse.mReceiverComponent != null) {
+ PlayerRecord prse = mPRStack.peek();
+ if (prse.getMediaButtonReceiver() != null) {
mEventHandler.sendMessage(
mEventHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
- mcse.mReceiverComponent));
+ prse.getMediaButtonReceiver()));
}
}
}
@@ -1284,28 +1237,28 @@ public class MediaFocusControl implements OnFinished {
/**
* Helper function:
* Set the new remote control receiver at the top of the RC focus stack.
- * Called synchronized on mAudioFocusLock, then mMCStack
+ * Called synchronized on mAudioFocusLock, then mPRStack
* precondition: mediaIntent != null
- * @return true if mMCStack was changed, false otherwise
+ * @return true if mPRStack was changed, false otherwise
*/
private boolean pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent,
ComponentName target, IBinder token) {
// already at top of stack?
- if (!mMCStack.empty() && mMCStack.peek().mMediaIntent.equals(mediaIntent)) {
+ if (!mPRStack.empty() && mPRStack.peek().hasMatchingMediaButtonIntent(mediaIntent)) {
return false;
}
if (mAppOps.noteOp(AppOpsManager.OP_TAKE_MEDIA_BUTTONS, Binder.getCallingUid(),
mediaIntent.getCreatorPackage()) != AppOpsManager.MODE_ALLOWED) {
return false;
}
- MediaController mcse = null;
+ PlayerRecord prse = null;
boolean wasInsideStack = false;
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- mcse = mMCStack.elementAt(index);
- if(mcse.mMediaIntent.equals(mediaIntent)) {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ prse = mPRStack.elementAt(index);
+ if(prse.hasMatchingMediaButtonIntent(mediaIntent)) {
// ok to remove element while traversing the stack since we're leaving the loop
- mMCStack.removeElementAt(index);
+ mPRStack.removeElementAt(index);
wasInsideStack = true;
break;
}
@@ -1315,9 +1268,9 @@ public class MediaFocusControl implements OnFinished {
Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
}
if (!wasInsideStack) {
- mcse = new MediaController(this, mediaIntent, target, token);
+ prse = new PlayerRecord(mediaIntent, target, token);
}
- mMCStack.push(mcse); // mcse is never null
+ mPRStack.push(prse); // prse is never null
// post message to persist the default media button receiver
if (target != null) {
@@ -1332,17 +1285,17 @@ public class MediaFocusControl implements OnFinished {
/**
* Helper function:
* Remove the remote control receiver from the RC focus stack.
- * Called synchronized on mAudioFocusLock, then mMCStack
+ * Called synchronized on mAudioFocusLock, then mPRStack
* precondition: pi != null
*/
private void removeMediaButtonReceiver_syncAfRcs(PendingIntent pi) {
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if (mcse.mMediaIntent.equals(pi)) {
- mcse.destroy();
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if (prse.hasMatchingMediaButtonIntent(pi)) {
+ prse.destroy();
// ok to remove element while traversing the stack since we're leaving the loop
- mMCStack.removeElementAt(index);
+ mPRStack.removeElementAt(index);
break;
}
}
@@ -1354,10 +1307,10 @@ public class MediaFocusControl implements OnFinished {
/**
* Helper function:
- * Called synchronized on mMCStack
+ * Called synchronized on mPRStack
*/
private boolean isCurrentRcController(PendingIntent pi) {
- if (!mMCStack.empty() && mMCStack.peek().mMediaIntent.equals(pi)) {
+ if (!mPRStack.empty() && mPRStack.peek().hasMatchingMediaButtonIntent(pi)) {
return true;
}
return false;
@@ -1378,7 +1331,7 @@ public class MediaFocusControl implements OnFinished {
*/
private void setNewRcClientOnDisplays_syncRcsCurrc(int newClientGeneration,
PendingIntent newMediaIntent, boolean clearing) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
if (mRcDisplays.size() > 0) {
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
while (displayIterator.hasNext()) {
@@ -1402,12 +1355,12 @@ public class MediaFocusControl implements OnFinished {
private void setNewRcClientGenerationOnClients_syncRcsCurrc(int newClientGeneration) {
// (using an iterator on the stack so we can safely remove an entry if needed,
// traversal order doesn't matter here as we update all entries)
- Iterator<MediaController> stackIterator = mMCStack.iterator();
+ Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- MediaController se = stackIterator.next();
- if ((se != null) && (se.mRcClient != null)) {
+ PlayerRecord se = stackIterator.next();
+ if ((se != null) && (se.getRcc() != null)) {
try {
- se.mRcClient.setCurrentClientGenerationId(newClientGeneration);
+ se.getRcc().setCurrentClientGenerationId(newClientGeneration);
} catch (RemoteException e) {
Log.w(TAG, "Dead client in setNewRcClientGenerationOnClients_syncRcsCurrc()",e);
stackIterator.remove();
@@ -1439,7 +1392,7 @@ public class MediaFocusControl implements OnFinished {
private void onRcDisplayClear() {
if (DEBUG_RC) Log.i(TAG, "Clear remote control display");
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
synchronized(mCurrentRcLock) {
mCurrentRcClientGen++;
// synchronously update the displays and clients with the new client generation
@@ -1452,17 +1405,17 @@ public class MediaFocusControl implements OnFinished {
/**
* Called when processing MSG_RCDISPLAY_UPDATE event
*/
- private void onRcDisplayUpdate(MediaController mcse, int flags /* USED ?*/) {
- synchronized(mMCStack) {
+ private void onRcDisplayUpdate(PlayerRecord prse, int flags /* USED ?*/) {
+ synchronized(mPRStack) {
synchronized(mCurrentRcLock) {
- if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(mcse.mRcClient))) {
+ if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(prse.getRcc()))) {
if (DEBUG_RC) Log.i(TAG, "Display/update remote control ");
mCurrentRcClientGen++;
// synchronously update the displays and clients with
// the new client generation
setNewRcClient_syncRcsCurrc(mCurrentRcClientGen,
- mcse.mMediaIntent /*newMediaIntent*/,
+ prse.getMediaButtonIntent() /*newMediaIntent*/,
false /*clearing*/);
// tell the current client that it needs to send info
@@ -1488,7 +1441,7 @@ public class MediaFocusControl implements OnFinished {
* a single RemoteControlDisplay, NOT all of them, as with MSG_RCDISPLAY_UPDATE.
*/
private void onRcDisplayInitInfo(IRemoteControlDisplay newRcd, int w, int h) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
synchronized(mCurrentRcLock) {
if (mCurrentRcClient != null) {
if (DEBUG_RC) { Log.i(TAG, "Init RCD with current info"); }
@@ -1515,7 +1468,7 @@ public class MediaFocusControl implements OnFinished {
/**
* Helper function:
- * Called synchronized on mMCStack
+ * Called synchronized on mPRStack
*/
private void clearRemoteControlDisplay_syncAfRcs() {
synchronized(mCurrentRcLock) {
@@ -1530,35 +1483,35 @@ public class MediaFocusControl implements OnFinished {
* checkUpdateRemoteControlDisplay_syncAfRcs() which checks the preconditions for
* this method.
* Preconditions:
- * - called synchronized mAudioFocusLock then on mMCStack
- * - mMCStack.isEmpty() is false
+ * - called synchronized mAudioFocusLock then on mPRStack
+ * - mPRStack.isEmpty() is false
*/
private void updateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
- MediaController mcse = mMCStack.peek();
+ PlayerRecord prse = mPRStack.peek();
int infoFlagsAboutToBeUsed = infoChangedFlags;
// this is where we enforce opt-in for information display on the remote controls
// with the new AudioManager.registerRemoteControlClient() API
- if (mcse.mRcClient == null) {
+ if (prse.getRcc() == null) {
//Log.w(TAG, "Can't update remote control display with null remote control client");
clearRemoteControlDisplay_syncAfRcs();
return;
}
synchronized(mCurrentRcLock) {
- if (!mcse.mRcClient.equals(mCurrentRcClient)) {
+ if (!prse.getRcc().equals(mCurrentRcClient)) {
// new RC client, assume every type of information shall be queried
infoFlagsAboutToBeUsed = RC_INFO_ALL;
}
- mCurrentRcClient = mcse.mRcClient;
- mCurrentRcClientIntent = mcse.mMediaIntent;
+ mCurrentRcClient = prse.getRcc();
+ mCurrentRcClientIntent = prse.getMediaButtonIntent();
}
// will cause onRcDisplayUpdate() to be called in AudioService's handler thread
mEventHandler.sendMessage( mEventHandler.obtainMessage(MSG_RCDISPLAY_UPDATE,
- infoFlagsAboutToBeUsed /* arg1 */, 0, mcse /* obj, != null */) );
+ infoFlagsAboutToBeUsed /* arg1 */, 0, prse /* obj, != null */) );
}
/**
* Helper function:
- * Called synchronized on mAudioFocusLock, then mMCStack
+ * Called synchronized on mAudioFocusLock, then mPRStack
* Check whether the remote control display should be updated, triggers the update if required
* @param infoChangedFlags the flags corresponding to the remote control client information
* that has changed, if applicable (checking for the update conditions might trigger a
@@ -1567,7 +1520,7 @@ public class MediaFocusControl implements OnFinished {
private void checkUpdateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
// determine whether the remote control display should be refreshed
// if either stack is empty, there is a mismatch, so clear the RC display
- if (mMCStack.isEmpty() || mFocusStack.isEmpty()) {
+ if (mPRStack.isEmpty() || mFocusStack.isEmpty()) {
clearRemoteControlDisplay_syncAfRcs();
return;
}
@@ -1600,19 +1553,19 @@ public class MediaFocusControl implements OnFinished {
}
// if the audio focus and RC owners belong to different packages, there is a mismatch, clear
- if (!af.hasSamePackage(mMCStack.peek().mCallingPackageName)) {
+ if (!af.hasSamePackage(mPRStack.peek().getCallingPackageName())) {
clearRemoteControlDisplay_syncAfRcs();
return;
}
// if the audio focus didn't originate from the same Uid as the one in which the remote
// control information will be retrieved, clear
- if (!af.hasSameUid(mMCStack.peek().mCallingUid)) {
+ if (!af.hasSameUid(mPRStack.peek().getCallingUid())) {
clearRemoteControlDisplay_syncAfRcs();
return;
}
// refresh conditions were verified: update the remote controls
- // ok to call: synchronized mAudioFocusLock then on mMCStack, mMCStack is not empty
+ // ok to call: synchronized mAudioFocusLock then on mPRStack, mPRStack is not empty
updateRemoteControlDisplay_syncAfRcs(infoChangedFlags);
}
@@ -1630,25 +1583,25 @@ public class MediaFocusControl implements OnFinished {
private void onPromoteRcc(int rccId) {
if (DEBUG_RC) { Log.d(TAG, "Promoting RCC " + rccId); }
synchronized(mAudioFocusLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
// ignore if given RCC ID is already at top of remote control stack
- if (!mMCStack.isEmpty() && (mMCStack.peek().mRccId == rccId)) {
+ if (!mPRStack.isEmpty() && (mPRStack.peek().getRccId() == rccId)) {
return;
}
int indexToPromote = -1;
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if (mcse.mRccId == rccId) {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if (prse.getRccId() == rccId) {
indexToPromote = index;
break;
}
}
if (indexToPromote >= 0) {
if (DEBUG_RC) { Log.d(TAG, " moving RCC from index " + indexToPromote
- + " to " + (mMCStack.size()-1)); }
- final MediaController mcse = mMCStack.remove(indexToPromote);
- mMCStack.push(mcse);
+ + " to " + (mPRStack.size()-1)); }
+ final PlayerRecord prse = mPRStack.remove(indexToPromote);
+ mPRStack.push(prse);
// the RC stack changed, reevaluate the display
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
@@ -1656,7 +1609,7 @@ public class MediaFocusControl implements OnFinished {
// not expected to happen, indicates improper concurrent modification
Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
}
- }//synchronized(mMCStack)
+ }//synchronized(mPRStack)
}//synchronized(mAudioFocusLock)
}
@@ -1669,7 +1622,7 @@ public class MediaFocusControl implements OnFinished {
Log.i(TAG, " Remote Control registerMediaButtonIntent() for " + mediaIntent);
synchronized(mAudioFocusLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
if (pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token)) {
// new RC client, assume every type of information shall be queried
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
@@ -1687,7 +1640,7 @@ public class MediaFocusControl implements OnFinished {
Log.i(TAG, " Remote Control unregisterMediaButtonIntent() for " + mediaIntent);
synchronized(mAudioFocusLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
boolean topOfStackWillChange = isCurrentRcController(mediaIntent);
removeMediaButtonReceiver_syncAfRcs(mediaIntent);
if (topOfStackWillChange) {
@@ -1698,6 +1651,12 @@ public class MediaFocusControl implements OnFinished {
}
}
+ protected void unregisterMediaButtonIntentAsync(final PendingIntent mediaIntent) {
+ mEventHandler.sendMessage(
+ mEventHandler.obtainMessage(MSG_UNREGISTER_MEDIABUTTONINTENT, 0, 0,
+ mediaIntent));
+ }
+
/**
* see AudioManager.registerMediaButtonEventReceiverForCalls(ComponentName c)
* precondition: c != null
@@ -1708,7 +1667,7 @@ public class MediaFocusControl implements OnFinished {
Log.e(TAG, "Invalid permissions to register media button receiver for calls");
return;
}
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
mMediaReceiverForCalls = c;
}
}
@@ -1722,14 +1681,14 @@ public class MediaFocusControl implements OnFinished {
Log.e(TAG, "Invalid permissions to unregister media button receiver for calls");
return;
}
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
mMediaReceiverForCalls = null;
}
}
/**
* see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...)
- * @return the unique ID of the MediaController associated with the RemoteControlClient
+ * @return the unique ID of the PlayerRecord associated with the RemoteControlClient
* Note: using this method with rcClient == null is a way to "disable" the IRemoteControlClient
* without modifying the RC stack, but while still causing the display to refresh (will
* become blank as a result of this)
@@ -1739,45 +1698,26 @@ public class MediaFocusControl implements OnFinished {
if (DEBUG_RC) Log.i(TAG, "Register remote control client rcClient="+rcClient);
int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
synchronized(mAudioFocusLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
// store the new display information
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if(mcse.mMediaIntent.equals(mediaIntent)) {
- // already had a remote control client?
- if (mcse.mRcClientDeathHandler != null) {
- // stop monitoring the old client's death
- mcse.unlinkToRcClientDeath();
- }
- // save the new remote control client
- mcse.mRcClient = rcClient;
- mcse.mCallingPackageName = callingPackageName;
- mcse.mCallingUid = Binder.getCallingUid();
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if(prse.hasMatchingMediaButtonIntent(mediaIntent)) {
+ prse.resetControllerInfoForRcc(rcClient, callingPackageName,
+ Binder.getCallingUid());
+
if (rcClient == null) {
- // here mcse.mRcClientDeathHandler is null;
- mcse.resetPlaybackInfo();
break;
}
- rccId = mcse.mRccId;
+
+ rccId = prse.getRccId();
// there is a new (non-null) client:
- // 1/ give the new client the displays (if any)
+ // give the new client the displays (if any)
if (mRcDisplays.size() > 0) {
- plugRemoteControlDisplaysIntoClient_syncRcStack(mcse.mRcClient);
- }
- // 2/ monitor the new client's death
- IBinder b = mcse.mRcClient.asBinder();
- RcClientDeathHandler rcdh =
- new RcClientDeathHandler(b, mcse.mMediaIntent);
- try {
- b.linkToDeath(rcdh, 0);
- } catch (RemoteException e) {
- // remote control client is DOA, disqualify it
- Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
- mcse.mRcClient = null;
+ plugRemoteControlDisplaysIntoClient_syncRcStack(prse.getRcc());
}
- mcse.mRcClientDeathHandler = rcdh;
break;
}
}//for
@@ -1791,7 +1731,7 @@ public class MediaFocusControl implements OnFinished {
if (isCurrentRcController(mediaIntent)) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
- }//synchronized(mMCStack)
+ }//synchronized(mPRStack)
}//synchronized(mAudioFocusLock)
return rccId;
}
@@ -1804,20 +1744,16 @@ public class MediaFocusControl implements OnFinished {
IRemoteControlClient rcClient) {
if (DEBUG_RC) Log.i(TAG, "Unregister remote control client rcClient="+rcClient);
synchronized(mAudioFocusLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
boolean topRccChange = false;
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if ((mcse.mMediaIntent.equals(mediaIntent))
- && rcClient.equals(mcse.mRcClient)) {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if ((prse.hasMatchingMediaButtonIntent(mediaIntent))
+ && rcClient.equals(prse.getRcc())) {
// we found the IRemoteControlClient to unregister
- // stop monitoring its death
- mcse.unlinkToRcClientDeath();
- // reset the client-related fields
- mcse.mRcClient = null;
- mcse.mCallingPackageName = null;
- topRccChange = (index == mMCStack.size()-1);
+ prse.resetControllerInfoForNoRcc();
+ topRccChange = (index == mPRStack.size()-1);
// there can only be one matching RCC in the RC stack, we're done
break;
}
@@ -1881,7 +1817,7 @@ public class MediaFocusControl implements OnFinished {
}
public void binderDied() {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
Log.w(TAG, "RemoteControl: display " + mRcDisplay + " died");
// remove the display from the list
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
@@ -1899,7 +1835,7 @@ public class MediaFocusControl implements OnFinished {
/**
* The remote control displays.
- * Access synchronized on mMCStack
+ * Access synchronized on mPRStack
*/
private ArrayList<DisplayInfoForServer> mRcDisplays = new ArrayList<DisplayInfoForServer>(1);
@@ -1927,12 +1863,12 @@ public class MediaFocusControl implements OnFinished {
boolean enabled) {
// let all the remote control clients know whether the given display is enabled
// (so the remote control stack traversal order doesn't matter).
- final Iterator<MediaController> stackIterator = mMCStack.iterator();
+ final Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- MediaController mcse = stackIterator.next();
- if(mcse.mRcClient != null) {
+ PlayerRecord prse = stackIterator.next();
+ if(prse.getRcc() != null) {
try {
- mcse.mRcClient.enableRemoteControlDisplay(rcd, enabled);
+ prse.getRcc().enableRemoteControlDisplay(rcd, enabled);
} catch (RemoteException e) {
Log.e(TAG, "Error connecting RCD to client: ", e);
}
@@ -1973,7 +1909,7 @@ public class MediaFocusControl implements OnFinished {
ComponentName listenerComp) {
if (DEBUG_RC) Log.d(TAG, ">>> registerRemoteControlDisplay("+rcd+")");
synchronized(mAudioFocusLock) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
if ((rcd == null) || rcDisplayIsPluggedIn_syncRcStack(rcd)) {
return;
}
@@ -1989,12 +1925,12 @@ public class MediaFocusControl implements OnFinished {
// let all the remote control clients know there is a new display (so the remote
// control stack traversal order doesn't matter).
- Iterator<MediaController> stackIterator = mMCStack.iterator();
+ Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- MediaController mcse = stackIterator.next();
- if(mcse.mRcClient != null) {
+ PlayerRecord prse = stackIterator.next();
+ if(prse.getRcc() != null) {
try {
- mcse.mRcClient.plugRemoteControlDisplay(rcd, w, h);
+ prse.getRcc().plugRemoteControlDisplay(rcd, w, h);
} catch (RemoteException e) {
Log.e(TAG, "Error connecting RCD to client: ", e);
}
@@ -2019,7 +1955,7 @@ public class MediaFocusControl implements OnFinished {
*/
protected void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) {
if (DEBUG_RC) Log.d(TAG, "<<< unregisterRemoteControlDisplay("+rcd+")");
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
if (rcd == null) {
return;
}
@@ -2038,12 +1974,12 @@ public class MediaFocusControl implements OnFinished {
if (displayWasPluggedIn) {
// disconnect this remote control display from all the clients, so the remote
// control stack traversal order doesn't matter
- final Iterator<MediaController> stackIterator = mMCStack.iterator();
+ final Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- final MediaController mcse = stackIterator.next();
- if(mcse.mRcClient != null) {
+ final PlayerRecord prse = stackIterator.next();
+ if(prse.getRcc() != null) {
try {
- mcse.mRcClient.unplugRemoteControlDisplay(rcd);
+ prse.getRcc().unplugRemoteControlDisplay(rcd);
} catch (RemoteException e) {
Log.e(TAG, "Error disconnecting remote control display to client: ", e);
}
@@ -2065,7 +2001,7 @@ public class MediaFocusControl implements OnFinished {
* display doesn't need to receive artwork.
*/
protected void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
boolean artworkSizeUpdate = false;
while (displayIterator.hasNext() && !artworkSizeUpdate) {
@@ -2081,12 +2017,12 @@ public class MediaFocusControl implements OnFinished {
if (artworkSizeUpdate) {
// RCD is currently plugged in and its artwork size has changed, notify all RCCs,
// stack traversal order doesn't matter
- final Iterator<MediaController> stackIterator = mMCStack.iterator();
+ final Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- final MediaController mcse = stackIterator.next();
- if(mcse.mRcClient != null) {
+ final PlayerRecord prse = stackIterator.next();
+ if(prse.getRcc() != null) {
try {
- mcse.mRcClient.setBitmapSizeForDisplay(rcd, w, h);
+ prse.getRcc().setBitmapSizeForDisplay(rcd, w, h);
} catch (RemoteException e) {
Log.e(TAG, "Error setting bitmap size for RCD on RCC: ", e);
}
@@ -2110,7 +2046,7 @@ public class MediaFocusControl implements OnFinished {
*/
protected void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd,
boolean wantsSync) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
boolean rcdRegistered = false;
// store the information about this display
// (display stack traversal order doesn't matter).
@@ -2128,12 +2064,12 @@ public class MediaFocusControl implements OnFinished {
}
// notify all current RemoteControlClients
// (stack traversal order doesn't matter as we notify all RCCs)
- final Iterator<MediaController> stackIterator = mMCStack.iterator();
+ final Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while (stackIterator.hasNext()) {
- final MediaController mcse = stackIterator.next();
- if (mcse.mRcClient != null) {
+ final PlayerRecord prse = stackIterator.next();
+ if (prse.getRcc() != null) {
try {
- mcse.mRcClient.setWantsSyncForDisplay(rcd, wantsSync);
+ prse.getRcc().setWantsSyncForDisplay(rcd, wantsSync);
} catch (RemoteException e) {
Log.e(TAG, "Error setting position sync flag for RCD on RCC: ", e);
}
@@ -2144,7 +2080,7 @@ public class MediaFocusControl implements OnFinished {
protected void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
// ignore position change requests if invalid generation ID
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
synchronized(mCurrentRcLock) {
if (mCurrentRcClientGen != generationId) {
return;
@@ -2159,7 +2095,7 @@ public class MediaFocusControl implements OnFinished {
private void onSetRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
if(DEBUG_RC) Log.d(TAG, "onSetRemoteControlClientPlaybackPosition(genId=" + generationId +
", timeMs=" + timeMs + ")");
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
synchronized(mCurrentRcLock) {
if ((mCurrentRcClient != null) && (mCurrentRcClientGen == generationId)) {
// tell the current client to seek to the requested location
@@ -2182,7 +2118,7 @@ public class MediaFocusControl implements OnFinished {
private void onUpdateRemoteControlClientMetadata(int genId, int key, Rating value) {
if(DEBUG_RC) Log.d(TAG, "onUpdateRemoteControlClientMetadata(genId=" + genId +
", what=" + key + ",rating=" + value + ")");
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
synchronized(mCurrentRcLock) {
if ((mCurrentRcClient != null) && (mCurrentRcClientGen == genId)) {
try {
@@ -2213,20 +2149,20 @@ public class MediaFocusControl implements OnFinished {
private void onNewPlaybackInfoForRcc(int rccId, int key, int value) {
if(DEBUG_RC) Log.d(TAG, "onNewPlaybackInfoForRcc(id=" + rccId +
", what=" + key + ",val=" + value + ")");
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
// iterating from top of stack as playback information changes are more likely
// on entries at the top of the remote control stack
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if (mcse.mRccId == rccId) {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if (prse.getRccId() == rccId) {
switch (key) {
case RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE:
- mcse.mPlaybackType = value;
+ prse.mPlaybackType = value;
postReevaluateRemote();
break;
case RemoteControlClient.PLAYBACKINFO_VOLUME:
- mcse.mPlaybackVolume = value;
+ prse.mPlaybackVolume = value;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolume = value;
@@ -2235,7 +2171,7 @@ public class MediaFocusControl implements OnFinished {
}
break;
case RemoteControlClient.PLAYBACKINFO_VOLUME_MAX:
- mcse.mPlaybackVolumeMax = value;
+ prse.mPlaybackVolumeMax = value;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolumeMax = value;
@@ -2244,7 +2180,7 @@ public class MediaFocusControl implements OnFinished {
}
break;
case RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING:
- mcse.mPlaybackVolumeHandling = value;
+ prse.mPlaybackVolumeHandling = value;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemote.mVolumeHandling = value;
@@ -2253,7 +2189,7 @@ public class MediaFocusControl implements OnFinished {
}
break;
case RemoteControlClient.PLAYBACKINFO_USES_STREAM:
- mcse.mPlaybackStream = value;
+ prse.mPlaybackStream = value;
break;
default:
Log.e(TAG, "unhandled key " + key + " for RCC " + rccId);
@@ -2264,7 +2200,7 @@ public class MediaFocusControl implements OnFinished {
}//for
} catch (ArrayIndexOutOfBoundsException e) {
// not expected to happen, indicates improper concurrent modification
- Log.e(TAG, "Wrong index mMCStack on onNewPlaybackInfoForRcc, lock error? ", e);
+ Log.e(TAG, "Wrong index mPRStack on onNewPlaybackInfoForRcc, lock error? ", e);
}
}
}
@@ -2272,21 +2208,21 @@ public class MediaFocusControl implements OnFinished {
protected void setPlaybackStateForRcc(int rccId, int state, long timeMs, float speed) {
sendMsg(mEventHandler, MSG_RCC_NEW_PLAYBACK_STATE, SENDMSG_QUEUE,
rccId /* arg1 */, state /* arg2 */,
- new MediaController.RccPlaybackState(state, timeMs, speed) /* obj */, 0 /* delay */);
+ new PlayerRecord.RccPlaybackState(state, timeMs, speed) /* obj */, 0 /* delay */);
}
private void onNewPlaybackStateForRcc(int rccId, int state,
- MediaController.RccPlaybackState newState) {
+ PlayerRecord.RccPlaybackState newState) {
if(DEBUG_RC) Log.d(TAG, "onNewPlaybackStateForRcc(id=" + rccId + ", state=" + state
+ ", time=" + newState.mPositionMs + ", speed=" + newState.mSpeed + ")");
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
// iterating from top of stack as playback information changes are more likely
// on entries at the top of the remote control stack
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if (mcse.mRccId == rccId) {
- mcse.mPlaybackState = newState;
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if (prse.getRccId() == rccId) {
+ prse.mPlaybackState = newState;
synchronized (mMainRemote) {
if (rccId == mMainRemote.mRccId) {
mMainRemoteIsActive = isPlaystateActive(state);
@@ -2303,7 +2239,7 @@ public class MediaFocusControl implements OnFinished {
}//for
} catch (ArrayIndexOutOfBoundsException e) {
// not expected to happen, indicates improper concurrent modification
- Log.e(TAG, "Wrong index on mMCStack in onNewPlaybackStateForRcc, lock error? ", e);
+ Log.e(TAG, "Wrong index on mPRStack in onNewPlaybackStateForRcc, lock error? ", e);
}
}
}
@@ -2315,15 +2251,15 @@ public class MediaFocusControl implements OnFinished {
// handler for MSG_RCC_NEW_VOLUME_OBS
private void onRegisterVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
// The stack traversal order doesn't matter because there is only one stack entry
// with this RCC ID, but the matching ID is more likely at the top of the stack, so
// start iterating from the top.
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if (mcse.mRccId == rccId) {
- mcse.mRemoteVolumeObs = rvo;
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if (prse.getRccId() == rccId) {
+ prse.mRemoteVolumeObs = rvo;
break;
}
}
@@ -2341,21 +2277,21 @@ public class MediaFocusControl implements OnFinished {
* @return false if no remote playing is currently playing
*/
protected boolean checkUpdateRemoteStateIfActive(int streamType) {
- synchronized(mMCStack) {
+ synchronized(mPRStack) {
// iterating from top of stack as active playback is more likely on entries at the top
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
- if ((mcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE)
- && isPlaystateActive(mcse.mPlaybackState.mState)
- && (mcse.mPlaybackStream == streamType)) {
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
+ if ((prse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE)
+ && isPlaystateActive(prse.mPlaybackState.mState)
+ && (prse.mPlaybackStream == streamType)) {
if (DEBUG_RC) Log.d(TAG, "remote playback active on stream " + streamType
- + ", vol =" + mcse.mPlaybackVolume);
+ + ", vol =" + prse.mPlaybackVolume);
synchronized (mMainRemote) {
- mMainRemote.mRccId = mcse.mRccId;
- mMainRemote.mVolume = mcse.mPlaybackVolume;
- mMainRemote.mVolumeMax = mcse.mPlaybackVolumeMax;
- mMainRemote.mVolumeHandling = mcse.mPlaybackVolumeHandling;
+ mMainRemote.mRccId = prse.getRccId();
+ mMainRemote.mVolume = prse.mPlaybackVolume;
+ mMainRemote.mVolumeMax = prse.mPlaybackVolumeMax;
+ mMainRemote.mVolumeHandling = prse.mPlaybackVolumeHandling;
mMainRemoteIsActive = true;
}
return true;
@@ -2422,16 +2358,16 @@ public class MediaFocusControl implements OnFinished {
return;
}
IRemoteVolumeObserver rvo = null;
- synchronized (mMCStack) {
+ synchronized (mPRStack) {
// The stack traversal order doesn't matter because there is only one stack entry
// with this RCC ID, but the matching ID is more likely at the top of the stack, so
// start iterating from the top.
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
//FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
- if (mcse.mRccId == rccId) {
- rvo = mcse.mRemoteVolumeObs;
+ if (prse.getRccId() == rccId) {
+ rvo = prse.mRemoteVolumeObs;
break;
}
}
@@ -2477,16 +2413,16 @@ public class MediaFocusControl implements OnFinished {
rccId = mMainRemote.mRccId;
}
IRemoteVolumeObserver rvo = null;
- synchronized (mMCStack) {
+ synchronized (mPRStack) {
// The stack traversal order doesn't matter because there is only one stack entry
// with this RCC ID, but the matching ID is more likely at the top of the stack, so
// start iterating from the top.
try {
- for (int index = mMCStack.size()-1; index >= 0; index--) {
- final MediaController mcse = mMCStack.elementAt(index);
+ for (int index = mPRStack.size()-1; index >= 0; index--) {
+ final PlayerRecord prse = mPRStack.elementAt(index);
//FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
- if (mcse.mRccId == rccId) {
- rvo = mcse.mRemoteVolumeObs;
+ if (prse.getRccId() == rccId) {
+ rvo = prse.mRemoteVolumeObs;
break;
}
}
@@ -2509,7 +2445,7 @@ public class MediaFocusControl implements OnFinished {
* have their volume controlled. In this implementation this is only to reset whether
* VolumePanel should display remote volumes
*/
- private void postReevaluateRemote() {
+ protected void postReevaluateRemote() {
sendMsg(mEventHandler, MSG_REEVALUATE_REMOTE, SENDMSG_QUEUE, 0, 0, null, 0);
}
@@ -2517,13 +2453,13 @@ public class MediaFocusControl implements OnFinished {
if (DEBUG_VOL) { Log.w(TAG, "onReevaluateRemote()"); }
// is there a registered RemoteControlClient that is handling remote playback
boolean hasRemotePlayback = false;
- synchronized (mMCStack) {
+ synchronized (mPRStack) {
// iteration stops when PLAYBACK_TYPE_REMOTE is found, so remote control stack
// traversal order doesn't matter
- Iterator<MediaController> stackIterator = mMCStack.iterator();
+ Iterator<PlayerRecord> stackIterator = mPRStack.iterator();
while(stackIterator.hasNext()) {
- MediaController mcse = stackIterator.next();
- if (mcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE) {
+ PlayerRecord prse = stackIterator.next();
+ if (prse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE) {
hasRemotePlayback = true;
break;
}
diff --git a/media/java/android/media/MediaController.java b/media/java/android/media/PlayerRecord.java
index 6e3a9b3..a79b0ed 100644
--- a/media/java/android/media/MediaController.java
+++ b/media/java/android/media/PlayerRecord.java
@@ -18,7 +18,7 @@ package android.media;
import android.app.PendingIntent;
import android.content.ComponentName;
-import android.media.MediaFocusControl.RcClientDeathHandler;
+import android.os.Binder;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
@@ -33,7 +33,7 @@ import java.io.PrintWriter;
* instance is managed by android.media.MediaFocusControl, from its addition to the player stack
* stack to its release.
*/
-class MediaController implements DeathRecipient {
+class PlayerRecord implements DeathRecipient {
// on purpose not using this classe's name, as it will only be used from MediaFocusControl
private static final String TAG = "MediaFocusControl";
@@ -44,34 +44,33 @@ class MediaController implements DeathRecipient {
*/
private static int sLastRccId = 0;
- //FIXME should be final static
- public MediaFocusControl mController;
+ public static MediaFocusControl sController;
/**
* The target for the ACTION_MEDIA_BUTTON events.
- * Always non null.
+ * Always non null. //FIXME verify
*/
- final public PendingIntent mMediaIntent;
+ final private PendingIntent mMediaIntent;
/**
* The registered media button event receiver.
- * Always non null.
*/
- final public ComponentName mReceiverComponent;
+ final private ComponentName mReceiverComponent;
- public int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
+ private int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
- public IBinder mToken;
- public String mCallingPackageName;
- public int mCallingUid;
+ private IBinder mToken;
+ private String mCallingPackageName;
+ private int mCallingUid;
/**
* Provides access to the information to display on the remote control.
* May be null (when a media button event receiver is registered,
* but no remote control client has been registered) */
- public IRemoteControlClient mRcClient;
- public RcClientDeathHandler mRcClientDeathHandler;
+ private IRemoteControlClient mRcClient;
+ private RcClientDeathHandler mRcClientDeathHandler;
/**
* Information only used for non-local playback
*/
+ //FIXME private?
public int mPlaybackType;
public int mPlaybackVolume;
public int mPlaybackVolumeMax;
@@ -142,24 +141,80 @@ class MediaController implements DeathRecipient {
}
- void dump(PrintWriter pw) {
- // FIXME to implement, remove dump from MediaFocusControl that accesses private members
+ /**
+ * Inner class to monitor remote control client deaths, and remove the client for the
+ * remote control stack if necessary.
+ */
+ private class RcClientDeathHandler implements IBinder.DeathRecipient {
+ final private IBinder mCb; // To be notified of client's death
+ //FIXME needed?
+ final private PendingIntent mMediaIntent;
+
+ RcClientDeathHandler(IBinder cb, PendingIntent pi) {
+ mCb = cb;
+ mMediaIntent = pi;
+ }
+
+ public void binderDied() {
+ Log.w(TAG, " RemoteControlClient died");
+ // remote control client died, make sure the displays don't use it anymore
+ // by setting its remote control client to null
+ sController.registerRemoteControlClient(mMediaIntent, null/*rcClient*/, null/*ignored*/);
+ // the dead client was maybe handling remote playback, the controller should reevaluate
+ sController.postReevaluateRemote();
+ }
+
+ public IBinder getBinder() {
+ return mCb;
+ }
}
- public void resetPlaybackInfo() {
- mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
- mPlaybackVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
- mPlaybackVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
- mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
- mPlaybackStream = AudioManager.STREAM_MUSIC;
- mPlaybackState.reset();
- mRemoteVolumeObs = null;
+
+ protected static class RemotePlaybackState {
+ int mRccId;
+ int mVolume;
+ int mVolumeMax;
+ int mVolumeHandling;
+
+ protected RemotePlaybackState(int id, int vol, int volMax) {
+ mRccId = id;
+ mVolume = vol;
+ mVolumeMax = volMax;
+ mVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
+ }
+ }
+
+
+ void dump(PrintWriter pw, boolean registrationInfo) {
+ if (registrationInfo) {
+ pw.println(" pi: " + mMediaIntent +
+ " -- pack: " + mCallingPackageName +
+ " -- ercvr: " + mReceiverComponent +
+ " -- client: " + mRcClient +
+ " -- uid: " + mCallingUid +
+ " -- type: " + mPlaybackType +
+ " state: " + mPlaybackState);
+ } else {
+ // emphasis on state
+ pw.println(" uid: " + mCallingUid +
+ " -- id: " + mRccId +
+ " -- type: " + mPlaybackType +
+ " -- state: " + mPlaybackState +
+ " -- vol handling: " + mPlaybackVolumeHandling +
+ " -- vol: " + mPlaybackVolume +
+ " -- volMax: " + mPlaybackVolumeMax +
+ " -- volObs: " + mRemoteVolumeObs);
+ }
+ }
+
+
+ static protected void setMediaFocusControl(MediaFocusControl mfc) {
+ sController = mfc;
}
/** precondition: mediaIntent != null */
- public MediaController(MediaFocusControl controller, PendingIntent mediaIntent,
- ComponentName eventReceiver, IBinder token) {
- mController = controller;
+ protected PlayerRecord(PendingIntent mediaIntent, ComponentName eventReceiver, IBinder token)
+ {
mMediaIntent = mediaIntent;
mReceiverComponent = eventReceiver;
mToken = token;
@@ -176,16 +231,95 @@ class MediaController implements DeathRecipient {
try {
mToken.linkToDeath(this, 0);
} catch (RemoteException e) {
- //FIXME do not access the event handler directly
- mController.mEventHandler.post(new Runnable() {
- @Override public void run() {
- mController.unregisterMediaButtonIntent(mMediaIntent);
- }
- });
+ sController.unregisterMediaButtonIntentAsync(mMediaIntent);
}
}
}
+ //---------------------------------------------
+ // Accessors
+ protected int getRccId() {
+ return mRccId;
+ }
+
+ protected IRemoteControlClient getRcc() {
+ return mRcClient;
+ }
+
+ protected ComponentName getMediaButtonReceiver() {
+ return mReceiverComponent;
+ }
+
+ protected PendingIntent getMediaButtonIntent() {
+ return mMediaIntent;
+ }
+
+ // FIXME this is only used when comparing with the audio focus owner calling package name,
+ // accessor to be removed once audio focus and media button owner are dissociated
+ protected String getCallingPackageName() {
+ return mCallingPackageName;
+ }
+
+ // FIXME this is only used when comparing with the audio focus owner calling package name,
+ // accessor to be removed once audio focus and media button owner are dissociated
+ protected int getCallingUid() {
+ return mCallingUid;
+ }
+
+ protected boolean hasMatchingMediaButtonIntent(PendingIntent pi) {
+ return mMediaIntent.equals(pi);
+ }
+
+ //---------------------------------------------
+ // Modify the records stored in the instance
+ protected void resetControllerInfoForRcc(IRemoteControlClient rcClient,
+ String callingPackageName, int uid) {
+ // already had a remote control client?
+ if (mRcClientDeathHandler != null) {
+ // stop monitoring the old client's death
+ unlinkToRcClientDeath();
+ }
+ // save the new remote control client
+ mRcClient = rcClient;
+ mCallingPackageName = callingPackageName;
+ mCallingUid = uid;
+ if (rcClient == null) {
+ // here mcse.mRcClientDeathHandler is null;
+ resetPlaybackInfo();
+ } else {
+ IBinder b = mRcClient.asBinder();
+ RcClientDeathHandler rcdh =
+ new RcClientDeathHandler(b, mMediaIntent);
+ try {
+ b.linkToDeath(rcdh, 0);
+ } catch (RemoteException e) {
+ // remote control client is DOA, disqualify it
+ Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
+ mRcClient = null;
+ }
+ mRcClientDeathHandler = rcdh;
+ }
+ }
+
+ protected void resetControllerInfoForNoRcc() {
+ // stop monitoring the RCC death
+ unlinkToRcClientDeath();
+ // reset the RCC-related fields
+ mRcClient = null;
+ mCallingPackageName = null;
+ }
+
+ public void resetPlaybackInfo() {
+ mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
+ mPlaybackVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+ mPlaybackVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+ mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
+ mPlaybackStream = AudioManager.STREAM_MUSIC;
+ mPlaybackState.reset();
+ mRemoteVolumeObs = null;
+ }
+
+ //---------------------------------------------
public void unlinkToRcClientDeath() {
if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
try {
@@ -209,7 +343,7 @@ class MediaController implements DeathRecipient {
@Override
public void binderDied() {
- mController.unregisterMediaButtonIntent(mMediaIntent);
+ sController.unregisterMediaButtonIntentAsync(mMediaIntent);
}
@Override
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 15ae238..fce3fd0 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -202,12 +202,17 @@ public class MtpDatabase {
public void setServer(MtpServer server) {
mServer = server;
+ // always unregister before registering
+ try {
+ mContext.unregisterReceiver(mBatteryReceiver);
+ } catch (IllegalArgumentException e) {
+ // wasn't previously registered, ignore
+ }
+
// register for battery notifications when we are connected
if (server != null) {
mContext.registerReceiver(mBatteryReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
- } else {
- mContext.unregisterReceiver(mBatteryReceiver);
}
}
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 82c6a80..0e55228 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -17,11 +17,12 @@
#define LOG_TAG "MtpDatabaseJNI"
#include "utils/Log.h"
-#include <stdio.h>
#include <assert.h>
+#include <fcntl.h>
+#include <inttypes.h>
#include <limits.h>
+#include <stdio.h>
#include <unistd.h>
-#include <fcntl.h>
#include "jni.h"
#include "JNIHelp.h"
@@ -393,7 +394,7 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
// release date is stored internally as just the year
if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
char date[20];
- snprintf(date, sizeof(date), "%04lld0101T000000", longValue);
+ snprintf(date, sizeof(date), "%04" PRId64 "0101T000000", longValue);
packet.putString(date);
goto out;
}
@@ -657,7 +658,7 @@ MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property
return result;
}
-MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
+MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) {
return -1;
}
@@ -1151,7 +1152,7 @@ android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
}
static jstring
-android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
+android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject /*thiz*/, jlong seconds)
{
char date[20];
formatDateTime(seconds, date, sizeof(date));
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index 3fc562c..31e806c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -979,13 +979,6 @@ public class KeyguardViewMediator {
return;
}
- if (mLockPatternUtils.checkVoldPassword()) {
- if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
- // Without this, settings is not enabled until the lock screen first appears
- hideLocked();
- return;
- }
-
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
showLocked(options);
}
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 1693e01..1da66bb 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -92,6 +92,12 @@
systemui:rowHeight="@dimen/notification_row_min_height"
/>
</ScrollView>
+
+ <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
+ android:id="@+id/notification_stack_scroller"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
</FrameLayout>
</LinearLayout>
</com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index ab71371..76e7784 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -40,4 +40,7 @@
<!-- The fixed height of each tile -->
<dimen name="quick_settings_cell_height">100dp</dimen>
+
+ <!-- Width of the zen mode interstitial dialog. -->
+ <dimen name="zen_mode_dialog_width">384dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index ad4dcf9..45f6af3 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -51,4 +51,7 @@
<!-- How far to slide the panel out when you touch it -->
<!-- On tablets this is just the close_handle_height -->
<dimen name="peek_height">@dimen/close_handle_height</dimen>
+
+ <!-- Width of the zen mode interstitial dialog. -->
+ <dimen name="zen_mode_dialog_width">384dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index a59dc75..5cf0453 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -39,8 +39,6 @@
<color name="status_bar_clock_color">#FFFFFFFF</color>
<drawable name="notification_item_background_color">#ff111111</drawable>
<drawable name="notification_item_background_color_pressed">#ff454545</drawable>
- <color name="notification_icon_legacy_bg_color">#ff4285F4</color>
- <color name="notification_action_legacy_color_filter">#ff555555</color>
<!-- Tint color for inactive Quick Settings icons. -->
<color name="ic_qs_off">#ff404040</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f4bfd10..a9b6985 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -232,4 +232,22 @@
<!-- The size of the icon in the recents task view. -->
<dimen name="recents_task_view_icon_size">60dp</dimen>
+
+ <!-- Space below the notification stack -->
+ <dimen name="notification_stack_margin_bottom">0dp</dimen>
+
+ <!-- Space reserved for the cards behind the top card in the top stack -->
+ <dimen name="top_stack_peek_amount">24dp</dimen>
+
+ <!-- Space reserved for the cards behind the top card in the bottom stack -->
+ <dimen name="bottom_stack_peek_amount">18dp</dimen>
+
+ <!-- The side padding of the notifications-->
+ <dimen name="notification_side_padding">8dp</dimen>
+
+ <!-- Z distance between notifications if they are in the stack -->
+ <dimen name="z_distance_between_notifications">2dp</dimen>
+
+ <!-- Width of the zen mode interstitial dialog. Defaults to MATCH_PARENT. -->
+ <dimen name="zen_mode_dialog_width">-1px</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 68c8364..bad5641 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -29,14 +29,9 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.database.ContentObserver;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
@@ -46,20 +41,17 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
-import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.IWindowManager;
import android.view.LayoutInflater;
@@ -70,7 +62,6 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
-import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
@@ -80,18 +71,16 @@ import android.widget.TextView;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.util.LegacyNotificationUtil;
import com.android.internal.widget.SizeAdaptiveLayout;
-import com.android.systemui.ImageUtils;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SearchPanelView;
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
-import com.android.systemui.statusbar.policy.NotificationRowLayout;
import java.util.ArrayList;
import java.util.Locale;
-import java.util.Stack;
public abstract class BaseStatusBar extends SystemUI implements
CommandQueue.Callbacks {
@@ -109,6 +98,8 @@ public abstract class BaseStatusBar extends SystemUI implements
protected static final int MSG_HIDE_HEADS_UP = 1027;
protected static final int MSG_ESCALATE_HEADS_UP = 1028;
+ public static final boolean ENABLE_NOTIFICATION_STACK = SystemProperties
+ .getBoolean("persist.notifications.use_stack", false);
protected static final boolean ENABLE_HEADS_UP = true;
// scores above this threshold should be displayed in heads up mode.
protected static final int INTERRUPTION_THRESHOLD = 10;
@@ -129,7 +120,7 @@ public abstract class BaseStatusBar extends SystemUI implements
// all notifications
protected NotificationData mNotificationData = new NotificationData();
- protected NotificationRowLayout mPile;
+ protected ViewGroup mPile;
protected NotificationData.Entry mInterruptingNotificationEntry;
protected long mInterruptingNotificationTime;
@@ -157,8 +148,7 @@ public abstract class BaseStatusBar extends SystemUI implements
// public mode, private notifications, etc
private boolean mLockscreenPublicMode = false;
private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
- private Context mLightThemeContext;
- private ImageUtils mImageUtils = new ImageUtils();
+ private LegacyNotificationUtil mLegacyNotificationUtil = LegacyNotificationUtil.getInstance();
private UserManager mUserManager;
@@ -296,8 +286,6 @@ public abstract class BaseStatusBar extends SystemUI implements
true,
mLockscreenSettingsObserver,
UserHandle.USER_ALL);
- mLightThemeContext = new RemoteViewsThemeContextWrapper(mContext,
- android.R.style.Theme_Holo_Light);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -458,158 +446,6 @@ public abstract class BaseStatusBar extends SystemUI implements
}
}
- private void processLegacyHoloNotification(StatusBarNotification sbn, View content) {
-
- // TODO: Also skip processing if it is a holo-style notification.
- // If the notification is custom, we can't process it.
- if (!sbn.getNotification().extras.getBoolean(Notification.EXTRA_BUILDER_REMOTE_VIEWS)) {
- return;
- }
-
- processLegacyHoloLargeIcon(content);
- processLegacyHoloActions(content);
- processLegacyNotificationIcon(content);
- processLegacyTextViews(content);
- }
-
- /**
- * @return the context to be used for the inflation of the specified {@code sbn}; this is
- * dependent whether the notification is quantum-style or holo-style
- */
- private Context getInflationContext(StatusBarNotification sbn) {
-
- // TODO: Adjust this logic when we change the theme of the status bar windows.
- if (sbn.getNotification().extras.getBoolean(Notification.EXTRA_BUILDER_REMOTE_VIEWS)) {
- return mLightThemeContext;
- } else {
- return mContext;
- }
- }
-
- private void processLegacyNotificationIcon(View content) {
- View v = content.findViewById(com.android.internal.R.id.right_icon);
- if (v != null & v instanceof ImageView) {
- ImageView iv = (ImageView) v;
- Drawable d = iv.getDrawable();
- if (isMonochrome(d)) {
- d.mutate();
- d.setColorFilter(mLightThemeContext.getResources().getColor(
- R.color.notification_action_legacy_color_filter), PorterDuff.Mode.MULTIPLY);
- }
- }
- }
-
- private void processLegacyHoloLargeIcon(View content) {
- View v = content.findViewById(com.android.internal.R.id.icon);
- if (v != null & v instanceof ImageView) {
- ImageView iv = (ImageView) v;
- if (isMonochrome(iv.getDrawable())) {
- iv.setBackground(mLightThemeContext.getResources().getDrawable(
- R.drawable.notification_icon_legacy_bg_inset));
- }
- }
- }
-
- private boolean isMonochrome(Drawable d) {
- if (d == null) {
- return false;
- } else if (d instanceof BitmapDrawable) {
- BitmapDrawable bd = (BitmapDrawable) d;
- return bd.getBitmap() != null && mImageUtils.isGrayscale(bd.getBitmap());
- } else if (d instanceof AnimationDrawable) {
- AnimationDrawable ad = (AnimationDrawable) d;
- int count = ad.getNumberOfFrames();
- return count > 0 && isMonochrome(ad.getFrame(0));
- } else {
- return false;
- }
- }
-
- private void processLegacyHoloActions(View content) {
- View v = content.findViewById(com.android.internal.R.id.actions);
- if (v != null & v instanceof ViewGroup) {
- ViewGroup vg = (ViewGroup) v;
- int childCount = vg.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = vg.getChildAt(i);
- if (child instanceof Button) {
- Button button = (Button) child;
- Drawable[] compoundDrawables = button.getCompoundDrawablesRelative();
- if (isMonochrome(compoundDrawables[0])) {
- Drawable d = compoundDrawables[0];
- d.mutate();
- d.setColorFilter(mLightThemeContext.getResources().getColor(
- R.color.notification_action_legacy_color_filter),
- PorterDuff.Mode.MULTIPLY);
- }
- }
- }
- }
- }
-
- private void processLegacyTextViews(View content) {
- Stack<View> viewStack = new Stack<View>();
- viewStack.push(content);
- while(!viewStack.isEmpty()) {
- View current = viewStack.pop();
- if(current instanceof ViewGroup){
- ViewGroup currentGroup = (ViewGroup) current;
- int numChildren = currentGroup.getChildCount();
- for(int i=0;i<numChildren;i++){
- viewStack.push(currentGroup.getChildAt(i));
- }
- }
- if (current instanceof TextView) {
- processLegacyTextView((TextView) current);
- }
- }
- }
-
- private void processLegacyTextView(TextView textView) {
- if (textView.getText() instanceof Spanned) {
- Spanned ss = (Spanned) textView.getText();
- Object[] spans = ss.getSpans(0, ss.length(), Object.class);
- SpannableStringBuilder builder = new SpannableStringBuilder(ss.toString());
- for (Object span : spans) {
- Object resultSpan = span;
- if (span instanceof TextAppearanceSpan) {
- resultSpan = processTextAppearanceSpan((TextAppearanceSpan) span);
- }
- builder.setSpan(resultSpan, ss.getSpanStart(span), ss.getSpanEnd(span),
- ss.getSpanFlags(span));
- }
- textView.setText(builder);
- }
- }
-
- private TextAppearanceSpan processTextAppearanceSpan(TextAppearanceSpan span) {
- ColorStateList colorStateList = span.getTextColor();
- if (colorStateList != null) {
- int[] colors = colorStateList.getColors();
- boolean changed = false;
- for (int i = 0; i < colors.length; i++) {
- if (mImageUtils.isGrayscale(colors[i])) {
- colors[i] = processColor(colors[i]);
- changed = true;
- }
- }
- if (changed) {
- return new TextAppearanceSpan(
- span.getFamily(), span.getTextStyle(), span.getTextSize(),
- new ColorStateList(colorStateList.getStates(), colors),
- span.getLinkTextColor());
- }
- }
- return span;
- }
-
- private int processColor(int color) {
- return Color.argb(Color.alpha(color),
- 255 - Color.red(color),
- 255 - Color.green(color),
- 255 - Color.blue(color));
- }
-
private void startApplicationDetailsActivity(String packageName) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null));
@@ -947,10 +783,10 @@ public abstract class BaseStatusBar extends SystemUI implements
View contentViewLocal = null;
View bigContentViewLocal = null;
try {
- contentViewLocal = contentView.apply(getInflationContext(sbn), expanded,
+ contentViewLocal = contentView.apply(mContext, expanded,
mOnClickHandler);
if (bigContentView != null) {
- bigContentViewLocal = bigContentView.apply(getInflationContext(sbn), expanded,
+ bigContentViewLocal = bigContentView.apply(mContext, expanded,
mOnClickHandler);
}
}
@@ -983,8 +819,8 @@ public abstract class BaseStatusBar extends SystemUI implements
View publicViewLocal = null;
if (publicNotification != null) {
try {
- publicViewLocal = publicNotification.contentView.apply(getInflationContext(sbn),
- expandedPublic, mOnClickHandler);
+ publicViewLocal = publicNotification.contentView.apply(mContext, expandedPublic,
+ mOnClickHandler);
if (publicViewLocal != null) {
publicViewLocal.setIsRootNamespace(true);
@@ -1005,7 +841,8 @@ public abstract class BaseStatusBar extends SystemUI implements
if (publicViewLocal == null) {
// Add a basic notification template
publicViewLocal = LayoutInflater.from(mContext).inflate(
- com.android.internal.R.layout.notification_template_base, expandedPublic, true);
+ com.android.internal.R.layout.notification_template_quantum_base,
+ expandedPublic, true);
final TextView title = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.title);
try {
@@ -1024,7 +861,12 @@ public abstract class BaseStatusBar extends SystemUI implements
entry.notification.getNotification().number,
entry.notification.getNotification().tickerText);
- icon.setImageDrawable(StatusBarIconView.getIcon(mContext, ic));
+ Drawable iconDrawable = StatusBarIconView.getIcon(mContext, ic);
+ icon.setImageDrawable(iconDrawable);
+ if (mLegacyNotificationUtil.isGrayscale(iconDrawable)) {
+ icon.setBackgroundResource(
+ com.android.internal.R.drawable.notification_icon_legacy_bg_inset);
+ }
final TextView text = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.text);
text.setText("Unlock your device to see this notification.");
@@ -1035,13 +877,6 @@ public abstract class BaseStatusBar extends SystemUI implements
row.setDrawingCacheEnabled(true);
applyLegacyRowBackground(sbn, content);
- processLegacyHoloNotification(sbn, contentViewLocal);
- if (bigContentViewLocal != null) {
- processLegacyHoloNotification(sbn, bigContentViewLocal);
- }
- if (publicViewLocal != null) {
- processLegacyHoloNotification(sbn, publicViewLocal);
- }
if (MULTIUSER_DEBUG) {
TextView debug = (TextView) row.findViewById(R.id.debug_info);
@@ -1260,8 +1095,7 @@ public abstract class BaseStatusBar extends SystemUI implements
}
private boolean shouldIntercept() {
- return mZenMode == Settings.Global.ZEN_MODE_LIMITED
- || mZenMode == Settings.Global.ZEN_MODE_FULL;
+ return mZenMode != Settings.Global.ZEN_MODE_OFF;
}
protected boolean shouldIntercept(Notification n) {
@@ -1459,17 +1293,13 @@ public abstract class BaseStatusBar extends SystemUI implements
: null;
// Reapply the RemoteViews
- contentView.reapply(getInflationContext(notification), entry.expanded, mOnClickHandler);
- processLegacyHoloNotification(notification, entry.expanded);
+ contentView.reapply(mContext, entry.expanded, mOnClickHandler);
if (bigContentView != null && entry.getBigContentView() != null) {
- bigContentView.reapply(getInflationContext(notification), entry.getBigContentView(),
+ bigContentView.reapply(mContext, entry.getBigContentView(),
mOnClickHandler);
- processLegacyHoloNotification(notification, entry.getBigContentView());
}
if (publicContentView != null && entry.getPublicContentView() != null) {
- publicContentView.reapply(getInflationContext(notification),
- entry.getPublicContentView(), mOnClickHandler);
- processLegacyHoloNotification(notification, entry.getPublicContentView());
+ publicContentView.reapply(mContext, entry.getPublicContentView(), mOnClickHandler);
}
// update the contentIntent
final PendingIntent contentIntent = notification.getNotification().contentIntent;
@@ -1540,35 +1370,4 @@ public abstract class BaseStatusBar extends SystemUI implements
}
mContext.unregisterReceiver(mBroadcastReceiver);
}
-
- /**
- * A custom context theme wrapper that applies a platform theme to a created package context.
- * This is useful if you want to inflate {@link RemoteViews} with a custom theme (normally, the
- * theme used there is the default platform theme).
- */
- private static class RemoteViewsThemeContextWrapper extends ContextThemeWrapper {
-
- private int mThemeRes;
-
- private RemoteViewsThemeContextWrapper(Context base, int themeres) {
- super(base, themeres);
- mThemeRes = themeres;
- }
-
- @Override
- public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
- throws NameNotFoundException {
- Context c = super.createPackageContextAsUser(packageName, flags, user);
- c.setTheme(mThemeRes);
- return c;
- }
-
- @Override
- public Context createPackageContext(String packageName, int flags)
- throws NameNotFoundException {
- Context c = super.createPackageContext(packageName, flags);
- c.setTheme(mThemeRes);
- return c;
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 60ec787..adfa118 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -80,13 +80,13 @@ import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.ScrollView;
import android.widget.TextView;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.DemoMode;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.GestureRecorder;
@@ -94,6 +94,7 @@ import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
+
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.DateView;
@@ -104,6 +105,8 @@ import com.android.systemui.statusbar.policy.NotificationRowLayout;
import com.android.systemui.statusbar.policy.OnSizeChangedListener;
import com.android.systemui.statusbar.policy.RotationLockController;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -195,7 +198,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
// expanded notifications
NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
- ScrollView mScrollView;
+ View mNotificationScroller;
View mExpandedContents;
int mNotificationPanelGravity;
int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
@@ -352,13 +355,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
super.setZenMode(mode);
if (mModeIcon == null) return;
if (!isDeviceProvisioned()) return;
- final boolean limited = mode == Settings.Global.ZEN_MODE_LIMITED;
- final boolean full = mode == Settings.Global.ZEN_MODE_FULL;
- mModeIcon.setVisibility(full || limited ? View.VISIBLE : View.GONE);
- final int icon = limited ? R.drawable.stat_sys_zen_limited : R.drawable.stat_sys_zen_full;
- if (full || limited) {
- mModeIcon.setImageResource(icon);
- }
+ mModeIcon.setVisibility(mode != Settings.Global.ZEN_MODE_OFF ? View.VISIBLE : View.GONE);
}
@Override
@@ -481,14 +478,38 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
mNotificationIcons.setOverflowIndicator(mMoreIcon);
mModeIcon = (ImageView)mStatusBarView.findViewById(R.id.modeIcon);
+ mModeIcon.setImageResource(R.drawable.stat_sys_zen_limited);
mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
mTickerView = mStatusBarView.findViewById(R.id.ticker);
- mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems);
- mPile.setLayoutTransitionsEnabled(false);
- mPile.setLongPressListener(getNotificationLongClicker());
+ View legacyScrollView = mStatusBarWindow.findViewById(R.id.scroll);
+ NotificationStackScrollLayout notificationStack
+ = (NotificationStackScrollLayout) mStatusBarWindow
+ .findViewById(R.id.notification_stack_scroller);
+ if (ENABLE_NOTIFICATION_STACK) {
+ notificationStack.setLongPressListener(getNotificationLongClicker());
+ mPile = notificationStack;
+ legacyScrollView.setVisibility(View.GONE);
+
+ // The scrollview and the notification container are unified now!
+ // TODO: remove mNotificationScroller entirely once we fully switch to the new Layout
+ mNotificationScroller = notificationStack;
+ } else {
+ mNotificationScroller = legacyScrollView;
+ // less drawing during pulldowns
+ mNotificationScroller.setVerticalScrollBarEnabled(false);
+ NotificationRowLayout rowLayout
+ = (NotificationRowLayout) mStatusBarWindow.findViewById(R.id.latestItems);
+ rowLayout.setLayoutTransitionsEnabled(false);
+ rowLayout.setLongPressListener(getNotificationLongClicker());
+ mPile = rowLayout;
+ notificationStack.setVisibility(View.GONE);
+ }
+
mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
+
+
mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header);
mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
@@ -536,10 +557,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
}
- mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
- mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
if (!mNotificationPanelIsFullScreenWidth) {
- mScrollView.setSystemUiVisibility(
+ mNotificationPanel.setSystemUiVisibility(
View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
View.STATUS_BAR_DISABLE_CLOCK);
}
@@ -602,7 +621,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
// set up the dynamic hide/show of the label
- mPile.setOnSizeChangedListener(new OnSizeChangedListener() {
+ if (!ENABLE_NOTIFICATION_STACK)
+ ((NotificationRowLayout) mPile).setOnSizeChangedListener(new OnSizeChangedListener() {
@Override
public void onSizeChanged(View view, int w, int h, int oldw, int oldh) {
updateCarrierLabelVisibility(false);
@@ -981,9 +1001,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
@Override
public void resetHeadsUpDecayTimer() {
+ mHandler.removeMessages(MSG_HIDE_HEADS_UP);
if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
&& mHeadsUpNotificationView.isClearable()) {
- mHandler.removeMessages(MSG_HIDE_HEADS_UP);
mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
}
}
@@ -1153,19 +1173,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
protected void updateCarrierLabelVisibility(boolean force) {
+ // TODO: Handle this for the notification stack scroller as well
if (!mShowCarrierInPanel) return;
// The idea here is to only show the carrier label when there is enough room to see it,
// i.e. when there aren't enough notifications to fill the panel.
if (SPEW) {
Log.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
- mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
+ mPile.getHeight(), mNotificationScroller.getHeight(), mCarrierLabelHeight));
}
final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
final boolean makeVisible =
!(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
&& mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
- && mScrollView.getVisibility() == View.VISIBLE;
+ && mNotificationScroller.getVisibility() == View.VISIBLE;
if (force || mCarrierLabelVisible != makeVisible) {
mCarrierLabelVisible = makeVisible;
@@ -1208,7 +1229,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
if (mHasFlipSettings
&& mFlipSettingsView != null
&& mFlipSettingsView.getVisibility() == View.VISIBLE
- && mScrollView.getVisibility() != View.VISIBLE) {
+ && mNotificationScroller.getVisibility() != View.VISIBLE) {
// the flip settings panel is unequivocally showing; we should not be shown
mClearButton.setVisibility(View.INVISIBLE);
} else if (mClearButton.isShown()) {
@@ -1462,7 +1483,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
mExpandedVisible = true;
- mPile.setLayoutTransitionsEnabled(true);
+ if(!ENABLE_NOTIFICATION_STACK) {
+ ((NotificationRowLayout) mPile).setLayoutTransitionsEnabled(true);
+ }
if (mNavigationBarView != null)
mNavigationBarView.setSlippery(true);
@@ -1577,7 +1600,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
mNotificationPanel.expand();
- if (mHasFlipSettings && mScrollView.getVisibility() != View.VISIBLE) {
+ if (mHasFlipSettings && mNotificationScroller.getVisibility() != View.VISIBLE) {
flipToNotifications();
}
@@ -1591,11 +1614,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
if (mClearButtonAnim != null) mClearButtonAnim.cancel();
- mScrollView.setVisibility(View.VISIBLE);
+ mNotificationScroller.setVisibility(View.VISIBLE);
mScrollViewAnim = start(
startDelay(FLIP_DURATION_OUT,
interpolator(mDecelerateInterpolator,
- ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
+ ObjectAnimator.ofFloat(mNotificationScroller, View.SCALE_X, 0f, 1f)
.setDuration(FLIP_DURATION_IN)
)));
mFlipSettingsViewAnim = start(
@@ -1653,8 +1676,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mFlipSettingsView.setScaleX(1f);
mFlipSettingsView.setVisibility(View.VISIBLE);
mSettingsButton.setVisibility(View.GONE);
- mScrollView.setVisibility(View.GONE);
- mScrollView.setScaleX(0f);
+ mNotificationScroller.setVisibility(View.GONE);
+ mNotificationScroller.setScaleX(0f);
mNotificationButton.setVisibility(View.VISIBLE);
mNotificationButton.setAlpha(1f);
mClearButton.setVisibility(View.GONE);
@@ -1681,15 +1704,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mScrollViewAnim = start(
setVisibilityWhenDone(
interpolator(mAccelerateInterpolator,
- ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
+ ObjectAnimator.ofFloat(mNotificationScroller, View.SCALE_X, 1f, 0f)
)
.setDuration(FLIP_DURATION_OUT),
- mScrollView, View.INVISIBLE));
+ mNotificationScroller, View.INVISIBLE));
mSettingsButtonAnim = start(
setVisibilityWhenDone(
ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
.setDuration(FLIP_DURATION),
- mScrollView, View.INVISIBLE));
+ mNotificationScroller, View.INVISIBLE));
mNotificationButton.setVisibility(View.VISIBLE);
mNotificationButtonAnim = start(
ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
@@ -1743,8 +1766,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
if (mClearButtonAnim != null) mClearButtonAnim.cancel();
- mScrollView.setScaleX(1f);
- mScrollView.setVisibility(View.VISIBLE);
+ mNotificationScroller.setScaleX(1f);
+ mNotificationScroller.setVisibility(View.VISIBLE);
mSettingsButton.setAlpha(1f);
mSettingsButton.setVisibility(View.VISIBLE);
mNotificationPanel.setVisibility(View.GONE);
@@ -1754,7 +1777,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
mExpandedVisible = false;
- mPile.setLayoutTransitionsEnabled(false);
+ if(!ENABLE_NOTIFICATION_STACK) {
+ ((NotificationRowLayout) mPile).setLayoutTransitionsEnabled(false);
+ }
if (mNavigationBarView != null)
mNavigationBarView.setSlippery(false);
visibilityChanged(false);
@@ -2207,8 +2232,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
pw.println(" mDisplayMetrics=" + mDisplayMetrics);
pw.println(" mPile: " + viewInfo(mPile));
pw.println(" mTickerView: " + viewInfo(mTickerView));
- pw.println(" mScrollView: " + viewInfo(mScrollView)
- + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
+ pw.println(" mNotificationScroller: " + viewInfo(mNotificationScroller)
+ + " scroll " + mNotificationScroller.getScrollX()
+ + "," + mNotificationScroller.getScrollY());
}
pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
@@ -2402,17 +2428,38 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
public void onClick(View v) {
+ // TODO: Handle this better with notification stack scroller
synchronized (mNotificationData) {
+ mPostCollapseCleanup = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) {
+ Log.v(TAG, "running post-collapse cleanup");
+ }
+ try {
+ if (!ENABLE_NOTIFICATION_STACK) {
+ ((NotificationRowLayout) mPile).setViewRemoval(true);
+ }
+ mBarService.onClearAllNotifications(mCurrentUserId);
+ } catch (Exception ex) { }
+ }
+ };
+
+ if(ENABLE_NOTIFICATION_STACK) {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
+ return;
+ }
+
// animate-swipe all dismissable notifications, then animate the shade closed
int numChildren = mPile.getChildCount();
- int scrollTop = mScrollView.getScrollY();
- int scrollBottom = scrollTop + mScrollView.getHeight();
+ int scrollTop = mNotificationScroller.getScrollY();
+ int scrollBottom = scrollTop + mNotificationScroller.getHeight();
final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
for (int i=0; i<numChildren; i++) {
final View child = mPile.getChildAt(i);
- if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
- child.getTop() < scrollBottom) {
+ if (((SwipeHelper.Callback) mPile).canChildBeDismissed(child)
+ && child.getBottom() > scrollTop && child.getTop() < scrollBottom) {
snapshot.add(child);
}
}
@@ -2429,23 +2476,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
int currentDelay = 140;
int totalDelay = 0;
- // Set the shade-animating state to avoid doing other work during
- // all of these animations. In particular, avoid layout and
- // redrawing when collapsing the shade.
- mPile.setViewRemoval(false);
- mPostCollapseCleanup = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) {
- Log.v(TAG, "running post-collapse cleanup");
- }
- try {
- mPile.setViewRemoval(true);
- mBarService.onClearAllNotifications(mCurrentUserId);
- } catch (Exception ex) { }
- }
- };
+ if(!ENABLE_NOTIFICATION_STACK) {
+ // Set the shade-animating state to avoid doing other work during
+ // all of these animations. In particular, avoid layout and
+ // redrawing when collapsing the shade.
+ ((NotificationRowLayout) mPile).setViewRemoval(false);
+ }
View sampleView = snapshot.get(0);
int width = sampleView.getWidth();
@@ -2455,7 +2492,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- mPile.dismissRowAnimated(_v, velocity);
+ if (!ENABLE_NOTIFICATION_STACK) {
+ ((NotificationRowLayout) mPile).dismissRowAnimated(
+ _v, velocity);
+ } else {
+ ((NotificationStackScrollLayout) mPile).dismissRowAnimated(
+ _v, velocity);
+ }
}
}, totalDelay);
currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 8170b5a..aed9a71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -33,6 +33,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -42,6 +43,7 @@ import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
+import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -56,11 +58,13 @@ import android.text.TextUtils.TruncateAt;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
+import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
@@ -897,7 +901,16 @@ class QuickSettings {
d.requestWindowFeature(Window.FEATURE_NO_TITLE);
d.setCancelable(true);
d.setCanceledOnTouchOutside(true);
- final ZenModeView v = new ZenModeView(mContext);
+ final ZenModeView v = new ZenModeView(mContext) {
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ WindowManager.LayoutParams lp = d.getWindow().getAttributes();
+ lp.width = mContext.getResources()
+ .getDimensionPixelSize(R.dimen.zen_mode_dialog_width);
+ d.getWindow().setAttributes(lp);
+ }
+ };
v.setAdapter(new ZenModeViewAdapter(mContext) {
@Override
public void configure() {
@@ -914,6 +927,10 @@ class QuickSettings {
d.setContentView(v);
d.create();
d.getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+ WindowManager.LayoutParams lp = d.getWindow().getAttributes();
+ lp.horizontalMargin = 0;
+ lp.width = mContext.getResources().getDimensionPixelSize(R.dimen.zen_mode_dialog_width);
+ d.getWindow().setAttributes(lp);
d.show();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index c3c281c..9b25046 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -608,16 +608,8 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
mZenModeState.enabled = mode != Settings.Global.ZEN_MODE_OFF;
mZenModeState.zenMode = mode;
- if (mode == Settings.Global.ZEN_MODE_FULL) {
- mZenModeState.iconId = R.drawable.stat_sys_zen_full;
- mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_FULL);
- } else if (mode == Settings.Global.ZEN_MODE_LIMITED) {
- mZenModeState.iconId = R.drawable.stat_sys_zen_limited;
- mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED);
- } else {
- mZenModeState.iconId = R.drawable.stat_sys_zen_limited;
- mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED);
- }
+ mZenModeState.label = ZenModeView.MODE_LABEL;
+ mZenModeState.iconId = R.drawable.stat_sys_zen_limited;
mZenModeCallback.refreshView(mZenModeTile, mZenModeState);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 7b03195..925e0d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -24,6 +24,7 @@ import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.widget.FrameLayout;
import android.widget.ScrollView;
@@ -31,7 +32,6 @@ import android.widget.ScrollView;
import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;
-import com.android.systemui.statusbar.policy.NotificationRowLayout;
public class StatusBarWindowView extends FrameLayout
@@ -40,7 +40,7 @@ public class StatusBarWindowView extends FrameLayout
public static final boolean DEBUG = BaseStatusBar.DEBUG;
private ExpandHelper mExpandHelper;
- private NotificationRowLayout latestItems;
+ private ViewGroup latestItems;
private NotificationPanelView mNotificationPanel;
private ScrollView mScrollView;
@@ -55,12 +55,18 @@ public class StatusBarWindowView extends FrameLayout
@Override
protected void onAttachedToWindow () {
super.onAttachedToWindow();
- latestItems = (NotificationRowLayout) findViewById(R.id.latestItems);
+
+ if (BaseStatusBar.ENABLE_NOTIFICATION_STACK) {
+ latestItems = (ViewGroup) findViewById(R.id.notification_stack_scroller);
+ } else {
+ latestItems = (ViewGroup) findViewById(R.id.latestItems);
+ }
mScrollView = (ScrollView) findViewById(R.id.scroll);
mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
- mExpandHelper = new ExpandHelper(getContext(), latestItems, minHeight, maxHeight);
+ mExpandHelper = new ExpandHelper(getContext(), (ExpandHelper.Callback) latestItems,
+ minHeight, maxHeight);
mExpandHelper.setEventSource(this);
mExpandHelper.setScrollView(mScrollView);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
index d1c7a41..d1a9d57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
@@ -21,10 +21,10 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Paint;
-import android.graphics.Path;
+import android.graphics.PorterDuff.Mode;
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.PathShape;
+import android.graphics.drawable.shapes.OvalShape;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
@@ -36,13 +36,13 @@ import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.ListView;
import android.widget.RelativeLayout;
-import android.widget.Spinner;
+import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
@@ -53,28 +53,30 @@ public class ZenModeView extends RelativeLayout {
private static final String TAG = ZenModeView.class.getSimpleName();
private static final boolean DEBUG = false;
+ public static final String MODE_LABEL = "Limited interruptions";
+ public static final int BACKGROUND = 0xff282828;
+
private static final Typeface CONDENSED =
Typeface.create("sans-serif-condensed", Typeface.NORMAL);
private static final int GRAY = 0xff999999; //TextAppearance.StatusBar.Expanded.Network
- private static final int BACKGROUND = 0xff282828;
+ private static final int DARK_GRAY = 0xff333333;
+
private static final long DURATION = new ValueAnimator().getDuration();
- private static final long BOUNCE_DURATION = DURATION / 3;
+ private static final long PAGER_DURATION = DURATION / 2;
private static final float BOUNCE_SCALE = 0.8f;
- private static final float SETTINGS_ALPHA = 0.6f;
-
- private static final String FULL_TEXT =
- "You won't hear any calls, alarms or timers.";
+ private static final long CLOSE_DELAY = 600;
private final Context mContext;
private final Paint mPathPaint;
private final ImageView mSettingsButton;
- private final ModeSpinner mModeSpinner;
- private final TextView mActionButton;
+ private final TextView mModeText;
+ private final Switch mModeSwitch;
private final View mDivider;
private final UntilPager mUntilPager;
- private final AlarmWarning mAlarmWarning;
+ private final ProgressDots mProgressDots;
private Adapter mAdapter;
+ private boolean mInit;
public ZenModeView(Context context) {
this(context, null);
@@ -105,37 +107,45 @@ public class ZenModeView extends RelativeLayout {
mSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (mAdapter != null && mAdapter.getMode() == Adapter.MODE_LIMITED) {
+ if (mAdapter != null) {
mAdapter.configure();
}
bounce(mSettingsButton, null);
}
});
- mModeSpinner = new ModeSpinner(mContext);
- mModeSpinner.setId(android.R.id.title);
+ mModeText = new TextView(mContext);
+ mModeText.setText(MODE_LABEL);
+ mModeText.setId(android.R.id.title);
+ mModeText.setTextColor(GRAY);
+ mModeText.setTypeface(CONDENSED);
+ mModeText.setAllCaps(true);
+ mModeText.setGravity(Gravity.CENTER);
+ mModeText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mModeText.getTextSize() * 1.1f);
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize);
lp.topMargin = p;
lp.addRule(CENTER_HORIZONTAL);
- addView(mModeSpinner, lp);
-
- mActionButton = new TextView(mContext);
- mActionButton.setTextColor(GRAY);
- mActionButton.setTypeface(CONDENSED);
- mActionButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mActionButton.getTextSize() * 1.2f);
- mActionButton.setAllCaps(true);
- mActionButton.setGravity(Gravity.CENTER);
- mActionButton.setPadding(p, 0, p * 2, 0);
+ addView(mModeText, lp);
+
+ mModeSwitch = new Switch(mContext);
+ mModeSwitch.setSwitchPadding(0);
+ mModeSwitch.setSwitchTypeface(CONDENSED);
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize);
lp.topMargin = p;
lp.addRule(ALIGN_PARENT_RIGHT);
- lp.addRule(ALIGN_BASELINE, mModeSpinner.getId());
- addView(mActionButton, lp);
- mActionButton.setOnClickListener(new View.OnClickListener() {
+ lp.addRule(ALIGN_BASELINE, mModeText.getId());
+ addView(mModeSwitch, lp);
+ mModeSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
- public void onClick(View v) {
- bounce(v, null);
- beginOrEnd();
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ mAdapter.setMode(isChecked);
+ if (!mInit) return;
+ postDelayed(new Runnable(){
+ @Override
+ public void run() {
+ mAdapter.close();
+ }
+ }, CLOSE_DELAY);
}
});
@@ -143,35 +153,24 @@ public class ZenModeView extends RelativeLayout {
mDivider.setId(android.R.id.empty);
mDivider.setBackgroundColor(GRAY);
lp = new LayoutParams(LayoutParams.MATCH_PARENT, 2);
- lp.addRule(BELOW, mModeSpinner.getId());
+ lp.addRule(BELOW, mModeText.getId());
lp.topMargin = p;
- lp.bottomMargin = p;
+ lp.bottomMargin = p * 2;
addView(mDivider, lp);
mUntilPager = new UntilPager(mContext, mPathPaint, iconSize * 3 / 4);
mUntilPager.setId(android.R.id.tabhost);
- lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ lp.leftMargin = lp.rightMargin = iconSize / 2;
+ lp.addRule(CENTER_HORIZONTAL);
lp.addRule(BELOW, mDivider.getId());
addView(mUntilPager, lp);
- mAlarmWarning = new AlarmWarning(mContext);
+ mProgressDots = new ProgressDots(mContext, iconSize / 5);
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(CENTER_HORIZONTAL);
lp.addRule(BELOW, mUntilPager.getId());
- lp.bottomMargin = p;
- addView(mAlarmWarning, lp);
- }
-
- private void beginOrEnd() {
- if (mAdapter == null) return;
- if (mAdapter.getMode() == mAdapter.getCommittedMode()) {
- // end
- mAdapter.setCommittedMode(Adapter.MODE_OFF);
- } else {
- // begin
- mAdapter.setCommittedMode(mAdapter.getMode());
- }
- mAdapter.close();
+ addView(mProgressDots, lp);
}
public void setAdapter(Adapter adapter) {
@@ -191,55 +190,15 @@ public class ZenModeView extends RelativeLayout {
}
private void updateState(boolean animate) {
- mModeSpinner.updateState();
mUntilPager.updateState();
- mAlarmWarning.updateState(animate);
- final float settingsAlpha = isFull() ? 0 : SETTINGS_ALPHA;
- if (settingsAlpha != mSettingsButton.getAlpha()) {
- if (animate) {
- mSettingsButton.animate().alpha(settingsAlpha).start();
- } else {
- mSettingsButton.setAlpha(settingsAlpha);
- }
- }
- final boolean committed = mAdapter != null
- && mAdapter.getMode() == mAdapter.getCommittedMode();
- mActionButton.setText(committed ? "End" : "Begin");
- }
-
- private boolean isFull() {
- return mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (DEBUG) log("onMeasure %s %s",
- MeasureSpec.toString(widthMeasureSpec), MeasureSpec.toString(heightMeasureSpec));
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- if (!isFull()) {
- final LayoutParams lp = (LayoutParams) mModeSpinner.getLayoutParams();
- final int mh = vh(mModeSpinner) + vh(mDivider) + vh(mUntilPager) + lp.topMargin;
- setMeasuredDimension(getMeasuredWidth(), mh);
- }
- }
-
- private int vh(View v) {
- LayoutParams lp = (LayoutParams) v.getLayoutParams();
- return v.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
+ mModeSwitch.setChecked(mAdapter.getMode());
+ mInit = true;
}
private static void log(String msg, Object... args) {
Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
}
- private static ShapeDrawable sd(Path p, int size, Paint pt) {
- final ShapeDrawable sd = new ShapeDrawable(new PathShape(p, size, size));
- sd.getPaint().set(pt);
- sd.setIntrinsicHeight(size);
- sd.setIntrinsicWidth(size);
- return sd;
- }
-
private static void bounce(final View v, final Runnable midBounce) {
v.animate().scaleX(BOUNCE_SCALE).scaleY(BOUNCE_SCALE).setDuration(DURATION / 3)
.setListener(new AnimatorListenerAdapter() {
@@ -257,118 +216,23 @@ public class ZenModeView extends RelativeLayout {
}).start();
}
- public static String modeToString(int mode) {
- if (mode == Adapter.MODE_OFF) return "MODE_OFF";
- if (mode == Adapter.MODE_LIMITED) return "MODE_LIMITED";
- if (mode == Adapter.MODE_FULL) return "MODE_FULL";
- throw new IllegalArgumentException("Invalid mode: " + mode);
- }
-
- public static String modeToLabel(int mode) {
- if (mode == Adapter.MODE_LIMITED) return "Limited interruptions";
- if (mode == Adapter.MODE_FULL) return "Zero interruptions";
- throw new UnsupportedOperationException("Unsupported mode: " + mode);
- }
-
- private final class UntilPager extends RelativeLayout {
- private final ImageView mPrev;
- private final ImageView mNext;
- private final TextView mText1;
- private final TextView mText2;
-
- private TextView mText;
+ private final class UntilView extends FrameLayout {
+ private static final boolean SUPPORT_LINKS = false;
- public UntilPager(Context context, Paint pathPaint, int iconSize) {
+ private final TextView mText;
+ public UntilView(Context context) {
super(context);
- mText1 = new TextView(mContext);
- mText1.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize() * 1.2f);
- mText1.setTypeface(CONDENSED);
- mText1.setTextColor(GRAY);
- mText1.setGravity(Gravity.CENTER);
- LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, iconSize);
- addView(mText1, lp);
- mText = mText1;
-
- mText2 = new TextView(mContext);
- mText2.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize());
- mText2.setTypeface(CONDENSED);
- mText2.setTextColor(GRAY);
- mText2.setAlpha(0);
- mText2.setGravity(Gravity.CENTER);
- addView(mText2, lp);
-
- lp = new LayoutParams(iconSize, iconSize);
- final View v = new View(mContext);
- v.setBackgroundColor(BACKGROUND);
- addView(v, lp);
- mPrev = new ImageView(mContext);
- mPrev.setId(android.R.id.button1);
- mPrev.setImageDrawable(sd(prevPath(iconSize), iconSize, pathPaint));
- addView(mPrev, lp);
- mPrev.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- onNav(v, -1);
- }
- });
-
- lp = new LayoutParams(iconSize, iconSize);
- lp.addRule(ALIGN_PARENT_RIGHT);
- final View v2 = new View(mContext);
- v2.setBackgroundColor(BACKGROUND);
- addView(v2, lp);
- mNext = new ImageView(mContext);
- mNext.setId(android.R.id.button2);
- mNext.setImageDrawable(sd(nextPath(iconSize), iconSize, pathPaint));
- addView(mNext, lp);
- mNext.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- onNav(v, 1);
- }
- });
-
- updateState();
+ mText = new TextView(mContext);
+ mText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText.getTextSize() * 1.2f);
+ mText.setTypeface(CONDENSED);
+ mText.setTextColor(GRAY);
+ mText.setGravity(Gravity.CENTER);
+ addView(mText);
}
- private void onNav(View v, int d) {
- bounce(v, null);
- if (mAdapter == null) {
- return;
- }
- if (mAdapter.getExitConditionCount() == 1) {
- horBounce(d);
- return;
- }
- final int w = getWidth();
- final float s = Math.signum(d);
- final TextView current = mText;
- final TextView other = mText == mText1 ? mText2 : mText1;
- final ExitCondition ec = mAdapter.getExitCondition(d);
- setText(other, ec);
- other.setTranslationX(-s * w);
- other.animate().translationX(0).alpha(1).setDuration(DURATION).start();
- current.animate().translationX(s * w).alpha(0).setDuration(DURATION).start();
- mText = other;
- mAdapter.select(ec);
- }
-
- private void horBounce(int d) {
- final int w = getWidth();
- mText.animate()
- .setDuration(BOUNCE_DURATION)
- .translationX(Math.signum(d) * w / 20)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mText.animate().translationX(0).setListener(null).start();
- }
- }).start();
- }
-
- private void setText(final TextView textView, final ExitCondition ec) {
+ public void setExitCondition(final ExitCondition ec) {
SpannableStringBuilder ss = new SpannableStringBuilder(ec.summary);
- if (ec.action != null) {
+ if (SUPPORT_LINKS && ec.action != null) {
ss.setSpan(new CustomLinkSpan() {
@Override
public void onClick() {
@@ -376,38 +240,122 @@ public class ZenModeView extends RelativeLayout {
Toast.makeText(mContext, ec.action, Toast.LENGTH_SHORT).show();
}
}, 0, ss.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
- textView.setMovementMethod(LinkMovementMethod.getInstance());
+ mText.setMovementMethod(LinkMovementMethod.getInstance());
} else {
- textView.setMovementMethod(null);
+ mText.setMovementMethod(null);
+ }
+ mText.setText(ss);
+ }
+ }
+
+ private final class ProgressDots extends LinearLayout {
+ private final int mDotSize;
+ public ProgressDots(Context context, int dotSize) {
+ super(context);
+ setOrientation(HORIZONTAL);
+ mDotSize = dotSize;
+ }
+
+ private void updateState(int current, int count) {
+ while (getChildCount() < count) {
+ View dot = new View(mContext);
+ OvalShape s = new OvalShape();
+ ShapeDrawable sd = new ShapeDrawable(s);
+
+ dot.setBackground(sd);
+ LayoutParams lp = new LayoutParams(mDotSize, mDotSize);
+ lp.leftMargin = lp.rightMargin = mDotSize / 2;
+ lp.topMargin = lp.bottomMargin = mDotSize * 2 / 3;
+ addView(dot, lp);
+ }
+ while (getChildCount() > count) {
+ removeViewAt(getChildCount() - 1);
+ }
+ final int N = getChildCount();
+ for (int i = 0; i < N; i++) {
+ final int color = current == i ? GRAY : DARK_GRAY;
+ ((ShapeDrawable)getChildAt(i).getBackground()).setColorFilter(color, Mode.ADD);
+ }
+ }
+ }
+
+ private final class UntilPager extends RelativeLayout {
+ private final UntilView[] mViews;
+ private int mCurrent;
+ private float mDownX;
+
+ public UntilPager(Context context, Paint pathPaint, int iconSize) {
+ super(context);
+ mViews = new UntilView[3];
+ for (int i = 0; i < mViews.length; i++) {
+ UntilView v = new UntilView(mContext);
+ LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, iconSize);
+ addView(v, lp);
+ mViews[i] = v;
}
- textView.setText(ss);
+ updateState();
+ addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right,
+ int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ if (left != oldLeft || right != oldRight) {
+ updateState();
+ }
+ }
+ });
+ setBackgroundColor(DARK_GRAY);
}
private void updateState() {
if (mAdapter == null) {
return;
}
- setText(mText, mAdapter.getExitCondition(0));
+ UntilView current = mViews[mCurrent];
+ current.setExitCondition(mAdapter.getExitCondition(0));
+ UntilView next = mViews[mCurrent + 1 % 3];
+ next.setExitCondition(mAdapter.getExitCondition(1));
+ UntilView prev = mViews[mCurrent + 2 % 3];
+ prev.setExitCondition(mAdapter.getExitCondition(-1));
+ position(0, false);
+ mProgressDots.updateState(mAdapter.getExitConditionIndex(),
+ mAdapter.getExitConditionCount());
}
- private Path prevPath(int size) {
- final int hp = size * 3 / 8;
- final int vp = size / 4;
- final Path p = new Path();
- p.moveTo(size - hp, vp);
- p.lineTo(hp, size / 2);
- p.lineTo(size - hp, size - vp);
- return p;
+ private void position(float dx, boolean animate) {
+ int w = getWidth();
+ UntilView current = mViews[mCurrent];
+ UntilView next = mViews[mCurrent + 1 % 3];
+ UntilView prev = mViews[mCurrent + 2 % 3];
+ if (animate) {
+ current.animate().setDuration(PAGER_DURATION).translationX(dx).start();
+ next.animate().setDuration(PAGER_DURATION).translationX(w + dx).start();
+ prev.animate().setDuration(PAGER_DURATION).translationX(-w + dx).start();
+ } else {
+ current.setTranslationX(dx);
+ next.setTranslationX(w + dx);
+ prev.setTranslationX(-w + dx);
+ }
}
- private Path nextPath(int size) {
- final int hp = size * 3 / 8;
- final int vp = size / 4;
- Path p = new Path();
- p.moveTo(hp, vp);
- p.lineTo(size - hp, size / 2);
- p.lineTo(hp, size - vp);
- return p;
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ log("onTouchEvent " + MotionEvent.actionToString(event.getAction()));
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ mDownX = event.getX();
+ } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ float dx = event.getX() - mDownX;
+ position(dx, false);
+ } else if (event.getAction() == MotionEvent.ACTION_UP
+ || event.getAction() == MotionEvent.ACTION_CANCEL) {
+ float dx = event.getX() - mDownX;
+ int d = Math.abs(dx) < getWidth() / 3 ? 0 : Math.signum(dx) > 0 ? -1 : 1;
+ if (d != 0 && mAdapter.getExitConditionCount() > 1) {
+ mAdapter.select(mAdapter.getExitCondition(d));
+ } else {
+ position(0, true);
+ }
+ }
+ return true;
}
}
@@ -432,21 +380,16 @@ public class ZenModeView extends RelativeLayout {
}
public interface Adapter {
- public static final int MODE_OFF = 0;
- public static final int MODE_LIMITED = 1;
- public static final int MODE_FULL = 2;
-
void configure();
void close();
- int getMode();
- void setMode(int mode);
- int getCommittedMode();
- void setCommittedMode(int mode);
+ boolean getMode();
+ void setMode(boolean mode);
void select(ExitCondition ec);
void init();
void setCallbacks(Callbacks callbacks);
ExitCondition getExitCondition(int d);
int getExitConditionCount();
+ int getExitConditionIndex();
public static class ExitCondition {
public String summary;
@@ -459,110 +402,4 @@ public class ZenModeView extends RelativeLayout {
void onChanged();
}
}
-
- private final class ModeSpinner extends Spinner {
- public ModeSpinner(final Context context) {
- super(context);
- setBackgroundResource(R.drawable.spinner_default_holo_dark_am_no_underline);
- final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(mContext, 0) {
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (DEBUG) log("getView %s parent=%s", position, parent);
- return getDropDownView(position, convertView, parent);
- }
-
- @Override
- public View getDropDownView(final int position, View convertView, ViewGroup parent) {
- if (DEBUG) log("getDropDownView %s cv=%s parent=%s",
- position, convertView, parent);
- final TextView tv = convertView != null ? (TextView) convertView
- : new TextView(context);
- final int mode = getItem(position);
- tv.setText(modeToLabel(mode));
- final boolean inDropdown = parent instanceof ListView;
- if (convertView == null) {
- if (DEBUG) log(" setting up view");
- tv.setTextColor(GRAY);
- tv.setTypeface(CONDENSED);
- tv.setAllCaps(true);
- tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.2f);
- final int p = (int) tv.getTextSize() / 2;
- if (inDropdown) {
- tv.setPadding(p, p, 0, p);
- } else {
- tv.setGravity(Gravity.CENTER_HORIZONTAL);
- tv.setPadding(p, 0, 0, 0);
- }
- }
- tv.setOnTouchListener(new OnTouchListener(){
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (DEBUG) log("onTouch %s %s inDropdown=%s", tv.getText(),
- MotionEvent.actionToString(event.getAction()), inDropdown);
- if (inDropdown && mAdapter != null) {
- mAdapter.setMode(mode);
- }
- return false;
- }
- });
- return tv;
- }
- };
- adapter.add(Adapter.MODE_LIMITED);
- adapter.add(Adapter.MODE_FULL);
- setAdapter(adapter);
- }
-
- public void updateState() {
- int mode = mAdapter != null ? mAdapter.getMode() : Adapter.MODE_LIMITED;
- if (mode == Adapter.MODE_OFF) {
- mode = Adapter.MODE_LIMITED;
- }
- if (DEBUG) log("setSelectedMode " + mode);
- for (int i = 0; i < getAdapter().getCount(); i++) {
- if (getAdapter().getItem(i).equals(mode)) {
- if (DEBUG) log(" setting selection = " + i);
- setSelection(i, true);
- onDetachedFromWindow();
- }
- }
- }
- }
-
- private final class AlarmWarning extends LinearLayout {
- public AlarmWarning(Context context) {
- super(context);
- setOrientation(HORIZONTAL);
-
- final TextView tv = new TextView(mContext);
- tv.setTextColor(GRAY);
- tv.setGravity(Gravity.TOP);
- tv.setTypeface(CONDENSED);
- tv.setText(FULL_TEXT);
- addView(tv);
-
- final ImageView icon = new ImageView(mContext);
- icon.setAlpha(.75f);
- int size = (int)tv.getTextSize();
- icon.setImageResource(android.R.drawable.ic_dialog_alert);
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(size, size);
- final int p = size / 4;
- lp.bottomMargin = lp.topMargin = lp.rightMargin = lp.leftMargin = p;
- addView(icon, 0, lp);
- setPadding(p, 0, p, p);
- }
-
- public void updateState(boolean animate) {
- final float alpha = isFull() ? 1 : 0;
- if (alpha == getAlpha()) {
- return;
- }
- if (animate) {
- animate().alpha(alpha).start();
- } else {
- setAlpha(alpha);
- requestLayout();
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
index d2067a4..c97ba8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
@@ -39,8 +39,7 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
private Callbacks mCallbacks;
private int mExitIndex;
- private int mMode;
- private int mCommittedMode;
+ private boolean mMode;
public ZenModeViewAdapter(Context context) {
mContext = context;
@@ -51,27 +50,15 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
}
@Override
- public int getMode() {
+ public boolean getMode() {
return mMode;
}
@Override
- public void setMode(int mode) {
+ public void setMode(boolean mode) {
if (mode == mMode) return;
mMode = mode;
- dispatchChanged();
- }
-
- @Override
- public int getCommittedMode() {
- return mCommittedMode;
- }
-
- @Override
- public void setCommittedMode(int mode) {
- final int v = mode == MODE_LIMITED ? Settings.Global.ZEN_MODE_LIMITED
- : mode == MODE_FULL ? Settings.Global.ZEN_MODE_FULL
- : Settings.Global.ZEN_MODE_OFF;
+ final int v = mMode ? Settings.Global.ZEN_MODE_ON : Settings.Global.ZEN_MODE_OFF;
AsyncTask.execute(new Runnable() {
@Override
public void run() {
@@ -79,6 +66,7 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
Settings.Global.ZEN_MODE, v);
}
});
+ dispatchChanged();
}
@Override
@@ -87,11 +75,6 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
mExitIndex = 0;
dispatchChanged();
}
- final int mode = mCommittedMode == MODE_FULL ? MODE_FULL : MODE_LIMITED;
- if (mode != mMode) {
- mMode = mode;
- dispatchChanged();
- }
}
private void dispatchChanged() {
@@ -122,6 +105,11 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
}
@Override
+ public int getExitConditionIndex() {
+ return mExitIndex;
+ }
+
+ @Override
public void select(ExitCondition ec) {
final int i = mExits.indexOf(ec);
if (i == -1 || i == mExitIndex) {
@@ -171,15 +159,13 @@ public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
}
private void loadSettings() {
- mCommittedMode = getModeFromSetting();
+ mMode = getModeFromSetting();
}
- private int getModeFromSetting() {
+ private boolean getModeFromSetting() {
final int v = Settings.Global.getInt(mResolver,
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
- if (v == Settings.Global.ZEN_MODE_LIMITED) return MODE_LIMITED;
- if (v == Settings.Global.ZEN_MODE_FULL) return MODE_FULL;
- return MODE_OFF;
+ return v != Settings.Global.ZEN_MODE_OFF;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
new file mode 100644
index 0000000..edac3a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -0,0 +1,816 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.stack;
+
+import android.content.Context;
+import android.content.res.Configuration;
+
+import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.OverScroller;
+
+import com.android.systemui.ExpandHelper;
+import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+
+/**
+ * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
+ */
+public class NotificationStackScrollLayout extends ViewGroup
+ implements SwipeHelper.Callback, ExpandHelper.Callback {
+
+ private static final String TAG = "NotificationStackScrollLayout";
+ private static final boolean DEBUG = false;
+
+ /**
+ * Sentinel value for no current active pointer. Used by {@link #mActivePointerId}.
+ */
+ private static final int INVALID_POINTER = -1;
+
+ private SwipeHelper mSwipeHelper;
+ private boolean mAllowScrolling = true;
+ private int mCurrentStackHeight = Integer.MAX_VALUE;
+ private int mOwnScrollY;
+ private int mMaxLayoutHeight;
+
+ private VelocityTracker mVelocityTracker;
+ private OverScroller mScroller;
+ private int mTouchSlop;
+ private int mMinimumVelocity;
+ private int mMaximumVelocity;
+ private int mOverscrollDistance;
+ private int mOverflingDistance;
+ private boolean mIsBeingDragged;
+ private int mLastMotionY;
+ private int mActivePointerId;
+
+ private int mSidePaddings;
+ private Paint mDebugPaint;
+ private int mBackgroundRoundedRectCornerRadius;
+ private int mContentHeight;
+ private int mCollapsedSize;
+ private int mBottomStackPeekSize;
+ private int mEmptyMarginBottom;
+ private int mPaddingBetweenElements;
+
+ /**
+ * The algorithm which calculates the properties for our children
+ */
+ private StackScrollAlgorithm mStackScrollAlgorithm;
+
+ /**
+ * The current State this Layout is in
+ */
+ private StackScrollState mCurrentStackScrollState;
+
+ public NotificationStackScrollLayout(Context context) {
+ this(context, null);
+ }
+
+ public NotificationStackScrollLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public NotificationStackScrollLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public NotificationStackScrollLayout(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ initView(context);
+ if (DEBUG) {
+ setWillNotDraw(false);
+ mDebugPaint = new Paint();
+ mDebugPaint.setColor(0xffff0000);
+ mDebugPaint.setStrokeWidth(2);
+ mDebugPaint.setStyle(Paint.Style.STROKE);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (DEBUG) {
+ int y = mCollapsedSize;
+ canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
+ y = (int) (getLayoutHeight() - mBottomStackPeekSize - mCollapsedSize);
+ canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
+ y = (int) getLayoutHeight();
+ canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
+ }
+ }
+
+ private void initView(Context context) {
+ mScroller = new OverScroller(getContext());
+ setFocusable(true);
+ setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
+ final ViewConfiguration configuration = ViewConfiguration.get(context);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
+ mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+ mOverscrollDistance = configuration.getScaledOverscrollDistance();
+ mOverflingDistance = configuration.getScaledOverflingDistance();
+ float densityScale = getResources().getDisplayMetrics().density;
+ float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+ mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+
+ mSidePaddings = context.getResources()
+ .getDimensionPixelSize(R.dimen.notification_side_padding);
+ mBackgroundRoundedRectCornerRadius = context.getResources()
+ .getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_quantum_rounded_rect_radius);
+ mCollapsedSize = context.getResources()
+ .getDimensionPixelSize(R.dimen.notification_row_min_height);
+ mBottomStackPeekSize = context.getResources()
+ .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
+ mEmptyMarginBottom = context.getResources().getDimensionPixelSize(
+ R.dimen.notification_stack_margin_bottom);
+ // currently the padding is in the elements themself
+ mPaddingBetweenElements = 0;
+ mStackScrollAlgorithm = new StackScrollAlgorithm(context);
+ mCurrentStackScrollState = null;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int mode = MeasureSpec.getMode(widthMeasureSpec);
+ int size = MeasureSpec.getSize(widthMeasureSpec);
+ int childMeasureSpec = MeasureSpec.makeMeasureSpec(size - 2 * mSidePaddings, mode);
+ measureChildren(childMeasureSpec, heightMeasureSpec);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+
+ // we layout all our children centered on the top
+ float centerX = getWidth() / 2.0f;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ float width = child.getMeasuredWidth();
+ float height = child.getMeasuredHeight();
+ int oldWidth = child.getWidth();
+ int oldHeight = child.getHeight();
+ child.layout((int) (centerX - width / 2.0f),
+ 0,
+ (int) (centerX + width / 2.0f),
+ (int) height);
+ updateChildOutline(child, width, height, oldWidth, oldHeight);
+ }
+ setMaxLayoutHeight(getHeight() - mEmptyMarginBottom);
+ updateScrollPositionIfNecessary();
+ updateChildren();
+ updateContentHeight();
+ }
+
+ private void setMaxLayoutHeight(int maxLayoutHeight) {
+ mMaxLayoutHeight = maxLayoutHeight;
+ updateAlgorithmHeight();
+ }
+
+ private void updateAlgorithmHeight() {
+ mStackScrollAlgorithm.setLayoutHeight(getLayoutHeight());
+ }
+
+ /**
+ * Updates the children views according to the stack scroll algorithm. Call this whenever
+ * modifications to {@link #mOwnScrollY} are performed to reflect it in the view layout.
+ */
+ private void updateChildren() {
+ if (!isCurrentlyAnimating()) {
+ if (mCurrentStackScrollState == null) {
+ mCurrentStackScrollState = new StackScrollState(this);
+ }
+ mCurrentStackScrollState.setScrollY(mOwnScrollY);
+ mStackScrollAlgorithm.getStackScrollState(mCurrentStackScrollState);
+ mCurrentStackScrollState.apply();
+ mOwnScrollY = mCurrentStackScrollState.getScrollY();
+ } else {
+ // TODO: handle animation
+ }
+ }
+
+ private boolean isCurrentlyAnimating() {
+ return false;
+ }
+
+ private void updateChildOutline(View child,
+ float width,
+ float height,
+ int oldWidth,
+ int oldHeight) {
+ // The children currently have paddings inside themselfs because of the expansion
+ // visualization. In order for the shadows to work correctly we have to set the correct
+ // outline.
+ View container = child.findViewById(R.id.container);
+ if (container != null && (oldWidth != width || oldHeight != height)) {
+ Outline outline = getOutlineForSize(container.getLeft(),
+ container.getTop(),
+ container.getWidth(),
+ container.getHeight());
+ child.setOutline(outline);
+ }
+ }
+
+ private Outline getOutlineForSize(int leftInset, int topInset, int width, int height) {
+ Outline result = new Outline();
+ result.setRoundRect(leftInset, topInset, leftInset + width, topInset + height,
+ mBackgroundRoundedRectCornerRadius);
+ return result;
+ }
+
+ private void updateScrollPositionIfNecessary() {
+ int scrollRange = getScrollRange();
+ if (scrollRange < mOwnScrollY) {
+ mOwnScrollY = scrollRange;
+ }
+ }
+
+ public void setCurrentStackHeight(int currentStackHeight) {
+ this.mCurrentStackHeight = currentStackHeight;
+ updateAlgorithmHeight();
+ updateChildren();
+ }
+
+ /**
+ * Get the current height of the view. This is at most the size of the view given by a the
+ * layout but it can also be made smaller by setting {@link #mCurrentStackHeight}
+ *
+ * @return either the layout height or the externally defined height, whichever is smaller
+ */
+ private float getLayoutHeight() {
+ return Math.min(mMaxLayoutHeight, mCurrentStackHeight);
+ }
+
+ public void setLongPressListener(View.OnLongClickListener listener) {
+ mSwipeHelper.setLongPressListener(listener);
+ }
+
+ public void onChildDismissed(View v) {
+ if (DEBUG) Log.v(TAG, "onChildDismissed: " + v);
+ final View veto = v.findViewById(R.id.veto);
+ if (veto != null && veto.getVisibility() != View.GONE) {
+ veto.performClick();
+ }
+ allowScrolling(true);
+ }
+
+ public void onBeginDrag(View v) {
+ allowScrolling(false);
+ }
+
+ public void onDragCancelled(View v) {
+ allowScrolling(true);
+ }
+
+ public View getChildAtPosition(MotionEvent ev) {
+ return getChildAtPosition(ev.getX(), ev.getY());
+ }
+
+ public View getChildAtRawPosition(float touchX, float touchY) {
+ int[] location = new int[2];
+ getLocationOnScreen(location);
+ return getChildAtPosition(touchX - location[0],touchY - location[1]);
+ }
+
+ public View getChildAtPosition(float touchX, float touchY) {
+ // find the view under the pointer, accounting for GONE views
+ final int count = getChildCount();
+ for (int childIdx = 0; childIdx < count; childIdx++) {
+ View slidingChild = getChildAt(childIdx);
+ if (slidingChild.getVisibility() == GONE) {
+ continue;
+ }
+ float top = slidingChild.getTranslationY();
+ float bottom = top + slidingChild.getMeasuredHeight();
+ int left = slidingChild.getLeft();
+ int right = slidingChild.getRight();
+
+ if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
+ return slidingChild;
+ }
+ }
+ return null;
+ }
+
+ public boolean canChildBeExpanded(View v) {
+ return v instanceof ExpandableNotificationRow
+ && ((ExpandableNotificationRow) v).isExpandable();
+ }
+
+ public void setUserExpandedChild(View v, boolean userExpanded) {
+ if (v instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) v).setUserExpanded(userExpanded);
+ }
+ }
+
+ public void setUserLockedChild(View v, boolean userLocked) {
+ if (v instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) v).setUserLocked(userLocked);
+ }
+ }
+
+ public View getChildContentView(View v) {
+ return v;
+ }
+
+ public boolean canChildBeDismissed(View v) {
+ final View veto = v.findViewById(R.id.veto);
+ return (veto != null && veto.getVisibility() != View.GONE);
+ }
+
+ private void allowScrolling(boolean allow) {
+ mAllowScrolling = allow;
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ float densityScale = getResources().getDisplayMetrics().density;
+ mSwipeHelper.setDensityScale(densityScale);
+ float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+ mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
+ initView(getContext());
+ }
+
+ public void dismissRowAnimated(View child, int vel) {
+ mSwipeHelper.dismissChild(child, vel);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ boolean scrollerWantsIt = false;
+ if (mAllowScrolling) {
+ scrollerWantsIt = onScrollTouch(ev);
+ }
+ boolean horizontalSwipeWantsIt = false;
+ if (!mIsBeingDragged) {
+ horizontalSwipeWantsIt = mSwipeHelper.onTouchEvent(ev);
+ }
+ return horizontalSwipeWantsIt || scrollerWantsIt || super.onTouchEvent(ev);
+ }
+
+ private boolean onScrollTouch(MotionEvent ev) {
+ initVelocityTrackerIfNotExists();
+ mVelocityTracker.addMovement(ev);
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ if (getChildCount() == 0) {
+ return false;
+ }
+ boolean isBeingDragged = !mScroller.isFinished();
+ setIsBeingDragged(isBeingDragged);
+ if (isBeingDragged) {
+ final ViewParent parent = getParent();
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(true);
+ }
+ }
+
+ /*
+ * If being flinged and user touches, stop the fling. isFinished
+ * will be false if being flinged.
+ */
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
+
+ // Remember where the motion event started
+ mLastMotionY = (int) ev.getY();
+ mActivePointerId = ev.getPointerId(0);
+ break;
+ }
+ case MotionEvent.ACTION_MOVE:
+ final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (activePointerIndex == -1) {
+ Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
+ break;
+ }
+
+ final int y = (int) ev.getY(activePointerIndex);
+ int deltaY = mLastMotionY - y;
+ if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
+ final ViewParent parent = getParent();
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(true);
+ }
+ setIsBeingDragged(true);
+ if (deltaY > 0) {
+ deltaY -= mTouchSlop;
+ } else {
+ deltaY += mTouchSlop;
+ }
+ }
+ if (mIsBeingDragged) {
+ // Scroll to follow the motion event
+ mLastMotionY = y;
+
+ final int oldX = mScrollX;
+ final int oldY = mOwnScrollY;
+ final int range = getScrollRange();
+ final int overscrollMode = getOverScrollMode();
+ final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS ||
+ (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
+
+ // Calling overScrollBy will call onOverScrolled, which
+ // calls onScrollChanged if applicable.
+ if (overScrollBy(0, deltaY, 0, mOwnScrollY,
+ 0, range, 0, mOverscrollDistance, true)) {
+ // Break our velocity if we hit a scroll barrier.
+ mVelocityTracker.clear();
+ }
+ // TODO: Overscroll
+// if (canOverscroll) {
+// final int pulledToY = oldY + deltaY;
+// if (pulledToY < 0) {
+// mEdgeGlowTop.onPull((float) deltaY / getHeight());
+// if (!mEdgeGlowBottom.isFinished()) {
+// mEdgeGlowBottom.onRelease();
+// }
+// } else if (pulledToY > range) {
+// mEdgeGlowBottom.onPull((float) deltaY / getHeight());
+// if (!mEdgeGlowTop.isFinished()) {
+// mEdgeGlowTop.onRelease();
+// }
+// }
+// if (mEdgeGlowTop != null
+// && (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())){
+// postInvalidateOnAnimation();
+// }
+// }
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mIsBeingDragged) {
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
+
+ if (getChildCount() > 0) {
+ if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+ fling(-initialVelocity);
+ } else {
+ if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0,
+ getScrollRange())) {
+ postInvalidateOnAnimation();
+ }
+ }
+ }
+
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ if (mIsBeingDragged && getChildCount() > 0) {
+ if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange())) {
+ postInvalidateOnAnimation();
+ }
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ final int index = ev.getActionIndex();
+ mLastMotionY = (int) ev.getY(index);
+ mActivePointerId = ev.getPointerId(index);
+ break;
+ }
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
+ break;
+ }
+ return true;
+ }
+
+ private void onSecondaryPointerUp(MotionEvent ev) {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+ MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ // TODO: Make this decision more intelligent.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mLastMotionY = (int) ev.getY(newPointerIndex);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
+
+ private void initVelocityTrackerIfNotExists() {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ }
+
+ private void recycleVelocityTracker() {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ }
+
+ private void initOrResetVelocityTracker() {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ } else {
+ mVelocityTracker.clear();
+ }
+ }
+
+ @Override
+ public void computeScroll() {
+ if (mScroller.computeScrollOffset()) {
+ // This is called at drawing time by ViewGroup.
+ int oldX = mScrollX;
+ int oldY = mOwnScrollY;
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+
+ if (oldX != x || oldY != y) {
+ final int range = getScrollRange();
+ final int overscrollMode = getOverScrollMode();
+ final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS ||
+ (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
+
+ overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, range,
+ 0, mOverflingDistance, false);
+ onScrollChanged(mScrollX, mOwnScrollY, oldX, oldY);
+
+ if (canOverscroll) {
+ // TODO: Overscroll
+// if (y < 0 && oldY >= 0) {
+// mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity());
+// } else if (y > range && oldY <= range) {
+// mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity());
+// }
+ }
+ updateChildren();
+ }
+
+ // Keep on drawing until the animation has finished.
+ postInvalidateOnAnimation();
+ }
+ }
+
+ public void customScrollBy(int y) {
+ mOwnScrollY += y;
+ updateChildren();
+ }
+
+ public void customScrollTo(int y) {
+ mOwnScrollY = y;
+ updateChildren();
+ }
+
+ @Override
+ protected void onOverScrolled(int scrollX, int scrollY,
+ boolean clampedX, boolean clampedY) {
+ // Treat animating scrolls differently; see #computeScroll() for why.
+ if (!mScroller.isFinished()) {
+ final int oldX = mScrollX;
+ final int oldY = mOwnScrollY;
+ mScrollX = scrollX;
+ mOwnScrollY = scrollY;
+ invalidateParentIfNeeded();
+ onScrollChanged(mScrollX, mOwnScrollY, oldX, oldY);
+ if (clampedY) {
+ mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange());
+ }
+ updateChildren();
+ } else {
+ customScrollTo(scrollY);
+ scrollTo(scrollX, mScrollY);
+ }
+ }
+
+ private int getScrollRange() {
+ int scrollRange = 0;
+ if (getChildCount() > 0) {
+ int contentHeight = getContentHeight();
+ scrollRange = Math.max(0,
+ contentHeight - mMaxLayoutHeight + mCollapsedSize);
+ }
+ return scrollRange;
+ }
+
+ private int getContentHeight() {
+ return mContentHeight;
+ }
+
+ private void updateContentHeight() {
+ int height = 0;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ height += child.getHeight();
+ if (i < getChildCount()-1) {
+ height += mPaddingBetweenElements;
+ }
+ }
+ mContentHeight = height;
+ }
+
+ /**
+ * Fling the scroll view
+ *
+ * @param velocityY The initial velocity in the Y direction. Positive
+ * numbers mean that the finger/cursor is moving down the screen,
+ * which means we want to scroll towards the top.
+ */
+ private void fling(int velocityY) {
+ if (getChildCount() > 0) {
+ int height = (int) getLayoutHeight();
+ int bottom = getContentHeight();
+
+ mScroller.fling(mScrollX, mOwnScrollY, 0, velocityY, 0, 0, 0,
+ Math.max(0, bottom - height), 0, height/2);
+
+ postInvalidateOnAnimation();
+ }
+ }
+
+ private void endDrag() {
+ setIsBeingDragged(false);
+
+ recycleVelocityTracker();
+
+ // TODO: Overscroll
+// if (mEdgeGlowTop != null) {
+// mEdgeGlowTop.onRelease();
+// mEdgeGlowBottom.onRelease();
+// }
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ boolean scrollWantsIt = false;
+ if (mAllowScrolling) {
+ scrollWantsIt = onInterceptTouchEventScroll(ev);
+ }
+ boolean swipeWantsIt = false;
+ if (!mIsBeingDragged) {
+ swipeWantsIt = mSwipeHelper.onInterceptTouchEvent(ev);
+ }
+ return swipeWantsIt || scrollWantsIt ||
+ super.onInterceptTouchEvent(ev);
+ }
+
+ private boolean onInterceptTouchEventScroll(MotionEvent ev) {
+ /*
+ * This method JUST determines whether we want to intercept the motion.
+ * If we return true, onMotionEvent will be called and we do the actual
+ * scrolling there.
+ */
+
+ /*
+ * Shortcut the most recurring case: the user is in the dragging
+ * state and he is moving his finger. We want to intercept this
+ * motion.
+ */
+ final int action = ev.getAction();
+ if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
+ return true;
+ }
+
+ /*
+ * Don't try to intercept touch if we can't scroll anyway.
+ */
+ if (mOwnScrollY == 0 && getScrollRange() == 0) {
+ return false;
+ }
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_MOVE: {
+ /*
+ * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
+ * whether the user has moved far enough from his original down touch.
+ */
+
+ /*
+ * Locally do absolute value. mLastMotionY is set to the y value
+ * of the down event.
+ */
+ final int activePointerId = mActivePointerId;
+ if (activePointerId == INVALID_POINTER) {
+ // If we don't have a valid id, the touch down wasn't on content.
+ break;
+ }
+
+ final int pointerIndex = ev.findPointerIndex(activePointerId);
+ if (pointerIndex == -1) {
+ Log.e(TAG, "Invalid pointerId=" + activePointerId
+ + " in onInterceptTouchEvent");
+ break;
+ }
+
+ final int y = (int) ev.getY(pointerIndex);
+ final int yDiff = Math.abs(y - mLastMotionY);
+ if (yDiff > mTouchSlop) {
+ setIsBeingDragged(true);
+ mLastMotionY = y;
+ initVelocityTrackerIfNotExists();
+ mVelocityTracker.addMovement(ev);
+ final ViewParent parent = getParent();
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(true);
+ }
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_DOWN: {
+ final int y = (int) ev.getY();
+ if (getChildAtPosition(ev.getX(), y) == null) {
+ setIsBeingDragged(false);
+ recycleVelocityTracker();
+ break;
+ }
+
+ /*
+ * Remember location of down touch.
+ * ACTION_DOWN always refers to pointer index 0.
+ */
+ mLastMotionY = y;
+ mActivePointerId = ev.getPointerId(0);
+
+ initOrResetVelocityTracker();
+ mVelocityTracker.addMovement(ev);
+ /*
+ * If being flinged and user touches the screen, initiate drag;
+ * otherwise don't. mScroller.isFinished should be false when
+ * being flinged.
+ */
+ boolean isBeingDragged = !mScroller.isFinished();
+ setIsBeingDragged(isBeingDragged);
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ /* Release the drag */
+ setIsBeingDragged(false);
+ mActivePointerId = INVALID_POINTER;
+ recycleVelocityTracker();
+ if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange())) {
+ postInvalidateOnAnimation();
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ break;
+ }
+
+ /*
+ * The only time we want to intercept motion events is if we are in the
+ * drag mode.
+ */
+ return mIsBeingDragged;
+ }
+
+ private void setIsBeingDragged(boolean isDragged) {
+ mIsBeingDragged = isDragged;
+ if (isDragged) {
+ mSwipeHelper.removeLongPressCallback();
+ }
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ super.onWindowFocusChanged(hasWindowFocus);
+ if (!hasWindowFocus) {
+ mSwipeHelper.removeLongPressCallback();
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/PiecewiseLinearIndentationFunctor.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/PiecewiseLinearIndentationFunctor.java
new file mode 100644
index 0000000..38b544f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/PiecewiseLinearIndentationFunctor.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.stack;
+
+import java.util.ArrayList;
+
+/**
+ * A Functor which interpolates the stack distance linearly based on base values.
+ * The base values are based on an interpolation between a linear function and a
+ * quadratic function
+ */
+public class PiecewiseLinearIndentationFunctor extends StackIndentationFunctor {
+
+ private final ArrayList<Float> mBaseValues;
+ private final float mLinearPart;
+
+ /**
+ * @param maxItemsInStack The maximum number of items which should be visible at the same time,
+ * i.e the function returns totalTransitionDistance for the element with
+ * index maxItemsInStack
+ * @param peekSize The visual appearance of this is how far the cards in the stack peek
+ * out below the top card and it is measured in real pixels.
+ * Note that the visual appearance does not necessarily always correspond to
+ * the actual visual distance below the top card but is a maximum,
+ * achieved when the next card just starts transitioning into the stack and
+ * the stack is full.
+ * If totalTransitionDistance is equal to this, we directly start at the peek,
+ * otherwise the first element transitions between 0 and
+ * totalTransitionDistance - peekSize.
+ * Visualization:
+ * --------------------------------------------------- ---
+ * | | |
+ * | FIRST ITEM | | <- totalTransitionDistance
+ * | | |
+ * |---------------------------------------------------| | ---
+ * |__________________SECOND ITEM______________________| | | <- peekSize
+ * |===================================================| _|_ _|_
+ *
+ * @param totalTransitionDistance The total transition distance an element has to go through
+ * @param linearPart The interpolation factor between the linear and the quadratic amount taken.
+ * This factor must be somewhere in [0 , 1]
+ */
+ PiecewiseLinearIndentationFunctor(int maxItemsInStack,
+ int peekSize,
+ int totalTransitionDistance,
+ float linearPart) {
+ super(maxItemsInStack, peekSize, totalTransitionDistance);
+ mBaseValues = new ArrayList<Float>(maxItemsInStack+1);
+ initBaseValues();
+ mLinearPart = linearPart;
+ }
+
+ private void initBaseValues() {
+ int sumOfSquares = getSumOfSquares(mMaxItemsInStack-1);
+ int totalWeight = 0;
+ mBaseValues.add(0.0f);
+ for (int i = 0; i < mMaxItemsInStack - 1; i++) {
+ totalWeight += (mMaxItemsInStack - i - 1) * (mMaxItemsInStack - i - 1);
+ mBaseValues.add((float) totalWeight / sumOfSquares);
+ }
+ }
+
+ /**
+ * Get the sum of squares up to and including n, i.e sum(i * i, 1, n)
+ *
+ * @param n the maximum square to include
+ * @return
+ */
+ private int getSumOfSquares(int n) {
+ return n * (n + 1) * (2 * n + 1) / 6;
+ }
+
+ @Override
+ public float getValue(float itemsBefore) {
+ if (mStackStartsAtPeek) {
+ // We directly start at the stack, so no initial interpolation.
+ itemsBefore++;
+ }
+ if (itemsBefore < 0) {
+ return 0;
+ } else if (itemsBefore >= mMaxItemsInStack) {
+ return mTotalTransitionDistance;
+ }
+ int below = (int) itemsBefore;
+ float partialIn = itemsBefore - below;
+
+ if (below == 0) {
+ return mDistanceToPeekStart * partialIn;
+ } else {
+ float result = mDistanceToPeekStart;
+ float progress = mBaseValues.get(below - 1) * (1 - partialIn)
+ + mBaseValues.get(below) * partialIn;
+ result += (progress * (1 - mLinearPart)
+ + (itemsBefore - 1) / (mMaxItemsInStack - 1) * mLinearPart) * mPeekSize;
+ return result;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackIndentationFunctor.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackIndentationFunctor.java
new file mode 100644
index 0000000..f72947a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackIndentationFunctor.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.stack;
+
+/**
+ * A functor which can be queried for offset given the number of items before it.
+ */
+public abstract class StackIndentationFunctor {
+
+ protected final int mTotalTransitionDistance;
+ protected final int mDistanceToPeekStart;
+ protected int mMaxItemsInStack;
+ protected int mPeekSize;
+ protected boolean mStackStartsAtPeek;
+
+ /**
+ * @param maxItemsInStack The maximum number of items which should be visible at the same time,
+ * i.e the function returns totalTransitionDistance for the element with
+ * index maxItemsInStack
+ * @param peekSize The visual appearance of this is how far the cards in the stack peek
+ * out below the top card and it is measured in real pixels.
+ * Note that the visual appearance does not necessarily always correspond to
+ * the actual visual distance below the top card but is a maximum,
+ * achieved when the next card just starts transitioning into the stack and
+ * the stack is full.
+ * If totalTransitionDistance is equal to this, we directly start at the peek,
+ * otherwise the first element transitions between 0 and
+ * totalTransitionDistance - peekSize.
+ * Visualization:
+ * --------------------------------------------------- ---
+ * | | |
+ * | FIRST ITEM | | <- totalTransitionDistance
+ * | | |
+ * |---------------------------------------------------| | ---
+ * |__________________SECOND ITEM______________________| | | <- peekSize
+ * |===================================================| _|_ _|_
+ *
+ * @param totalTransitionDistance The total transition distance an element has to go through
+ */
+ StackIndentationFunctor(int maxItemsInStack, int peekSize, int totalTransitionDistance) {
+ mTotalTransitionDistance = totalTransitionDistance;
+ mDistanceToPeekStart = mTotalTransitionDistance - peekSize;
+ mStackStartsAtPeek = mDistanceToPeekStart == 0;
+ mMaxItemsInStack = maxItemsInStack;
+ mPeekSize = peekSize;
+
+ }
+
+ public void setPeekSize(int mPeekSize) {
+ this.mPeekSize = mPeekSize;
+ }
+
+ /**
+ * Gets the offset of this Functor given a the quantity of items before it
+ *
+ * @param itemsBefore how many items are already in the stack before this element
+ * @return the offset
+ */
+ public abstract float getValue(float itemsBefore);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
new file mode 100644
index 0000000..9db4e77
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.stack;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.systemui.R;
+
+/**
+ * The Algorithm of the {@link com.android.systemui.statusbar.stack
+ * .NotificationStackScrollLayout} which can be queried for {@link com.android.systemui.statusbar
+ * .stack.StackScrollState}
+ */
+public class StackScrollAlgorithm {
+
+ private static final int MAX_ITEMS_IN_BOTTOM_STACK = 3;
+ private static final int MAX_ITEMS_IN_TOP_STACK = 3;
+
+ private int mPaddingBetweenElements;
+ private int mCollapsedSize;
+ private int mTopStackPeekSize;
+ private int mBottomStackPeekSize;
+ private int mZDistanceBetweenElements;
+ private int mZBasicHeight;
+
+ private StackIndentationFunctor mTopStackIndentationFunctor;
+ private StackIndentationFunctor mBottomStackIndentationFunctor;
+
+ private float mLayoutHeight;
+ private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
+
+ public StackScrollAlgorithm(Context context) {
+ initConstants(context);
+ }
+
+ private void initConstants(Context context) {
+
+ // currently the padding is in the elements themself
+ mPaddingBetweenElements = 0;
+ mCollapsedSize = context.getResources()
+ .getDimensionPixelSize(R.dimen.notification_row_min_height);
+ mTopStackPeekSize = context.getResources()
+ .getDimensionPixelSize(R.dimen.top_stack_peek_amount);
+ mBottomStackPeekSize = context.getResources()
+ .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
+ mZDistanceBetweenElements = context.getResources()
+ .getDimensionPixelSize(R.dimen.z_distance_between_notifications);
+ mZBasicHeight = (MAX_ITEMS_IN_BOTTOM_STACK + 1) * mZDistanceBetweenElements;
+
+ mTopStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
+ MAX_ITEMS_IN_TOP_STACK,
+ mTopStackPeekSize,
+ mCollapsedSize + mPaddingBetweenElements,
+ 0.5f);
+ mBottomStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
+ MAX_ITEMS_IN_BOTTOM_STACK,
+ mBottomStackPeekSize,
+ mBottomStackPeekSize,
+ 0.5f);
+ }
+
+
+ public void getStackScrollState(StackScrollState resultState) {
+ // The state of the local variables are saved in an algorithmState to easily subdivide it
+ // into multiple phases.
+ StackScrollAlgorithmState algorithmState = mTempAlgorithmState;
+
+ // First we reset the view states to their default values.
+ resultState.resetViewStates();
+
+ // The first element is always in there so it's initialized with 1.0f.
+ algorithmState.itemsInTopStack = 1.0f;
+ algorithmState.partialInTop = 0.0f;
+ algorithmState.lastTopStackIndex = 0;
+ algorithmState.scrollY = resultState.getScrollY();
+ algorithmState.itemsInBottomStack = 0.0f;
+
+ // Phase 1:
+ findNumberOfItemsInTopStackAndUpdateState(resultState, algorithmState);
+
+ // Phase 2:
+ updatePositionsForState(resultState, algorithmState);
+
+ // Phase 3:
+ updateZValuesForState(resultState, algorithmState);
+
+ // Write the algorithm state to the result.
+ resultState.setScrollY(algorithmState.scrollY);
+ }
+
+ /**
+ * Determine the positions for the views. This is the main part of the algorithm.
+ *
+ * @param resultState The result state to update if a change to the properties of a child occurs
+ * @param algorithmState The state in which the current pass of the algorithm is currently in
+ * and which will be updated
+ */
+ private void updatePositionsForState(StackScrollState resultState,
+ StackScrollAlgorithmState algorithmState) {
+ float stackHeight = getLayoutHeight();
+
+ // The position where the bottom stack starts.
+ float transitioningPositionStart = stackHeight - mCollapsedSize - mBottomStackPeekSize;
+
+ // The y coordinate of the current child.
+ float currentYPosition = 0.0f;
+
+ // How far in is the element currently transitioning into the bottom stack.
+ float yPositionInScrollView = 0.0f;
+
+ ViewGroup hostView = resultState.getHostView();
+ int childCount = hostView.getChildCount();
+ int numberOfElementsCompletelyIn = (int) algorithmState.itemsInTopStack;
+ for (int i = 0; i < childCount; i++) {
+ View child = hostView.getChildAt(i);
+ StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
+ childViewState.yTranslation = currentYPosition;
+ int childHeight = child.getHeight();
+ // The y position after this element
+ float nextYPosition = currentYPosition + childHeight + mPaddingBetweenElements;
+ float yPositionInScrollViewAfterElement = yPositionInScrollView
+ + childHeight
+ + mPaddingBetweenElements;
+ float scrollOffset = yPositionInScrollViewAfterElement - algorithmState.scrollY;
+ if (i < algorithmState.lastTopStackIndex) {
+ // Case 1:
+ // We are in the top Stack
+ nextYPosition = updateStateForTopStackChild(algorithmState,
+ numberOfElementsCompletelyIn,
+ i, childViewState);
+
+ } else if (i == algorithmState.lastTopStackIndex) {
+ // Case 2:
+ // First element of regular scrollview comes next, so the position is just the
+ // scrolling position
+ nextYPosition = scrollOffset;
+ } else if (nextYPosition >= transitioningPositionStart) {
+ if (currentYPosition >= transitioningPositionStart) {
+ // Case 3:
+ // According to the regular scroll view we are fully translated out of the
+ // bottom of the screen so we are fully in the bottom stack
+ nextYPosition = updateStateForChildFullyInBottomStack(algorithmState,
+ transitioningPositionStart, childViewState, childHeight);
+
+
+ } else {
+ // Case 4:
+ // According to the regular scroll view we are currently translating out of /
+ // into the bottom of the screen
+ nextYPosition = updateStateForChildTransitioningInBottom(
+ algorithmState, stackHeight, transitioningPositionStart,
+ currentYPosition, childViewState,
+ childHeight, nextYPosition);
+ }
+ }
+ currentYPosition = nextYPosition;
+ yPositionInScrollView = yPositionInScrollViewAfterElement;
+ }
+ }
+
+ private float updateStateForChildTransitioningInBottom(StackScrollAlgorithmState algorithmState,
+ float stackHeight, float transitioningPositionStart, float currentYPosition,
+ StackScrollState.ViewState childViewState, int childHeight, float nextYPosition) {
+ float newSize = transitioningPositionStart + mCollapsedSize - currentYPosition;
+ newSize = Math.min(childHeight, newSize);
+ // Transitioning element on top of bottom stack:
+ algorithmState.partialInBottom = 1.0f - (
+ (stackHeight - mBottomStackPeekSize - nextYPosition) / mCollapsedSize);
+ // Our element can be expanded, so we might even have to scroll further than
+ // mCollapsedSize
+ algorithmState.partialInBottom = Math.min(1.0f, algorithmState.partialInBottom);
+ float offset = mBottomStackIndentationFunctor.getValue(
+ algorithmState.partialInBottom);
+ nextYPosition = transitioningPositionStart + offset;
+ algorithmState.itemsInBottomStack += algorithmState.partialInBottom;
+ // TODO: only temporarily collapse
+ if (childHeight != (int) newSize) {
+ childViewState.height = (int) newSize;
+ }
+ return nextYPosition;
+ }
+
+ private float updateStateForChildFullyInBottomStack(StackScrollAlgorithmState algorithmState,
+ float transitioningPositionStart, StackScrollState.ViewState childViewState,
+ int childHeight) {
+
+ float nextYPosition;
+ algorithmState.itemsInBottomStack += 1.0f;
+ if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) {
+ // We are visually entering the bottom stack
+ nextYPosition = transitioningPositionStart
+ + mBottomStackIndentationFunctor.getValue(
+ algorithmState.itemsInBottomStack);
+ } else {
+ // we are fully inside the stack
+ if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 2) {
+ childViewState.alpha = 0.0f;
+ } else if (algorithmState.itemsInBottomStack
+ > MAX_ITEMS_IN_BOTTOM_STACK + 1) {
+ childViewState.alpha = 1.0f - algorithmState.partialInBottom;
+ }
+ nextYPosition = transitioningPositionStart + mBottomStackPeekSize;
+ }
+ // TODO: only temporarily collapse
+ if (childHeight != mCollapsedSize) {
+ childViewState.height = mCollapsedSize;
+ }
+ return nextYPosition;
+ }
+
+ private float updateStateForTopStackChild(StackScrollAlgorithmState algorithmState,
+ int numberOfElementsCompletelyIn, int i, StackScrollState.ViewState childViewState) {
+
+ float nextYPosition = 0;
+
+ // First we calculate the index relative to the current stack window of size at most
+ // {@link #MAX_ITEMS_IN_TOP_STACK}
+ int paddedIndex = i
+ - Math.max(numberOfElementsCompletelyIn - MAX_ITEMS_IN_TOP_STACK, 0);
+ if (paddedIndex >= 0) {
+ // We are currently visually entering the top stack
+ nextYPosition = mCollapsedSize + mPaddingBetweenElements -
+ mTopStackIndentationFunctor.getValue(
+ algorithmState.itemsInTopStack - i - 1);
+ if (paddedIndex == 0 && i != 0) {
+ childViewState.alpha = 1.0f - algorithmState.partialInTop;
+ }
+ } else {
+ // We are hidden behind the top card and faded out, so we can hide ourselfs
+ if (i != 0) {
+ childViewState.alpha = 0.0f;
+ }
+ }
+ return nextYPosition;
+ }
+
+ /**
+ * Find the number of items in the top stack and update the result state if needed.
+ *
+ * @param resultState The result state to update if a height change of an child occurs
+ * @param algorithmState The state in which the current pass of the algorithm is currently in
+ * and which will be updated
+ */
+ private void findNumberOfItemsInTopStackAndUpdateState(StackScrollState resultState,
+ StackScrollAlgorithmState algorithmState) {
+
+ // The y Position if the element would be in a regular scrollView
+ float yPositionInScrollView = 0.0f;
+ ViewGroup hostView = resultState.getHostView();
+ int childCount = hostView.getChildCount();
+
+ // find the number of elements in the top stack.
+ for (int i = 0; i < childCount; i++) {
+ View child = hostView.getChildAt(i);
+ StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
+ int childHeight = child.getHeight();
+ float yPositionInScrollViewAfterElement = yPositionInScrollView
+ + childHeight
+ + mPaddingBetweenElements;
+ if (yPositionInScrollView < algorithmState.scrollY) {
+ if (yPositionInScrollViewAfterElement <= algorithmState.scrollY) {
+ // According to the regular scroll view we are fully off screen
+ algorithmState.itemsInTopStack += 1.0f;
+ if (childHeight != mCollapsedSize) {
+ childViewState.height = mCollapsedSize;
+ }
+ } else {
+ // According to the regular scroll view we are partially off screen
+ // If it is expanded we have to collapse it to a new size
+ float newSize = yPositionInScrollViewAfterElement
+ - mPaddingBetweenElements
+ - algorithmState.scrollY;
+
+ // How much did we scroll into this child
+ algorithmState.partialInTop = (mCollapsedSize - newSize) / (mCollapsedSize
+ + mPaddingBetweenElements);
+
+ // Our element can be expanded, so this can get negative
+ algorithmState.partialInTop = Math.max(0.0f, algorithmState.partialInTop);
+ algorithmState.itemsInTopStack += algorithmState.partialInTop;
+ // TODO: handle overlapping sizes with end stack
+ newSize = Math.max(mCollapsedSize, newSize);
+ // TODO: only temporarily collapse
+ if (newSize != childHeight) {
+ childViewState.height = (int) newSize;
+
+ // We decrease scrollY by the same amount we made this child smaller.
+ // The new scroll position is therefore the start of the element
+ algorithmState.scrollY = (int) yPositionInScrollView;
+ resultState.setScrollY(algorithmState.scrollY);
+ }
+ if (childHeight > mCollapsedSize) {
+ // If we are just resizing this child, this element is not treated to be
+ // transitioning into the stack and therefore it is the last element in
+ // the stack.
+ algorithmState.lastTopStackIndex = i;
+ break;
+ }
+ }
+ } else {
+ algorithmState.lastTopStackIndex = i;
+
+ // We are already past the stack so we can end the loop
+ break;
+ }
+ yPositionInScrollView = yPositionInScrollViewAfterElement;
+ }
+ }
+
+ /**
+ * Calculate the Z positions for all children based on the number of items in both stacks and
+ * save it in the resultState
+ *
+ * @param resultState The result state to update the zTranslation values
+ * @param algorithmState The state in which the current pass of the algorithm is currently in
+ */
+ private void updateZValuesForState(StackScrollState resultState,
+ StackScrollAlgorithmState algorithmState) {
+ ViewGroup hostView = resultState.getHostView();
+ int childCount = hostView.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = hostView.getChildAt(i);
+ StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
+ if (i < algorithmState.itemsInTopStack) {
+ float stackIndex = algorithmState.itemsInTopStack - i;
+ stackIndex = Math.min(stackIndex, MAX_ITEMS_IN_TOP_STACK + 2);
+ childViewState.zTranslation = mZBasicHeight
+ + stackIndex * mZDistanceBetweenElements;
+ } else if (i > (childCount - 1 - algorithmState.itemsInBottomStack)) {
+ float numItemsAbove = i - (childCount - 1 - algorithmState.itemsInBottomStack);
+ float translationZ = mZBasicHeight
+ - numItemsAbove * mZDistanceBetweenElements;
+ childViewState.zTranslation = translationZ;
+ } else {
+ childViewState.zTranslation = mZBasicHeight;
+ }
+ }
+ }
+
+ public float getLayoutHeight() {
+ return mLayoutHeight;
+ }
+
+ public void setLayoutHeight(float layoutHeight) {
+ this.mLayoutHeight = layoutHeight;
+ }
+
+ class StackScrollAlgorithmState {
+
+ /**
+ * The scroll position of the algorithm
+ */
+ public int scrollY;
+
+ /**
+ * The quantity of items which are in the top stack.
+ */
+ public float itemsInTopStack;
+
+ /**
+ * how far in is the element currently transitioning into the top stack
+ */
+ public float partialInTop;
+
+ /**
+ * The last item index which is in the top stack.
+ * NOTE: In the top stack the item after the transitioning element is also in the stack!
+ * This is needed to ensure a smooth transition between the y position in the regular
+ * scrollview and the one in the stack.
+ */
+ public int lastTopStackIndex;
+
+ /**
+ * The quantity of items which are in the bottom stack.
+ */
+ public float itemsInBottomStack;
+
+ /**
+ * how far in is the element currently transitioning into the bottom stack
+ */
+ public float partialInBottom;
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
new file mode 100644
index 0000000..f72a52f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.stack;
+
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A state of a {@link com.android.systemui.statusbar.stack.NotificationStackScrollLayout} which
+ * can be applied to a viewGroup.
+ */
+public class StackScrollState {
+
+ private static final String CHILD_NOT_FOUND_TAG = "StackScrollStateNoSuchChild";
+
+ private final ViewGroup mHostView;
+ private Map<View, ViewState> mStateMap;
+ private int mScrollY;
+
+ public int getScrollY() {
+ return mScrollY;
+ }
+
+ public void setScrollY(int scrollY) {
+ this.mScrollY = scrollY;
+ }
+
+ public StackScrollState(ViewGroup hostView) {
+ mHostView = hostView;
+ mStateMap = new HashMap<View, ViewState>(mHostView.getChildCount());
+ }
+
+ public ViewGroup getHostView() {
+ return mHostView;
+ }
+
+ public void resetViewStates() {
+ int numChildren = mHostView.getChildCount();
+ for (int i = 0; i < numChildren; i++) {
+ View child = mHostView.getChildAt(i);
+ ViewState viewState = mStateMap.get(child);
+ if (viewState == null) {
+ viewState = new ViewState();
+ mStateMap.put(child, viewState);
+ }
+ // initialize with the default values of the view
+ viewState.height = child.getHeight();
+ viewState.alpha = 1.0f;
+ }
+ }
+
+
+ public ViewState getViewStateForView(View requestedView) {
+ return mStateMap.get(requestedView);
+ }
+
+ /**
+ * Apply the properties saved in {@link #mStateMap} to the children of the {@link #mHostView}.
+ * The properties are only applied if they effectively changed.
+ */
+ public void apply() {
+ int numChildren = mHostView.getChildCount();
+ for (int i = 0; i < numChildren; i++) {
+ View child = mHostView.getChildAt(i);
+ ViewState state = mStateMap.get(child);
+ if (state != null) {
+ float alpha = child.getAlpha();
+ float yTranslation = child.getTranslationY();
+ float zTranslation = child.getTranslationZ();
+ int height = child.getHeight();
+ float newAlpha = state.alpha;
+ float newYTranslation = state.yTranslation;
+ float newZTranslation = state.zTranslation;
+ int newHeight = state.height;
+ boolean becomesInvisible = newAlpha == 0.0f;
+ if (alpha != newAlpha) {
+ // apply layer type
+ boolean becomesFullyVisible = newAlpha == 1.0f;
+ boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible;
+ int layerType = child.getLayerType();
+ int newLayerType = newLayerTypeIsHardware
+ ? View.LAYER_TYPE_HARDWARE
+ : View.LAYER_TYPE_NONE;
+ if (layerType != newLayerType) {
+ child.setLayerType(newLayerType, null);
+ }
+
+ // apply alpha
+ if (!becomesInvisible) {
+ child.setAlpha(newAlpha);
+ }
+ }
+
+ // apply visibility
+ int oldVisibility = child.getVisibility();
+ int newVisibility = becomesInvisible ? View.INVISIBLE : View.VISIBLE;
+ if (newVisibility != oldVisibility) {
+ child.setVisibility(newVisibility);
+ }
+
+ // apply yTranslation
+ if (yTranslation != newYTranslation) {
+ child.setTranslationY(newYTranslation);
+ }
+
+ // apply zTranslation
+ if (zTranslation != newZTranslation) {
+ child.setTranslationZ(newZTranslation);
+ }
+
+ // apply height
+ if (height != newHeight) {
+ applyNewHeight(child, newHeight);
+ }
+ } else {
+ Log.wtf(CHILD_NOT_FOUND_TAG, "No child state was found when applying this state " +
+ "to the hostView");
+ }
+ }
+ }
+
+ private void applyNewHeight(View child, int newHeight) {
+ ViewGroup.LayoutParams lp = child.getLayoutParams();
+ lp.height = newHeight;
+ child.setLayoutParams(lp);
+ }
+
+
+ public class ViewState {
+ float alpha;
+ float yTranslation;
+ float zTranslation;
+ int height;
+ }
+}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index b84df79..2f56e62 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -158,7 +158,7 @@ class AppWidgetServiceImpl {
final int N = instances.size();
for (int i = 0; i < N; i++) {
Provider p = instances.get(i).provider;
- if (p.info != null && pkg.equals(p.info.provider.getPackageName())) {
+ if (p != null && p.info != null && pkg.equals(p.info.provider.getPackageName())) {
return true;
}
}
@@ -1751,7 +1751,8 @@ class AppWidgetServiceImpl {
for (int i = 0; i < N; i++) {
AppWidgetId id = mAppWidgetIds.get(i);
if (backupTarget.equals(id.host.packageName)
- || backupTarget.equals(id.provider.info.provider.getPackageName())) {
+ || (id.provider != null && backupTarget.equals(
+ id.provider.info.provider.getPackageName()))) {
serializeAppWidgetId(out, id);
}
}
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 19e8083..fe814fc 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -30,11 +30,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.os.Binder;
import android.os.Environment;
-import android.os.IBinder;
import android.os.RemoteException;
-import android.os.storage.IMountService;
-import android.os.ServiceManager;
-import android.os.storage.StorageManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -83,7 +79,6 @@ public class LockSettingsService extends ILockSettings.Stub {
private final Context mContext;
private LockPatternUtils mLockPatternUtils;
- private boolean mFirstCallToVold;
public LockSettingsService(Context context) {
mContext = context;
@@ -91,7 +86,6 @@ public class LockSettingsService extends ILockSettings.Stub {
mOpenHelper = new DatabaseHelper(mContext);
mLockPatternUtils = new LockPatternUtils(context);
- mFirstCallToVold = true;
}
public void systemReady() {
@@ -353,33 +347,6 @@ public class LockSettingsService extends ILockSettings.Stub {
}
@Override
- public boolean checkVoldPassword(int userId) throws RemoteException {
- if (!mFirstCallToVold) {
- return false;
- }
- mFirstCallToVold = false;
-
- checkPasswordReadPermission(userId);
-
- // There's no guarantee that this will safely connect, but if it fails
- // we will simply show the lock screen when we shouldn't, so relatively
- // benign. There is an outside chance something nasty would happen if
- // this service restarted before vold stales out the password in this
- // case. The nastiness is limited to not showing the lock screen when
- // we should, within the first minute of decrypting the phone if this
- // service can't connect to vold, it restarts, and then the new instance
- // does successfully connect.
- final IMountService service = getMountService();
- String password = service.getPassword();
- service.clearPassword();
- if (service.getPasswordType() == StorageManager.CRYPT_TYPE_PATTERN) {
- return checkPattern(password, userId);
- } else {
- return checkPassword(password, userId);
- }
- }
-
- @Override
public void removeUser(int userId) {
checkWritePermission(userId);
@@ -557,12 +524,4 @@ public class LockSettingsService extends ILockSettings.Stub {
Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
Secure.LOCK_SCREEN_OWNER_INFO
};
-
- private IMountService getMountService() {
- final IBinder service = ServiceManager.getService("mount");
- if (service != null) {
- return IMountService.Stub.asInterface(service);
- }
- return null;
- }
}
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index b6e0d5f..cd74fed 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -74,7 +74,6 @@ import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.codec.DecoderException;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
@@ -574,14 +573,6 @@ class MountService extends IMountService.Stub
}
}
- private boolean isReady() {
- try {
- return mConnectedSignal.await(0, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- return false;
- }
- }
-
private void handleSystemReady() {
// Snapshot current volume states since it's not safe to call into vold
// while holding locks.
@@ -2090,19 +2081,6 @@ class MountService extends IMountService.Stub
return new String(Hex.encodeHex(bytes));
}
- private String fromHex(String hexPassword) {
- if (hexPassword == null) {
- return null;
- }
-
- try {
- byte[] bytes = Hex.decodeHex(hexPassword.toCharArray());
- return new String(bytes, StandardCharsets.UTF_8);
- } catch (DecoderException e) {
- return null;
- }
- }
-
@Override
public int decryptStorage(String password) {
if (TextUtils.isEmpty(password)) {
@@ -2252,35 +2230,6 @@ class MountService extends IMountService.Stub
}
@Override
- public String getPassword() throws RemoteException {
- if (!isReady()) {
- return new String();
- }
-
- final NativeDaemonEvent event;
- try {
- event = mConnector.execute("cryptfs", "getpw");
- return fromHex(event.getMessage());
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
- }
- }
-
- @Override
- public void clearPassword() throws RemoteException {
- if (!isReady()) {
- return;
- }
-
- final NativeDaemonEvent event;
- try {
- event = mConnector.execute("cryptfs", "clearpw");
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
- }
- }
-
- @Override
public int mkdirs(String callingPkg, String appPath) {
final int userId = UserHandle.getUserId(Binder.getCallingUid());
final UserEnvironment userEnv = new UserEnvironment(userId);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 3db3a26..36e53a3 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1189,6 +1189,7 @@ final class ActivityStack {
// At this point, nothing else needs to be shown
if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
behindFullscreen = true;
+ showHomeBehindStack = false;
} else if (isActivityOverHome(r)) {
if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
showHomeBehindStack = true;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 00813c5..e25e42c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -763,7 +763,7 @@ public class NotificationManagerService extends SystemService {
}
}
- private NotificationListenerInfo checkListenerToken(INotificationListener listener) {
+ private NotificationListenerInfo checkListenerTokenLocked(INotificationListener listener) {
checkNullListener(listener);
final IBinder token = listener.asBinder();
final int N = mListeners.size();
@@ -927,7 +927,9 @@ public class NotificationManagerService extends SystemService {
@Override
public void onClearAll(int callingUid, int callingPid, int userId) {
- cancelAll(callingUid, callingPid, userId, REASON_DELEGATE_CANCEL_ALL, null);
+ synchronized (mNotificationList) {
+ cancelAllLocked(callingUid, callingPid, userId, REASON_DELEGATE_CANCEL_ALL, null);
+ }
}
@Override
@@ -1553,13 +1555,15 @@ public class NotificationManagerService extends SystemService {
*/
@Override
public void cancelAllNotificationsFromListener(INotificationListener token) {
- NotificationListenerInfo info = checkListenerToken(token);
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
- cancelAll(callingUid, callingPid, info.userid,
- REASON_LISTENER_CANCEL_ALL, info);
+ synchronized (mNotificationList) {
+ NotificationListenerInfo info = checkListenerTokenLocked(token);
+ cancelAllLocked(callingUid, callingPid, info.userid,
+ REASON_LISTENER_CANCEL_ALL, info);
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1575,15 +1579,17 @@ public class NotificationManagerService extends SystemService {
@Override
public void cancelNotificationFromListener(INotificationListener token, String pkg,
String tag, int id) {
- NotificationListenerInfo info = checkListenerToken(token);
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
- cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
- Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
- true,
- info.userid, REASON_LISTENER_CANCEL, info);
+ synchronized (mNotificationList) {
+ NotificationListenerInfo info = checkListenerTokenLocked(token);
+ cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
+ Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+ true,
+ info.userid, REASON_LISTENER_CANCEL, info);
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1599,11 +1605,9 @@ public class NotificationManagerService extends SystemService {
@Override
public StatusBarNotification[] getActiveNotificationsFromListener(
INotificationListener token) {
- NotificationListenerInfo info = checkListenerToken(token);
-
- StatusBarNotification[] result = new StatusBarNotification[0];
- ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>();
synchronized (mNotificationList) {
+ NotificationListenerInfo info = checkListenerTokenLocked(token);
+ ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>();
final int N = mNotificationList.size();
for (int i=0; i<N; i++) {
StatusBarNotification sbn = mNotificationList.get(i).sbn;
@@ -1611,8 +1615,8 @@ public class NotificationManagerService extends SystemService {
list.add(sbn);
}
}
+ return list.toArray(new StatusBarNotification[list.size()]);
}
- return list.toArray(result);
}
@Override
@@ -2446,29 +2450,26 @@ public class NotificationManagerService extends SystemService {
}
}
- void cancelAll(int callingUid, int callingPid, int userId, int reason,
+ void cancelAllLocked(int callingUid, int callingPid, int userId, int reason,
NotificationListenerInfo listener) {
EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
null, userId, 0, 0, reason,
listener == null ? null : listener.component.toShortString());
- synchronized (mNotificationList) {
- final int N = mNotificationList.size();
- for (int i=N-1; i>=0; i--) {
- NotificationRecord r = mNotificationList.get(i);
+ final int N = mNotificationList.size();
+ for (int i=N-1; i>=0; i--) {
+ NotificationRecord r = mNotificationList.get(i);
- if (!notificationMatchesUserIdOrRelated(r, userId)) {
- continue;
- }
-
- if ((r.getFlags() & (Notification.FLAG_ONGOING_EVENT
- | Notification.FLAG_NO_CLEAR)) == 0) {
- mNotificationList.remove(i);
- cancelNotificationLocked(r, true);
- }
+ if (!notificationMatchesUserIdOrRelated(r, userId)) {
+ continue;
}
- updateLightsLocked();
+ if ((r.getFlags() & (Notification.FLAG_ONGOING_EVENT
+ | Notification.FLAG_NO_CLEAR)) == 0) {
+ mNotificationList.remove(i);
+ cancelNotificationLocked(r, true);
+ }
}
+ updateLightsLocked();
}
// lock on mNotificationList
@@ -2558,7 +2559,7 @@ public class NotificationManagerService extends SystemService {
exceptionPackages);
// alarm restrictions
- final boolean muteAlarms = mZenMode == Settings.Global.ZEN_MODE_FULL;
+ final boolean muteAlarms = false; // TODO until we save user config
mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, AudioManager.STREAM_ALARM,
muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
exceptionPackages);
@@ -2595,10 +2596,8 @@ public class NotificationManagerService extends SystemService {
}
private boolean shouldIntercept(String pkg, Notification n) {
- if (mZenMode == Settings.Global.ZEN_MODE_LIMITED) {
+ if (mZenMode != Settings.Global.ZEN_MODE_OFF) {
return !isAlarm(pkg, n);
- } else if (mZenMode == Settings.Global.ZEN_MODE_FULL) {
- return true;
}
return false;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a01c586..a07ad5a 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -69,6 +69,7 @@ import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
@@ -340,7 +341,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// Lock for state used when installing and doing other long running
// operations. Methods that must be called with this lock held have
- // the prefix "LI".
+ // the suffix "LI".
final Object mInstallLock = new Object();
// These are the directories in the 3rd party applications installed dir
@@ -916,6 +917,14 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.i(TAG, "Observer no longer exists.");
}
}
+ if (args.observer2 != null) {
+ try {
+ Bundle extras = extrasForInstallResult(res);
+ args.observer2.packageInstalled(res.name, extras, res.returnCode);
+ } catch (RemoteException e) {
+ Slog.i(TAG, "Observer no longer exists.");
+ }
+ }
} else {
Slog.e(TAG, "Bogus post-install token " + msg.arg1);
}
@@ -1044,6 +1053,21 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ Bundle extrasForInstallResult(PackageInstalledInfo res) {
+ Bundle extras = null;
+ switch (res.returnCode) {
+ case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
+ extras = new Bundle();
+ extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
+ res.origPermission);
+ extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
+ res.origPackage);
+ break;
+ }
+ }
+ return extras;
+ }
+
void scheduleWriteSettingsLocked() {
if (!mHandler.hasMessages(WRITE_SETTINGS)) {
mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
@@ -6772,18 +6796,24 @@ public class PackageManagerService extends IPackageManager.Stub {
private final boolean mIsPrivileged;
}
+ /*
+ * The old-style observer methods all just trampoline to the newer signature with
+ * expanded install observer API. The older API continues to work but does not
+ * supply the additional details of the Observer2 API.
+ */
+
/* Called when a downloaded package installation has been confirmed by the user */
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
- installPackage(packageURI, observer, flags, null);
+ installPackageEtc(packageURI, observer, null, flags, null);
}
/* Called when a downloaded package installation has been confirmed by the user */
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags,
final String installerPackageName) {
- installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
- null, null);
+ installPackageWithVerificationEtc(packageURI, observer, null, flags,
+ installerPackageName, null, null, null);
}
@Override
@@ -6792,20 +6822,67 @@ public class PackageManagerService extends IPackageManager.Stub {
ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
VerificationParams.NO_UID, manifestDigest);
- installPackageWithVerificationAndEncryption(packageURI, observer, flags,
+ installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null, flags,
installerPackageName, verificationParams, encryptionParams);
}
public void installPackageWithVerificationAndEncryption(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null, flags,
+ installerPackageName, verificationParams, encryptionParams);
+ }
+
+ /*
+ * And here are the "live" versions that take both observer arguments
+ */
+ public void installPackageEtc(
+ final Uri packageURI, final IPackageInstallObserver observer,
+ IPackageInstallObserver2 observer2, final int flags) {
+ installPackageEtc(packageURI, observer, observer2, flags, null);
+ }
+
+ public void installPackageEtc(
+ final Uri packageURI, final IPackageInstallObserver observer,
+ final IPackageInstallObserver2 observer2, final int flags,
+ final String installerPackageName) {
+ installPackageWithVerificationEtc(packageURI, observer, observer2, flags,
+ installerPackageName, null, null, null);
+ }
+
+ @Override
+ public void installPackageWithVerificationEtc(Uri packageURI, IPackageInstallObserver observer,
+ IPackageInstallObserver2 observer2,
+ int flags, String installerPackageName, Uri verificationURI,
+ ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
+ VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
+ VerificationParams.NO_UID, manifestDigest);
+ installPackageWithVerificationAndEncryptionEtc(packageURI, observer, observer2, flags,
+ installerPackageName, verificationParams, encryptionParams);
+ }
+
+ /*
+ * All of the installPackage...*() methods redirect to this one for the master implementation
+ */
+ public void installPackageWithVerificationAndEncryptionEtc(Uri packageURI,
+ IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
+ int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ if (observer == null && observer2 == null) {
+ throw new IllegalArgumentException("No install observer supplied");
+ }
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
null);
final int uid = Binder.getCallingUid();
if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
try {
- observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
+ if (observer != null) {
+ observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
+ }
+ if (observer2 != null) {
+ observer2.packageInstalled("", null, PackageManager.INSTALL_FAILED_USER_RESTRICTED);
+ }
} catch (RemoteException re) {
}
return;
@@ -6832,8 +6909,8 @@ public class PackageManagerService extends IPackageManager.Stub {
verificationParams.setInstallerUid(uid);
final Message msg = mHandler.obtainMessage(INIT_COPY);
- msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
- verificationParams, encryptionParams, user);
+ msg.obj = new InstallParams(packageURI, observer, observer2, filteredFlags,
+ installerPackageName, verificationParams, encryptionParams, user);
mHandler.sendMessage(msg);
}
@@ -7522,6 +7599,7 @@ public class PackageManagerService extends IPackageManager.Stub {
class InstallParams extends HandlerParams {
final IPackageInstallObserver observer;
+ final IPackageInstallObserver2 observer2;
int flags;
private final Uri mPackageURI;
@@ -7533,13 +7611,14 @@ public class PackageManagerService extends IPackageManager.Stub {
final ContainerEncryptionParams encryptionParams;
InstallParams(Uri packageURI,
- IPackageInstallObserver observer, int flags,
- String installerPackageName, VerificationParams verificationParams,
+ IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
+ int flags, String installerPackageName, VerificationParams verificationParams,
ContainerEncryptionParams encryptionParams, UserHandle user) {
super(user);
this.mPackageURI = packageURI;
this.flags = flags;
this.observer = observer;
+ this.observer2 = observer2;
this.installerPackageName = installerPackageName;
this.verificationParams = verificationParams;
this.encryptionParams = encryptionParams;
@@ -8109,6 +8188,7 @@ public class PackageManagerService extends IPackageManager.Stub {
static abstract class InstallArgs {
final IPackageInstallObserver observer;
+ final IPackageInstallObserver2 observer2;
// Always refers to PackageManager flags only
final int flags;
final Uri packageURI;
@@ -8116,12 +8196,14 @@ public class PackageManagerService extends IPackageManager.Stub {
final ManifestDigest manifestDigest;
final UserHandle user;
- InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
- String installerPackageName, ManifestDigest manifestDigest,
+ InstallArgs(Uri packageURI,
+ IPackageInstallObserver observer, IPackageInstallObserver2 observer2,
+ int flags, String installerPackageName, ManifestDigest manifestDigest,
UserHandle user) {
this.packageURI = packageURI;
this.flags = flags;
this.observer = observer;
+ this.observer2 = observer2;
this.installerPackageName = installerPackageName;
this.manifestDigest = manifestDigest;
this.user = user;
@@ -8178,13 +8260,13 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean created = false;
FileInstallArgs(InstallParams params) {
- super(params.getPackageUri(), params.observer, params.flags,
+ super(params.getPackageUri(), params.observer, params.observer2, params.flags,
params.installerPackageName, params.getManifestDigest(),
params.getUser());
}
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
- super(null, null, 0, null, null, null);
+ super(null, null, null, 0, null, null, null);
File codeFile = new File(fullCodePath);
installDir = codeFile.getParentFile();
codeFileName = fullCodePath;
@@ -8193,7 +8275,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
- super(packageURI, null, 0, null, null, null);
+ super(packageURI, null, null, 0, null, null, null);
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
String apkName = getNextCodePath(null, pkgName, ".apk");
codeFileName = new File(installDir, apkName + ".apk").getPath();
@@ -8514,14 +8596,14 @@ public class PackageManagerService extends IPackageManager.Stub {
String libraryPath;
AsecInstallArgs(InstallParams params) {
- super(params.getPackageUri(), params.observer, params.flags,
+ super(params.getPackageUri(), params.observer, params.observer2, params.flags,
params.installerPackageName, params.getManifestDigest(),
params.getUser());
}
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
boolean isExternal, boolean isForwardLocked) {
- super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
+ super(null, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
null, null, null);
// Extract cid from fullCodePath
@@ -8533,7 +8615,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
AsecInstallArgs(String cid, boolean isForwardLocked) {
- super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
+ super(null, null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
null, null, null);
this.cid = cid;
@@ -8541,7 +8623,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
- super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
+ super(packageURI, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
null, null, null);
this.cid = cid;
@@ -8875,6 +8957,10 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Package pkg;
int returnCode;
PackageRemovedInfo removedInfo;
+
+ // In some error cases we want to convey more info back to the observer
+ String origPackage;
+ String origPermission;
}
/*
@@ -9299,6 +9385,27 @@ public class PackageManagerService extends IPackageManager.Stub {
String oldCodePath = null;
boolean systemApp = false;
synchronized (mPackages) {
+ // Check whether the newly-scanned package wants to define an already-defined perm
+ int N = pkg.permissions.size();
+ for (int i = 0; i < N; i++) {
+ PackageParser.Permission perm = pkg.permissions.get(i);
+ BasePermission bp = mSettings.mPermissions.get(perm.info.name);
+ if (bp != null) {
+ // If the defining package is signed with our cert, it's okay. This
+ // also includes the "updating the same package" case, of course.
+ if (compareSignatures(bp.packageSetting.signatures.mSignatures,
+ pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
+ Slog.w(TAG, "Package " + pkg.packageName
+ + " attempting to redeclare permission " + perm.info.name
+ + " already owned by " + bp.sourcePackage);
+ res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
+ res.origPermission = perm.info.name;
+ res.origPackage = bp.sourcePackage;
+ return;
+ }
+ }
+ }
+
// Check if installing already existing package
if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
String oldName = mSettings.mRenamedPackages.get(pkgName);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 9236bde..37547f2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1477,6 +1477,7 @@ final class Settings {
// FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
// system/core/run-as/run-as.c
// system/core/sdcard/sdcard.c
+ // external/libselinux/src/android.c:package_info_init()
//
sb.setLength(0);
sb.append(ai.packageName);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0558b5a..dcf5880 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -920,6 +920,10 @@ public class WindowManagerService extends IWindowManager.Stub
final IWindow client = win.mClient;
final WindowToken token = win.mToken;
final DisplayContent displayContent = win.getDisplayContent();
+ if (displayContent == null) {
+ // It doesn't matter this display is going away.
+ return 0;
+ }
final WindowList windows = win.getWindowList();
final int N = windows.size();
@@ -1097,6 +1101,9 @@ public class WindowManagerService extends IWindowManager.Stub
private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
final WindowToken token = win.mToken;
final DisplayContent displayContent = win.getDisplayContent();
+ if (displayContent == null) {
+ return;
+ }
final WindowState attached = win.mAttachedWindow;
WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
@@ -2254,6 +2261,11 @@ public class WindowManagerService extends IWindowManager.Stub
return WindowManagerGlobal.ADD_APP_EXITING;
}
+ if (win.getDisplayContent() == null) {
+ Slog.w(TAG, "Adding window to Display that has been removed.");
+ return WindowManagerGlobal.ADD_INVALID_DISPLAY;
+ }
+
mPolicy.adjustWindowParamsLw(win.mAttrs);
win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
@@ -2743,7 +2755,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
- final DisplayInfo displayInfo = window.getDisplayContent().getDisplayInfo();
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
final RectF dispRect = new RectF(0, 0,
displayInfo.logicalWidth, displayInfo.logicalHeight);
matrix.mapRect(dispRect);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 6b3c368..3c9d53e 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -176,9 +176,15 @@ class WindowStateAnimator {
mAnimator = service.mAnimator;
mPolicy = service.mPolicy;
mContext = service.mContext;
- final DisplayInfo displayInfo = win.getDisplayContent().getDisplayInfo();
- mAnimDw = displayInfo.appWidth;
- mAnimDh = displayInfo.appHeight;
+ final DisplayContent displayContent = win.getDisplayContent();
+ if (displayContent != null) {
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ mAnimDw = displayInfo.appWidth;
+ mAnimDh = displayInfo.appHeight;
+ } else {
+ Slog.w(TAG, "WindowStateAnimator ctor: Display has been removed");
+ // This is checked on return and dealt with.
+ }
mWin = win;
mAttachedWinAnimator = win.mAttachedWindow == null
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index c26a516..a58b00bce 100644
--- a/services/core/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/core/jni/com_android_server_AlarmManagerService.cpp
@@ -365,7 +365,9 @@ static void android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativ
int result = impl->set(type, &ts);
if (result < 0)
{
- ALOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));
+ ALOGE("Unable to set alarm to %lld.%09lld: %s\n",
+ static_cast<long long>(seconds),
+ static_cast<long long>(nanoseconds), strerror(errno));
}
}
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 118cba4..daef37a 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -16,6 +16,7 @@
package android.test.mock;
+import android.app.PackageInstallObserver;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
@@ -664,4 +665,34 @@ public class MockPackageManager extends PackageManager {
public VerifierDeviceIdentity getVerifierDeviceIdentity() {
throw new UnsupportedOperationException();
}
+
+ /**
+ * @hide
+ */
+ @Override
+ public void installPackage(Uri packageURI, PackageInstallObserver observer,
+ int flags, String installerPackageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void installPackageWithVerification(Uri packageURI,
+ PackageInstallObserver observer, int flags, String installerPackageName,
+ Uri verificationURI, ManifestDigest manifestDigest,
+ ContainerEncryptionParams encryptionParams) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ PackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/tests/DynamicDrawableTest/Android.mk b/tests/DynamicDrawableTest/Android.mk
new file mode 100644
index 0000000..5c51301
--- /dev/null
+++ b/tests/DynamicDrawableTest/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := DynamicDrawableTest
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_PACKAGE)
diff --git a/tests/DynamicDrawableTest/AndroidManifest.xml b/tests/DynamicDrawableTest/AndroidManifest.xml
new file mode 100644
index 0000000..4ca3e3c
--- /dev/null
+++ b/tests/DynamicDrawableTest/AndroidManifest.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.test.dynamic" >
+ <uses-sdk android:minSdkVersion="11" />
+
+ <application
+ android:hardwareAccelerated="true"
+ android:label="vector" >
+ <activity
+ android:name="VectorDrawableTest"
+ android:label="Vector Icon" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="VectorDrawable01"
+ android:label="VectorTest1" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name="VectorDrawablePerformance"
+ android:label="Vector Performance" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+
+ <activity
+ android:name="VectorDrawableDupPerf"
+ android:label="Vector Performance of clones" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+ <activity
+ android:name="VectorDrawableStaticPerf"
+ android:label="Performance of vector images" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+
+ <activity
+ android:name="VectorCheckbox"
+ android:label="On a Checkbox" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+ <activity
+ android:name="VectorPathChecking"
+ android:label="Path Checking graphics" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+ </application>
+
+</manifest> \ No newline at end of file
diff --git a/tests/DynamicDrawableTest/lint.xml b/tests/DynamicDrawableTest/lint.xml
new file mode 100644
index 0000000..ee0eead
--- /dev/null
+++ b/tests/DynamicDrawableTest/lint.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint> \ No newline at end of file
diff --git a/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png b/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..60fbdf5
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/tests/DynamicDrawableTest/res/drawable/icon.png b/tests/DynamicDrawableTest/res/drawable/icon.png
new file mode 100644
index 0000000..cb40a19
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/icon.png
Binary files differ
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml
new file mode 100644
index 0000000..4f4b386
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml
@@ -0,0 +1,73 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:trigger="state_checked" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="480"
+ android:viewportWidth="480" />
+
+ <group>
+ <path
+ android:name="check"
+ android:pathData="m20,200l100,90l180,-180l-35,-35l-145,145l-60,-60l-40,40z"
+ android:fill="#ffff00ff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="5" />
+ </group>
+ <group>
+ <path
+ android:name="box1"
+ android:pathData="m127,171l37,38l33,-31l-37,-40l-1,3l-2,0l-30,30z"
+ android:fill="#ffffffff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="5" />
+ </group>
+ <group>
+ <path
+ android:name="box2"
+ android:pathData="m127,171l37,38l33,-31l-37,-40l-1,3l-2,0l-30,30z"
+ android:fill="#ff000000"
+ android:rotation="46.757"
+ android:pivotX="162"
+ android:pivotY="173.5"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="5" />
+ </group>
+ <group>
+ <path
+ android:name="box3"
+ android:pathData="m187,147l-1,55l-49,-1l2,-53l48,0z"
+ android:stroke="#FF000000"
+ android:strokeWidth="4" />
+ </group>
+ <group>
+ <path
+ android:name="box4"
+ android:pathData="m248,74l0,164l-177,0l1,-165l173,-1l3,2z"
+ android:stroke="#FF000000"
+ android:strokeWidth="30" />
+ </group>
+
+ <animation
+ android:durations="300,100,0,300"
+ android:sequence="check,box1,box2,box3,box4" />
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml
new file mode 100644
index 0000000..49906d17
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml
@@ -0,0 +1,46 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="320"
+ android:viewportHeight="320"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M 100,225 L 100,115 L 130,115 L 70,15 L 10,115 L 40,115 L 40,225 z"
+ android:fill="#ffffffff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M 130,225 L 130,115 L 130,115 L 70,15 L 10,115 L 10,115 L 10,225 z"
+ android:fill="#ff440000"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="180"
+ android:pivotX="70"
+ android:pivotY="120"
+ android:trimPathStart=".1"
+ android:trimPathEnd=".9"/>
+ </group>
+ <animation android:sequence="arrow,house"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml
new file mode 100644
index 0000000..137049d
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml
@@ -0,0 +1,137 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="7.30625"
+ android:viewportHeight="12.25"/>
+
+ <group>
+
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 0
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 12.25
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+ <group>
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 12.25
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 0, 12.25
+ l 7.3, 0
+ l 0, 12.25
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+
+
+ <animation
+ android:sequence="one,one"
+ android:durations="4000"/>
+ <animation
+ android:sequence="two,two"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip1,clip1"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip2,clip2"
+ android:durations="4000"/>
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml
new file mode 100644
index 0000000..cffb73f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml
@@ -0,0 +1,126 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="7.30625"
+ android:viewportHeight="12.25"/>
+
+ <group>
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 3.65, 6.125
+ m -.001, 0
+ a .001,.001 0 1,0 .002,0
+ a .001,.001 0 1,0 -.002,0z"
+ android:clipToPath="true"
+ android:fill="#112233"
+ />
+
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 3.65, 6.125
+ m -6, 0
+ a 6,6 0 1,0 12,0
+ a 6,6 0 1,0 -12,0z"
+ android:clipToPath="true"
+ android:fill="#112233"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+ <group>
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 3.65, 6.125
+ m -6, 0
+ a 6,6 0 1,0 12,0
+ a 6,6 0 1,0 -12,0z"
+ android:clipToPath="true"
+ android:fill="#332233"
+ />
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 3.65, 6.125
+ m -.001, 0
+ a .001,.001 0 1,0 .002,0
+ a .001,.001 0 1,0 -.002,0z"
+ android:clipToPath="true"
+ android:fill="#662233"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+
+
+
+ <animation
+ android:sequence="one,one"
+ android:durations="4000"/>
+ <animation
+ android:sequence="two,two"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip1,clip1"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip2,clip2"
+ android:durations="4000"/>
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml
new file mode 100644
index 0000000..bcf3ae6
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml
@@ -0,0 +1,147 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="7.30625"
+ android:viewportHeight="12.25"/>
+
+ <group>
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ffff00"
+ />
+
+
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ </group>
+ <group>
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ />
+ </group>
+ <group>
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ />
+ <path
+ android:name="three"
+ android:pathData="M 5.103125,6.003125q 0.84375,0.1875 1.3125,0.765625 0.484375,0.5625 0.484375,1.40625
+ q 0.0,1.296875 -0.890625,2.015625 -0.890625,0.703125 -2.53125,0.703125
+ q -0.546875,0.0 -1.140625,-0.109375 -0.5781251,-0.109375 -1.1875001,-0.328125
+ l 0.0,-1.140625q 0.484375,0.28125 1.0625001,0.4375 0.59375,0.140625 1.234375,0.140625
+ q 1.109375,0.0 1.6875,-0.4375 0.59375,-0.4375 0.59375,-1.28125
+ q 0.0,-0.765625 -0.546875,-1.203125 -0.546875,-0.4375 -1.5,-0.4375
+ l -1.03125,0.0 0.0,-0.96875 1.078125,0.0q 0.859375,0.0 1.328125,-0.34375
+ q 0.46875,-0.359375 0.46875,-1.015625 0.0,-0.671875 -0.484375,-1.03125
+ q -0.46875,-0.359375 -1.359375,-0.359375 -0.5,0.0 -1.0625,0.109375
+ q -0.546875,0.09375 -1.2187501,0.3125l 0.0,-1.046875q 0.6875001,-0.1875 1.2656251,-0.28125
+ q 0.59375,-0.09375 1.109375,-0.09375 1.359375,0.0 2.140625,0.609375
+ q 0.78125,0.609375 0.78125,1.65625 0.0,0.734375 -0.421875,1.234375
+ q -0.40625,0.5 -1.171875,0.6875Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ </group>
+ <group>
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ <path
+ android:name="three"
+ android:pathData="M 5.103125,6.003125q 0.84375,0.1875 1.3125,0.765625 0.484375,0.5625 0.484375,1.40625
+ q 0.0,1.296875 -0.890625,2.015625 -0.890625,0.703125 -2.53125,0.703125
+ q -0.546875,0.0 -1.140625,-0.109375 -0.5781251,-0.109375 -1.1875001,-0.328125
+ l 0.0,-1.140625q 0.484375,0.28125 1.0625001,0.4375 0.59375,0.140625 1.234375,0.140625
+ q 1.109375,0.0 1.6875,-0.4375 0.59375,-0.4375 0.59375,-1.28125
+ q 0.0,-0.765625 -0.546875,-1.203125 -0.546875,-0.4375 -1.5,-0.4375
+ l -1.03125,0.0 0.0,-0.96875 1.078125,0.0q 0.859375,0.0 1.328125,-0.34375
+ q 0.46875,-0.359375 0.46875,-1.015625 0.0,-0.671875 -0.484375,-1.03125
+ q -0.46875,-0.359375 -1.359375,-0.359375 -0.5,0.0 -1.0625,0.109375
+ q -0.546875,0.09375 -1.2187501,0.3125l 0.0,-1.046875q 0.6875001,-0.1875 1.2656251,-0.28125
+ q 0.59375,-0.09375 1.109375,-0.09375 1.359375,0.0 2.140625,0.609375
+ q 0.78125,0.609375 0.78125,1.65625 0.0,0.734375 -0.421875,1.234375
+ q -0.40625,0.5 -1.171875,0.6875Z"
+ android:fill="#ffff00"
+ />
+ </group>
+
+
+ <animation
+ android:sequence="one,one,three,three"
+ android:durations="2000,0,2000"/>
+ <animation
+ android:sequence="two,two,two,two"
+ android:durations="2000,0,2000"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml
new file mode 100644
index 0000000..73ff5e2
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml
@@ -0,0 +1,76 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="700"
+ android:viewportHeight="700"/>
+
+ <group>
+ </group>
+ <path android:pathData="M 569.374 461.472L 569.374 160.658L 160.658 160.658L 160.658 461.472L 569.374 461.472z"
+ android:name="path2451"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.65500000000000"/>
+ <path android:pathData="M 365.015 311.066"
+ android:name="path2453"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 164.46 164.49L 340.78 343.158C 353.849 356.328 377.63 356.172 390.423 343.278L 566.622 165.928"
+ android:name="path2455"
+ android:stroke="#FF000000"
+ android:fill="#FF0000FF"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 170.515 451.566L 305.61 313.46"
+ android:name="path2457"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 557.968 449.974L 426.515 315.375"
+ android:name="path2459"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ <group>
+ <path android:pathData="M 569.374 461.472L 569.374 160.658L 160.658 160.658L 160.658 461.472L 569.374 461.472z"
+ android:name="path2451"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.65500000000000"/>
+ <path android:pathData="M 365.015 311.066"
+ android:name="path2453"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 164.46 164.49L 340.78 343.158C 353.849 356.328 377.63 356.172 390.423 343.278L 566.622 165.928"
+ android:name="path2455"
+ android:stroke="#FF000000"
+ android:fill="#FFFFFFFF"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 170.515 451.566L 305.61 313.46"
+ android:name="path2457"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 557.968 449.974L 426.515 315.375"
+ android:name="path2459"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ </group>
+
+ <animation android:sequence="path2451,path2451"
+ android:durations="1000"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml
new file mode 100644
index 0000000..99d37ef
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml
@@ -0,0 +1,45 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="140"
+ android:viewportHeight="110"/>
+ <group>
+ <path
+ android:name="menu"
+ android:pathData="M 20,20 l 100,0 0,10 -100,0 z
+ M 20,50 l 100,0 0,10 -100,0 z
+ M 20,80 l 0,-10 100,0 0,10 z"
+ android:fill="#ffffffff"/>
+ </group>
+ <group>
+ <path
+ android:name="back"
+ android:pathData="M 20,55 l 35.3,-35.3 7.07,7.07 -35.3,35.3 z
+ M 27,50 l 97,0 0,10 -97,0 z
+ M 20,55 l 7.07,-7.07 35.3,35.3 -7.07,7.07 z"
+ android:fill="#ffffffff"
+ android:rotation="180"
+ android:pivotX="70"
+ android:pivotY="55"
+ />
+ </group>
+ <animation android:sequence="menu,back"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml
new file mode 100644
index 0000000..f8a03d7
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml
@@ -0,0 +1,48 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="600"
+ android:viewportHeight="600"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M535.441,412.339A280.868,280.868 0 1,1 536.186,161.733L284.493,286.29Z"
+ android:fill="#ffffcc00"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="pie2"
+ android:pathData="M564.441,287A280.868,280.868 0 1,1 564.441,285L284.493,286.29Z"
+ android:fill="#FFccaa00"
+ android:stroke="#FF000000"
+ android:strokeWidth="10"
+ android:pivotX="90"
+ android:pivotY="100"/>
+ </group>
+
+ <animation android:sequence="pie1,pie2"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml
new file mode 100644
index 0000000..09934de
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml
@@ -0,0 +1,41 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="200"
+ android:viewportHeight="200"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M 20,20 l 60,0 0,140 -60,0 z M 120,20 l 60,0 0,140 -60,0 z"
+ android:fill="#ffffffff"/>
+ </group>
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M 100,20 l 0,0 0,140 -80,0 z M 100,20 l 0,0 80,140 -80,0 z"
+ android:fill="#ffffffff"
+ android:rotation="90"
+ android:pivotX="100"
+ android:pivotY="100"/>
+ </group>
+ <animation android:sequence="arrow,house"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml
new file mode 100644
index 0000000..f17f67a
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="200"
+ android:viewportWidth="200" />
+
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FF555555" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FF555555" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FF555555" />
+ </group>
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FF555555" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FF555555" />
+ </group>
+
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FF555555" />
+ </group>
+
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FFFFFFFF" />
+ </group>
+
+ <animation
+ android:sequence="bar0,bar0,bar0,bar0"
+ android:durations="500,500,500"/>
+ <animation
+ android:sequence="bar1,bar1,bar1,bar1"
+ android:durations="500,500,500"/>
+ <animation
+ android:sequence="bar2,bar2,bar2,bar2"
+ android:durations="500,500,500"/>
+ <animation
+ android:sequence="bar3,bar3,bar3,bar3"
+ android:durations="500,500,500"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml
new file mode 100644
index 0000000..a1a03be
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml
@@ -0,0 +1,62 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="80"
+ android:viewportWidth="40" />
+
+ <group>
+ <path
+ android:name="battery"
+ android:pathData="M 20.28125,2.0000002 C 17.352748,2.0000002 15,4.3527485 15,7.2812502 L 15,8.0000002 L 13.15625,8.0000002 C 9.7507553,8.0000002 7,10.750759 7,14.15625 L 7,39.84375 C 7,43.24924 9.7507558,46 13.15625,46 L 33.84375,46 C 37.249245,46 39.999999,43.24924 40,39.84375 L 40,14.15625 C 40,10.75076 37.249243,8.0000002 33.84375,8.0000002 L 32,8.0000002 L 32,7.2812502 C 32,4.3527485 29.647252,2.0000002 26.71875,2.0000002 L 20.28125,2.0000002 z"
+ android:fill="#3388ff"
+ android:stroke="#ff8833"
+ android:strokeWidth="1"
+ android:rotation="0"/>
+ <path
+ android:name="spark"
+ android:pathData="M 30,18.031528 L 25.579581,23.421071 L 29.370621,26.765348 L 20.096792,37 L 21.156922,28.014053 L 17,24.902844 L 20.880632,18 L 30,18.031528 z"
+ android:fill="#FFFF0000" />
+
+ </group>
+ <group>
+ <path
+ android:name="battery"
+ android:pathData="M 20.28125,2.0000002 C 17.352748,2.0000002 15,4.3527485 15,7.2812502 L 15,8.0000002 L 13.15625,8.0000002 C 9.7507553,8.0000002 7,10.750759 7,14.15625 L 7,39.84375 C 7,43.24924 9.7507558,46 13.15625,46 L 33.84375,46 C 37.249245,46 39.999999,43.24924 40,39.84375 L 40,14.15625 C 40,10.75076 37.249243,8.0000002 33.84375,8.0000002 L 32,8.0000002 L 32,7.2812502 C 32,4.3527485 29.647252,2.0000002 26.71875,2.0000002 L 20.28125,2.0000002 z"
+ android:fill="#ff8833"
+ android:stroke="#3388ff"
+ android:strokeWidth="1"
+ android:rotation="0" />
+ <path
+ android:name="spark"
+ android:pathData="M 30,18.031528 L 25.579581,23.421071 L 29.370621,26.765348 L 20.096792,37 L 21.156922,28.014053 L 17,24.902844 L 20.880632,18 L 30,18.031528 z"
+ android:fill="#FFFF0000" />
+ </group>
+
+ <animation
+ android:durations="2000"
+ android:sequence="spark,spark" />
+ <animation
+ android:durations="2000"
+ android:sequence="battery,battery" />
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml
new file mode 100644
index 0000000..89748d5
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml
@@ -0,0 +1,90 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="600"
+ android:viewportHeight="600"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M300,70 a230,230 0 1,0 1,0 z"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="70"
+ android:trimPathStart="0"
+ android:trimPathEnd=".75"
+ android:trimPathOffset="0"/>
+
+ <path
+ android:name="v"
+ android:pathData="M300,70 l 0,-70 70,70 -70,70z"
+ android:fill="#FF00FF00"
+ android:pivotX="300"
+ android:pivotY="300"
+ android:rotation="0"
+ />
+ </group>
+
+ <group>
+ <path
+ android:name="v"
+ android:pathData="M300,70 l 0,-70 70,70 -70,70z"
+ android:pivotX="300"
+ android:pivotY="300"
+ android:rotation="360"/>
+ <path
+ android:name="pie2"
+ android:pathData="M300,70 a230,230 0 1,0 1,0 z"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="70"
+ android:rotation="360"
+ android:pivotX="300"
+ android:pivotY="300"
+ android:trimPathStart="0"
+ android:trimPathEnd=".5"
+ android:trimPathOffset="0"
+ android:strokeLineCap="round"
+ />
+ </group>
+
+ <animation android:sequence="pie1,pie2"
+ android:durations="2000"
+ android:startOffset="500"
+ android:repeatCount="-1"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+ <animation android:sequence="v,v"
+ android:durations="2000"
+ android:startOffset="500"
+ android:repeatCount="-1"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+ <animation android:sequence="pie1,pie2"
+ android:durations="2800"
+ android:startOffset="500"
+ android:limitTo="trimPathEnd"
+ android:repeatCount="-1"
+ android:repeatStyle="reverse"
+ android:animate="easeInOut"
+ />
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml
new file mode 100644
index 0000000..43dda52
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml
@@ -0,0 +1,82 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="600"
+ android:viewportHeight="400"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M300,200 h-150 a150,150 0 1,0 150,-150 z"
+ android:fill="#ffffffff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+
+ <path
+ android:name="half"
+ android:pathData="M275,175 v-150 a150,150 0 0,0 -150,150 z"
+ android:fill="#FFFF0000"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="5"
+ android:rotation="0"
+ android:pivotX="300"
+ android:pivotY="200"/>
+ </group>
+
+ <group>
+ <path
+ android:name="pie2"
+ android:pathData="M300,200 h-150 a150,150 0 1,0 150,-150 z"
+ android:fill="#ffff0000"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="300"
+ android:pivotY="200"/>
+
+ <path
+ android:name="half"
+ android:pathData="M275,175 v-150 a150,150 0 0,0 -150,150 z"
+ android:fill="#FFFFFF00"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="5"
+ android:rotation="-360"
+ android:pivotX="300"
+ android:pivotY="200"/>
+ </group>
+ <animation android:sequence="pie1,pie2"
+ android:durations="1000"
+ android:startOffset="500"
+ android:repeatCount="2"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+ <animation android:sequence="half,half"
+ android:durations="1000"
+ android:startOffset="500"
+ android:repeatCount="5"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml
new file mode 100644
index 0000000..0f1f149
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml
@@ -0,0 +1,54 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="800"
+ android:viewportHeight="500"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M200,450 l 50,-25
+ a25,25 -30 0,1 100,-50 l 50,-25
+ a25,50 -30 0,1 100,-50 l 50,-25
+ a25,75 -30 0,1 100,-50 l 50,-25
+ a25,100 -30 0,1 100,-50 l 50,-25"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"/>
+ </group>
+
+ <group>
+ <path
+ android:name="pie2"
+ android:pathData="M200,350 l 50,-25
+ a25,12 -30 0,1 100,-50 l 50,-25
+ a25,25 -30 0,1 100,-50 l 50,-25
+ a25,37 -30 0,1 100,-50 l 50,-25
+ a25,50 -30 0,1 100,-50 l 50,-25"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="20"
+ android:pivotX="90"
+ android:pivotY="100"/>
+
+ </group>
+ <animation android:sequence="pie1,pie2"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml
new file mode 100644
index 0000000..6bc946f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml
@@ -0,0 +1,48 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="500"
+ android:viewportHeight="400"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:fill="#ffffffff"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:fill="#ff440000"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="10"
+ android:rotation="180"
+ android:pivotX="250"
+ android:pivotY="200"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml
new file mode 100644
index 0000000..c9c8e8a
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml
@@ -0,0 +1,46 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="200"
+ android:viewportHeight="200"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M 100,10 v 180 M 10,100 h 180"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M 100,10 v 90 M 10,100 h 90"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="100"
+ android:pivotY="100"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml
new file mode 100644
index 0000000..9427652
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml
@@ -0,0 +1,46 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="1200"
+ android:viewportHeight="600"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M200,300 Q400,50 600,300 T1000,300"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M200,300 Q400,50 600,300 T1000,300"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="600"
+ android:pivotY="300"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml
new file mode 100644
index 0000000..83dfbd2
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml
@@ -0,0 +1,45 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="500"
+ android:viewportHeight="400"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:stroke="#FFFFFF00"
+ android:strokeWidth="10"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="250"
+ android:pivotY="200"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml
new file mode 100644
index 0000000..013254f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml
@@ -0,0 +1,45 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="1000"
+ android:viewportHeight="800"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M10,300 Q400,50 600,300 T1000,300"
+ android:stroke="#FF00FFFF"
+ android:strokeWidth="40"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M10,300 Q400,550 600,300 T1000,300"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="60"
+ android:pivotX="90"
+ android:pivotY="100"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml
new file mode 100644
index 0000000..aba7e5f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml
@@ -0,0 +1,37 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="480"
+ android:viewportHeight="480"/>
+
+ <group>
+ <path
+ android:name="edit"
+ android:pathData="M406.667,180c0,0 -100 -100 -113.334 -113.333
+ c-13.333 -13.334 -33.333,0 -33.333,0l-160,160c0,0 -40,153.333 -40,173.333c0,13.333,13.333,13.333,13.333,13.333l173.334 -40
+ c0,0,146.666 -146.666,160 -160C420,200,406.667,180,406.667,180z M226.399,356.823L131.95,378.62l-38.516 -38.522
+ c7.848 -34.675,20.152 -82.52,23.538 -95.593l3.027,2.162l106.667,106.666L226.399,356.823z"
+ android:stroke="#FF000000"
+ android:fill="#FF00FFFF"
+ android:strokeWidth="10"/>
+ </group>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml
new file mode 100644
index 0000000..8897181
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at"+
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M3.0,17.25L3.0,21.0l3.75,0.0L17.813995,9.936001l-3.75,-3.75L3.0,17.25zM20.707,7.0429993c0.391,-0.391 0.391,-1.023 0.0,-1.414l-2.336,-2.336c-0.391,-0.391 -1.023,-0.391 -1.414,0.0l-1.832,1.832l3.75,3.75L20.707,7.0429993z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml
new file mode 100644
index 0000000..2c7ebbd
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at"+
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M6.0,19.0c0.0,1.104 0.896,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0,-0.896 2.0,-2.0l0.0,-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0,-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0,-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml
new file mode 100644
index 0000000..e4cf78c
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at"+
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M16.0,5.0c-1.955,0.0 -3.83,1.268 -4.5,3.0c-0.67,-1.732 -2.547,-3.0 -4.5,-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207,-5.242 9.0,-7.971 9.0,-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml
new file mode 100644
index 0000000..cec12ba
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml
@@ -0,0 +1,33 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at"+
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M11.994999,2.0C6.4679985,2.0 2.0,6.4780006 2.0,12.0s4.468,10.0 9.995,10.0S22.0,17.522 22.0,12.0S17.521,2.0 11.994999,2.0zM12.0,20.0c-4.42,0.0 -8.0,-3.582 -8.0,-8.0s3.58,-8.0 8.0,-8.0s8.0,3.582 8.0,8.0S16.419998,20.0 12.0,20.0z"
+ android:fillOpacity="0.9"
+ />
+<path
+ android:pathData="M12.5,6.0l-1.5,0.0 0.0,7.0 5.3029995,3.1819992 0.75,-1.249999 -4.5529995,-2.7320004z"
+ android:fillOpacity="0.9"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml
new file mode 100644
index 0000000..5fe1fb6
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at"+
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M19.429,12.975998c0.042,-0.32 0.07,-0.645 0.07,-0.976s-0.029,-0.655 -0.07,-0.976l2.113,-1.654c0.188,-0.151 0.243,-0.422 0.118,-0.639l-2.0,-3.463c-0.125,-0.217 -0.386,-0.304 -0.612,-0.218l-2.49,1.004c-0.516,-0.396 -1.081,-0.731 -1.69,-0.984l-0.375,-2.648C14.456,2.1829987 14.25,2.0 14.0,2.0l-4.0,0.0C9.75,2.0 9.544,2.1829987 9.506,2.422001L9.131,5.0699997C8.521,5.322998 7.957,5.6570015 7.44,6.054001L4.952,5.0509987C4.726,4.965 4.464,5.052002 4.34,5.269001l-2.0,3.463C2.2150002,8.947998 2.27,9.219002 2.4580002,9.369999l2.112,1.653C4.528,11.344002 4.5,11.668999 4.5,12.0s0.029,0.656 0.071,0.977L2.4580002,14.630001c-0.188,0.151 -0.243,0.422 -0.118,0.639l2.0,3.463c0.125,0.217 0.386,0.304 0.612,0.218l2.489,-1.004c0.516,0.396 1.081,0.731 1.69,0.984l0.375,2.648C9.544,21.817001 9.75,22.0 10.0,22.0l4.0,0.0c0.25,0.0 0.456,-0.183 0.494,-0.422l0.375,-2.648c0.609,-0.253 1.174,-0.588 1.689,-0.984l2.49,1.004c0.226,0.086 0.487,-0.001 0.612,-0.218l2.0,-3.463c0.125,-0.217 0.07,-0.487 -0.118,-0.639L19.429,12.975998zM12.0,16.0c-2.21,0.0 -4.0,-1.791 -4.0,-4.0c0.0,-2.21 1.79,-4.0 4.0,-4.0c2.208,0.0 4.0,1.79 4.0,4.0C16.0,14.209 14.208,16.0 12.0,16.0z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_test01.xml b/tests/DynamicDrawableTest/res/drawable/vector_test01.xml
new file mode 100644
index 0000000..6beb9d8
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_test01.xml
@@ -0,0 +1,31 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at"+
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="128dp"
+android:height="128dp"/>
+
+ <viewport android:viewportWidth="512"
+ android:viewportHeight="512"/>
+
+<group>
+<path
+ android:name="002b"
+ android:pathData="M100,200c0,-100 150,-100 150,0s150,100 150,0t-200,299"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="4"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_test02.xml b/tests/DynamicDrawableTest/res/drawable/vector_test02.xml
new file mode 100644
index 0000000..2c1a28e
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_test02.xml
@@ -0,0 +1,31 @@
+<!-- Copyright (C) 2014 The Android Open Source Project
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at"+
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="128dp"
+android:height="128dp"/>
+
+ <viewport android:viewportWidth="512"
+ android:viewportHeight="512"/>
+
+<group>
+<path
+ android:name="002b"
+ android:pathData="M100,200c0,-100 150,-100 150,0s150,100 150,0T-200,299"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="4"
+ />
+</group>
+</vector>
diff --git a/core/res/res/drawable/item_background_borderless_quantum_light.xml b/tests/DynamicDrawableTest/res/values/strings.xml
index 09f6ae9..64163c2 100644
--- a/core/res/res/drawable/item_background_borderless_quantum_light.xml
+++ b/tests/DynamicDrawableTest/res/values/strings.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
-<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/darker_gray" />
+<resources>
+</resources>
diff --git a/core/res/res/drawable/item_background_quantum_light.xml b/tests/DynamicDrawableTest/res/values/styles.xml
index 09f6ae9..460c0db 100644
--- a/core/res/res/drawable/item_background_quantum_light.xml
+++ b/tests/DynamicDrawableTest/res/values/styles.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,6 +12,5 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/darker_gray" />
+<resources>
+</resources>
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java
new file mode 100644
index 0000000..1060d19
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.GridLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorCheckbox extends Activity {
+ private static final String LOGCAT = "VectorDrawable1";
+ int[] icon = {
+ R.drawable.vector_drawable01,
+ R.drawable.vector_drawable02,
+ R.drawable.vector_drawable03,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable05,
+ R.drawable.vector_drawable06,
+ R.drawable.vector_drawable07,
+ R.drawable.vector_drawable08,
+ R.drawable.vector_drawable09,
+ R.drawable.vector_drawable10,
+ R.drawable.vector_drawable11,
+ R.drawable.vector_drawable12,
+ R.drawable.vector_drawable13,
+ R.drawable.vector_drawable14,
+ R.drawable.vector_drawable15,
+ R.drawable.vector_drawable16,
+ R.drawable.vector_drawable17,
+ R.drawable.vector_drawable18,
+ R.drawable.vector_drawable19,
+ R.drawable.vector_drawable20
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GridLayout container = new GridLayout(this);
+ container.setColumnCount(5);
+ container.setBackgroundColor(0xFF888888);
+ final Button []bArray = new Button[icon.length];
+
+ for (int i = 0; i < icon.length; i++) {
+ CheckBox checkBox = new CheckBox(this);
+ bArray[i] = checkBox;
+ checkBox.setWidth(200);
+ checkBox.setWidth(200);
+ checkBox.setButtonDrawable(icon[i]);
+ container.addView(checkBox);
+ }
+ setContentView(container);
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java
new file mode 100644
index 0000000..0ae4b6d
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawable01 extends Activity implements View.OnClickListener {
+ private static final String LOGCAT = "VectorDrawable1";
+ int[] icon = {
+ R.drawable.vector_drawable01,
+ R.drawable.vector_drawable02,
+ R.drawable.vector_drawable03,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable05,
+ R.drawable.vector_drawable06,
+ R.drawable.vector_drawable07,
+ R.drawable.vector_drawable08,
+ R.drawable.vector_drawable09,
+ R.drawable.vector_drawable10,
+ R.drawable.vector_drawable11,
+ R.drawable.vector_drawable12,
+ R.drawable.vector_drawable13,
+ R.drawable.vector_drawable14,
+ R.drawable.vector_drawable15,
+ R.drawable.vector_drawable16,
+ R.drawable.vector_drawable17,
+ R.drawable.vector_drawable18,
+ R.drawable.vector_drawable19,
+ R.drawable.vector_drawable20
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GridLayout container = new GridLayout(this);
+ container.setColumnCount(5);
+ container.setBackgroundColor(0xFF888888);
+ final Button []bArray = new Button[icon.length];
+
+ for (int i = 0; i < icon.length; i++) {
+ Button button = new Button(this);
+ bArray[i] = button;
+ button.setWidth(200);
+ button.setWidth(200);
+ button.setBackgroundResource(icon[i]);
+ container.addView(button);
+ button.setOnClickListener(this);
+ }
+ Button b = new Button(this);
+ b.setText("Run All");
+ b.setOnClickListener(new View.OnClickListener(){
+
+ @Override
+ public void onClick(View v) {
+ for (int i = 0; i < bArray.length; i++) {
+ VectorDrawable d = (VectorDrawable) bArray[i].getBackground();
+ d.start();
+ }
+ }});
+ container.addView(b);
+ setContentView(container);
+
+ }
+
+ @Override
+ public void onClick(View v) {
+ VectorDrawable d = (VectorDrawable) v.getBackground();
+ d.start();
+ }
+
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java
new file mode 100644
index 0000000..a00bc5e
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawableDupPerf extends VectorDrawablePerformance {
+ {
+ icon = new int[]{
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ };
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
new file mode 100644
index 0000000..9e8ea75
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Button;
+import android.widget.GridLayout;
+import android.widget.ScrollView;
+import java.text.DecimalFormat;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawablePerformance extends Activity implements View.OnClickListener {
+ private static final String LOGCAT = "VectorDrawable1";
+ protected int[] icon = {
+ R.drawable.vector_drawable01,
+ R.drawable.vector_drawable02,
+ R.drawable.vector_drawable03,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable05,
+ R.drawable.vector_drawable06,
+ R.drawable.vector_drawable07,
+ R.drawable.vector_drawable08,
+ R.drawable.vector_drawable09,
+ R.drawable.vector_drawable10,
+ R.drawable.vector_drawable11,
+ R.drawable.vector_drawable12,
+ R.drawable.vector_drawable13,
+ R.drawable.vector_drawable14,
+ R.drawable.vector_drawable15,
+ R.drawable.vector_drawable16,
+ R.drawable.vector_drawable17,
+ R.drawable.vector_drawable18,
+ R.drawable.vector_drawable19,
+ R.drawable.vector_drawable20
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ScrollView scrollView = new ScrollView(this);
+ GridLayout container = new GridLayout(this);
+ scrollView.addView(container);
+ container.setColumnCount(5);
+ Resources res = this.getResources();
+ container.setBackgroundColor(0xFF888888);
+ VectorDrawable []d = new VectorDrawable[icon.length];
+ long time = android.os.SystemClock.elapsedRealtimeNanos();
+ for (int i = 0; i < icon.length; i++) {
+ d[i] = VectorDrawable.create(res,icon[i]);
+ }
+ time = android.os.SystemClock.elapsedRealtimeNanos()-time;
+ TextView t = new TextView(this);
+ DecimalFormat df = new DecimalFormat("#.##");
+ t.setText("avgL=" + df.format(time / (icon.length * 1000000.)) + " ms");
+ t.setBackgroundColor(0xFF000000);
+ container.addView(t);
+ time = android.os.SystemClock.elapsedRealtimeNanos();
+ for (int i = 0; i < icon.length; i++) {
+ Button button = new Button(this);
+ button.setWidth(200);
+ button.setWidth(200);
+ button.setBackgroundResource(icon[i]);
+ container.addView(button);
+ button.setOnClickListener(this);
+ }
+ setContentView(scrollView);
+ time = android.os.SystemClock.elapsedRealtimeNanos()-time;
+ t = new TextView(this);
+ t.setText("avgS=" + df.format(time / (icon.length * 1000000.)) + " ms");
+ t.setBackgroundColor(0xFF000000);
+ container.addView(t);
+ }
+
+ @Override
+ public void onClick(View v) {
+ VectorDrawable d = (VectorDrawable) v.getBackground();
+ d.start();
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java
new file mode 100644
index 0000000..9d3eded
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawableStaticPerf extends VectorDrawablePerformance {
+ {
+ icon = new int[]{
+ R.drawable.vector_icon_create,
+ R.drawable.vector_icon_delete,
+ R.drawable.vector_icon_heart,
+ R.drawable.vector_icon_schedule,
+ R.drawable.vector_icon_settings,
+ };
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java
new file mode 100644
index 0000000..704d3d7
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.dynamic;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@SuppressWarnings("UnusedDeclaration")
+public class VectorDrawableTest extends android.app.ListActivity {
+ private static final String EXTRA_PATH = "com.android.test.dynamic.Path";
+ private static final String CATEGORY_HWUI_TEST = "com.android.test.dynamic.TEST";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = getIntent();
+ String path = intent.getStringExtra("com.android.test.hwui.Path");
+
+ if (path == null) {
+ path = "";
+ }
+
+ setListAdapter(new SimpleAdapter(this, getData(path),
+ android.R.layout.simple_list_item_1, new String[] { "title" },
+ new int[] { android.R.id.text1 }));
+ getListView().setTextFilterEnabled(true);
+ }
+
+ protected List<Map<String, Object>> getData(String prefix) {
+ List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
+
+ Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(CATEGORY_HWUI_TEST);
+
+ PackageManager pm = getPackageManager();
+ List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
+
+ if (null == list)
+ return myData;
+
+ String[] prefixPath;
+ String prefixWithSlash = prefix;
+
+ if (prefix.equals("")) {
+ prefixPath = null;
+ } else {
+ prefixPath = prefix.split("/");
+ prefixWithSlash = prefix + "/";
+ }
+
+ int len = list.size();
+
+ Map<String, Boolean> entries = new HashMap<String, Boolean>();
+
+ for (int i = 0; i < len; i++) {
+ ResolveInfo info = list.get(i);
+ CharSequence labelSeq = info.loadLabel(pm);
+ String label = labelSeq != null
+ ? labelSeq.toString()
+ : info.activityInfo.name;
+
+ if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
+
+ String[] labelPath = label.split("/");
+
+ String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
+
+ if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
+ addItem(myData, nextLabel, activityIntent(
+ info.activityInfo.applicationInfo.packageName,
+ info.activityInfo.name));
+ } else {
+ if (entries.get(nextLabel) == null) {
+ addItem(myData, nextLabel, browseIntent(prefix.equals("") ?
+ nextLabel : prefix + "/" + nextLabel));
+ entries.put(nextLabel, true);
+ }
+ }
+ }
+ }
+
+ Collections.sort(myData, sDisplayNameComparator);
+
+ return myData;
+ }
+
+ private final static Comparator<Map<String, Object>> sDisplayNameComparator =
+ new Comparator<Map<String, Object>>() {
+ private final Collator collator = Collator.getInstance();
+
+ public int compare(Map<String, Object> map1, Map<String, Object> map2) {
+ return collator.compare(map1.get("title"), map2.get("title"));
+ }
+ };
+
+ protected Intent activityIntent(String pkg, String componentName) {
+ Intent result = new Intent();
+ result.setClassName(pkg, componentName);
+ return result;
+ }
+
+ protected Intent browseIntent(String path) {
+ Intent result = new Intent();
+ result.setClass(this, VectorDrawableTest.class);
+ result.putExtra(EXTRA_PATH, path);
+ return result;
+ }
+
+ protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
+ Map<String, Object> temp = new HashMap<String, Object>();
+ temp.put("title", name);
+ temp.put("intent", intent);
+ data.add(temp);
+ }
+
+ @Override
+ @SuppressWarnings({ "unchecked", "UnusedParameters" })
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position);
+
+ Intent intent = (Intent) map.get("intent");
+ startActivity(intent);
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java
new file mode 100644
index 0000000..3430192
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorPathChecking extends VectorDrawablePerformance {
+ {
+ icon = new int[]{
+ R.drawable.vector_test01,
+ R.drawable.vector_test02
+ };
+ }
+}
diff --git a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
index b690c45..93aa555 100644
--- a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
@@ -16,7 +16,7 @@
package com.android.framework.permission.tests;
-import junit.framework.TestCase;
+import android.app.PackageInstallObserver;
import android.content.pm.PackageManager;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -68,10 +68,14 @@ public class PmPermissionsTests extends AndroidTestCase {
* This test verifies that PackageManger.installPackage enforces permission
* android.permission.INSTALL_PACKAGES
*/
+ private class TestInstallObserver extends PackageInstallObserver {
+ }
+
@SmallTest
public void testInstallPackage() {
+ TestInstallObserver observer = new TestInstallObserver();
try {
- mPm.installPackage(null, null, 0, null);
+ mPm.installPackage(null, observer, 0, null);
fail("PackageManager.installPackage" +
"did not throw SecurityException as expected");
} catch (SecurityException e) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
index 53e1640..a2a8aa9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
@@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.util;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.GrowingArrayUtils;
import android.util.SparseArray;
@@ -59,10 +60,8 @@ public class SparseWeakArray<E> {
* number of mappings.
*/
public SparseWeakArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
- mKeys = new long[initialCapacity];
- mValues = new WeakReference[initialCapacity];
+ mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
+ mValues = new WeakReference[mKeys.length];
mSize = 0;
}
@@ -142,18 +141,6 @@ public class SparseWeakArray<E> {
mGarbage = false;
mSize = o;
-
- int newSize = ArrayUtils.idealLongArraySize(mSize);
- if (newSize < mKeys.length) {
- long[] nkeys = new long[newSize];
- WeakReference<?>[] nvalues = new WeakReference[newSize];
-
- System.arraycopy(mKeys, 0, nkeys, 0, newSize);
- System.arraycopy(mValues, 0, nvalues, 0, newSize);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
}
/**
@@ -182,28 +169,8 @@ public class SparseWeakArray<E> {
i = ~binarySearch(mKeys, 0, mSize, key);
}
- if (mSize >= mKeys.length) {
- int n = ArrayUtils.idealLongArraySize(mSize + 1);
-
- long[] nkeys = new long[n];
- WeakReference<?>[] nvalues = new WeakReference[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- if (mSize - i != 0) {
- // Log.e("SparseArray", "move " + (mSize - i));
- System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
- System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
- }
-
- mKeys[i] = key;
- mValues[i] = new WeakReference(value);
+ mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
+ mValues = GrowingArrayUtils.insert(mValues, mSize, i, new WeakReference(value));
mSize++;
}
}
@@ -321,24 +288,9 @@ public class SparseWeakArray<E> {
gc();
}
- int pos = mSize;
- if (pos >= mKeys.length) {
- int n = ArrayUtils.idealLongArraySize(pos + 1);
-
- long[] nkeys = new long[n];
- WeakReference<?>[] nvalues = new WeakReference[n];
-
- // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
- System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
- System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
-
- mKeys = nkeys;
- mValues = nvalues;
- }
-
- mKeys[pos] = key;
- mValues[pos] = new WeakReference(value);
- mSize = pos + 1;
+ mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
+ mValues = GrowingArrayUtils.append(mValues, mSize, new WeakReference(value));
+ mSize++;
}
private boolean hasReclaimedRefs() {