From 5b49fd09765c0ebc0df1078608f38026d9e8e067 Mon Sep 17 00:00:00 2001 From: harshanL Date: Mon, 26 Jan 2015 18:30:13 +0530 Subject: [PATCH] Added the maven archetype to create android mdm-agent project --- pom.xml | 1 + .../modules/distribution/src/assembly/bin.xml | 13 + .../tools/mdm-android-agent-archetype/pom.xml | 61 + .../mdm-android-agent-archetype/readme.txt | 12 + .../META-INF/maven/archetype-metadata.xml | 86 + .../archetype-resources/AndroidManifest.xml | 183 ++ .../resources/archetype-resources/README.md | 18 + .../assets/config.properties | 1 + .../resources/archetype-resources/build.xml | 92 + .../resources/archetype-resources/lint.xml | 3 + .../plugins/ActionBarSherlock/.gitignore | 34 + .../plugins/ActionBarSherlock/.travis.yml | 11 + .../plugins/ActionBarSherlock/CHANGELOG.md | 469 +++++ .../plugins/ActionBarSherlock/CONTRIBUTING.md | 11 + .../plugins/ActionBarSherlock/LICENSE.txt | 202 ++ .../plugins/ActionBarSherlock/README.md | 60 + .../plugins/ActionBarSherlock/checkstyle.xml | 121 ++ .../library/AndroidManifest.xml | 7 + .../ActionBarSherlock/library/README.md | 15 + .../ActionBarSherlock/library/build.gradle | 32 + .../plugins/ActionBarSherlock/library/pom.xml | 148 ++ .../library/project.properties | 12 + ...s__primary_text_disable_only_holo_dark.xml | 20 + ...__primary_text_disable_only_holo_light.xml | 21 + .../res/color/abs__primary_text_holo_dark.xml | 24 + .../color/abs__primary_text_holo_light.xml | 26 + .../abs__ab_bottom_solid_dark_holo.9.png | Bin 0 -> 144 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 0 -> 138 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 0 -> 144 bytes ...abs__ab_bottom_transparent_dark_holo.9.png | Bin 0 -> 135 bytes ...bs__ab_bottom_transparent_light_holo.9.png | Bin 0 -> 134 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 0 -> 2863 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 0 -> 2859 bytes .../abs__ab_solid_dark_holo.9.png | Bin 0 -> 146 bytes .../abs__ab_solid_light_holo.9.png | Bin 0 -> 145 bytes .../abs__ab_solid_shadow_holo.9.png | Bin 0 -> 192 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 0 -> 146 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 0 -> 146 bytes ...bs__ab_stacked_transparent_dark_holo.9.png | Bin 0 -> 139 bytes ...s__ab_stacked_transparent_light_holo.9.png | Bin 0 -> 133 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 0 -> 155 bytes .../abs__ab_transparent_light_holo.9.png | Bin 0 -> 145 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 0 -> 104 bytes ...abs__btn_cab_done_default_holo_light.9.png | Bin 0 -> 102 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 0 -> 112 bytes ...abs__btn_cab_done_focused_holo_light.9.png | Bin 0 -> 108 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 0 -> 110 bytes ...abs__btn_cab_done_pressed_holo_light.9.png | Bin 0 -> 108 bytes ...abs__cab_background_bottom_holo_dark.9.png | Bin 0 -> 149 bytes ...bs__cab_background_bottom_holo_light.9.png | Bin 0 -> 145 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 0 -> 147 bytes .../abs__cab_background_top_holo_light.9.png | Bin 0 -> 147 bytes .../abs__dialog_full_holo_dark.9.png | Bin 0 -> 1414 bytes .../abs__dialog_full_holo_light.9.png | Bin 0 -> 1537 bytes .../abs__ic_ab_back_holo_dark.png | Bin 0 -> 602 bytes .../abs__ic_ab_back_holo_light.png | Bin 0 -> 546 bytes .../abs__ic_cab_done_holo_dark.png | Bin 0 -> 713 bytes .../abs__ic_cab_done_holo_light.png | Bin 0 -> 737 bytes .../drawable-hdpi/abs__ic_clear_disabled.png | Bin 0 -> 1774 bytes .../drawable-hdpi/abs__ic_clear_normal.png | Bin 0 -> 1945 bytes ...c_clear_search_api_disabled_holo_light.png | Bin 0 -> 1504 bytes .../abs__ic_clear_search_api_holo_light.png | Bin 0 -> 1540 bytes .../library/res/drawable-hdpi/abs__ic_go.png | Bin 0 -> 1415 bytes .../abs__ic_go_search_api_holo_light.png | Bin 0 -> 1252 bytes ..._ic_menu_moreoverflow_normal_holo_dark.png | Bin 0 -> 144 bytes ...ic_menu_moreoverflow_normal_holo_light.png | Bin 0 -> 148 bytes .../abs__ic_menu_share_holo_dark.png | Bin 0 -> 467 bytes .../abs__ic_menu_share_holo_light.png | Bin 0 -> 505 bytes .../res/drawable-hdpi/abs__ic_search.png | Bin 0 -> 2280 bytes .../abs__ic_search_api_holo_light.png | Bin 0 -> 2271 bytes .../drawable-hdpi/abs__ic_voice_search.png | Bin 0 -> 2070 bytes .../abs__ic_voice_search_api_holo_light.png | Bin 0 -> 1833 bytes .../abs__list_activated_holo.9.png | Bin 0 -> 154 bytes .../abs__list_divider_holo_dark.9.png | Bin 0 -> 78 bytes .../abs__list_divider_holo_light.9.png | Bin 0 -> 76 bytes .../abs__list_focused_holo.9.png | Bin 0 -> 159 bytes .../abs__list_longpressed_holo.9.png | Bin 0 -> 154 bytes .../abs__list_pressed_holo_dark.9.png | Bin 0 -> 159 bytes .../abs__list_pressed_holo_light.9.png | Bin 0 -> 159 bytes ...bs__list_selector_disabled_holo_dark.9.png | Bin 0 -> 189 bytes ...s__list_selector_disabled_holo_light.9.png | Bin 0 -> 189 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 0 -> 922 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 0 -> 1061 bytes .../abs__progress_bg_holo_dark.9.png | Bin 0 -> 178 bytes .../abs__progress_bg_holo_light.9.png | Bin 0 -> 174 bytes .../abs__progress_primary_holo_dark.9.png | Bin 0 -> 917 bytes .../abs__progress_primary_holo_light.9.png | Bin 0 -> 917 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 0 -> 188 bytes .../abs__progress_secondary_holo_light.9.png | Bin 0 -> 188 bytes .../abs__spinner_48_inner_holo.png | Bin 0 -> 2081 bytes .../abs__spinner_48_outer_holo.png | Bin 0 -> 1811 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 0 -> 311 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 0 -> 312 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 0 -> 306 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 0 -> 306 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 0 -> 524 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 0 -> 523 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 0 -> 464 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 0 -> 458 bytes .../abs__tab_selected_focused_holo.9.png | Bin 0 -> 147 bytes .../abs__tab_selected_holo.9.png | Bin 0 -> 148 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 0 -> 147 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 0 -> 145 bytes ...__textfield_search_default_holo_dark.9.png | Bin 0 -> 110 bytes ..._textfield_search_default_holo_light.9.png | Bin 0 -> 105 bytes ...field_search_right_default_holo_dark.9.png | Bin 0 -> 108 bytes ...ield_search_right_default_holo_light.9.png | Bin 0 -> 103 bytes ...ield_search_right_selected_holo_dark.9.png | Bin 0 -> 114 bytes ...eld_search_right_selected_holo_light.9.png | Bin 0 -> 111 bytes ..._textfield_search_selected_holo_dark.9.png | Bin 0 -> 114 bytes ...textfield_search_selected_holo_light.9.png | Bin 0 -> 112 bytes .../abs__ab_bottom_solid_dark_holo.9.png | Bin 0 -> 134 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 0 -> 129 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 0 -> 134 bytes ...abs__ab_bottom_transparent_dark_holo.9.png | Bin 0 -> 123 bytes ...bs__ab_bottom_transparent_light_holo.9.png | Bin 0 -> 123 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 0 -> 2849 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 0 -> 191 bytes .../abs__ab_solid_dark_holo.9.png | Bin 0 -> 133 bytes .../abs__ab_solid_light_holo.9.png | Bin 0 -> 133 bytes .../abs__ab_solid_shadow_holo.9.png | Bin 0 -> 168 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 0 -> 134 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 0 -> 133 bytes ...bs__ab_stacked_transparent_dark_holo.9.png | Bin 0 -> 127 bytes ...s__ab_stacked_transparent_light_holo.9.png | Bin 0 -> 123 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 0 -> 139 bytes .../abs__ab_transparent_light_holo.9.png | Bin 0 -> 133 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 0 -> 101 bytes ...abs__btn_cab_done_default_holo_light.9.png | Bin 0 -> 99 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 0 -> 109 bytes ...abs__btn_cab_done_focused_holo_light.9.png | Bin 0 -> 105 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 0 -> 107 bytes ...abs__btn_cab_done_pressed_holo_light.9.png | Bin 0 -> 105 bytes ...abs__cab_background_bottom_holo_dark.9.png | Bin 0 -> 127 bytes ...bs__cab_background_bottom_holo_light.9.png | Bin 0 -> 124 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 0 -> 130 bytes .../abs__cab_background_top_holo_light.9.png | Bin 0 -> 128 bytes .../abs__dialog_full_holo_dark.9.png | Bin 0 -> 882 bytes .../abs__dialog_full_holo_light.9.png | Bin 0 -> 1003 bytes .../abs__ic_ab_back_holo_dark.png | Bin 0 -> 466 bytes .../abs__ic_ab_back_holo_light.png | Bin 0 -> 438 bytes .../abs__ic_cab_done_holo_dark.png | Bin 0 -> 566 bytes .../abs__ic_cab_done_holo_light.png | Bin 0 -> 552 bytes .../drawable-mdpi/abs__ic_clear_disabled.png | Bin 0 -> 1775 bytes .../drawable-mdpi/abs__ic_clear_normal.png | Bin 0 -> 1869 bytes ...c_clear_search_api_disabled_holo_light.png | Bin 0 -> 740 bytes .../abs__ic_clear_search_api_holo_light.png | Bin 0 -> 743 bytes .../library/res/drawable-mdpi/abs__ic_go.png | Bin 0 -> 1538 bytes .../abs__ic_go_search_api_holo_light.png | Bin 0 -> 570 bytes ..._ic_menu_moreoverflow_normal_holo_dark.png | Bin 0 -> 122 bytes ...ic_menu_moreoverflow_normal_holo_light.png | Bin 0 -> 131 bytes .../abs__ic_menu_share_holo_dark.png | Bin 0 -> 332 bytes .../abs__ic_menu_share_holo_light.png | Bin 0 -> 355 bytes .../res/drawable-mdpi/abs__ic_search.png | Bin 0 -> 2280 bytes .../abs__ic_search_api_holo_light.png | Bin 0 -> 1541 bytes .../drawable-mdpi/abs__ic_voice_search.png | Bin 0 -> 1937 bytes .../abs__ic_voice_search_api_holo_light.png | Bin 0 -> 794 bytes .../abs__list_activated_holo.9.png | Bin 0 -> 151 bytes .../abs__list_divider_holo_dark.9.png | Bin 0 -> 78 bytes .../abs__list_divider_holo_light.9.png | Bin 0 -> 76 bytes .../abs__list_focused_holo.9.png | Bin 0 -> 158 bytes .../abs__list_longpressed_holo.9.png | Bin 0 -> 151 bytes .../abs__list_pressed_holo_dark.9.png | Bin 0 -> 158 bytes .../abs__list_pressed_holo_light.9.png | Bin 0 -> 158 bytes ...bs__list_selector_disabled_holo_dark.9.png | Bin 0 -> 172 bytes ...s__list_selector_disabled_holo_light.9.png | Bin 0 -> 171 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 0 -> 651 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 0 -> 720 bytes .../abs__progress_bg_holo_dark.9.png | Bin 0 -> 165 bytes .../abs__progress_bg_holo_light.9.png | Bin 0 -> 159 bytes .../abs__progress_primary_holo_dark.9.png | Bin 0 -> 572 bytes .../abs__progress_primary_holo_light.9.png | Bin 0 -> 572 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 0 -> 170 bytes .../abs__progress_secondary_holo_light.9.png | Bin 0 -> 170 bytes .../abs__spinner_48_inner_holo.png | Bin 0 -> 1336 bytes .../abs__spinner_48_outer_holo.png | Bin 0 -> 1165 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 0 -> 254 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 0 -> 255 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 0 -> 249 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 0 -> 249 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 0 -> 417 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 0 -> 424 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 0 -> 370 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 0 -> 370 bytes .../abs__tab_selected_focused_holo.9.png | Bin 0 -> 148 bytes .../abs__tab_selected_holo.9.png | Bin 0 -> 151 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 0 -> 150 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 0 -> 155 bytes ...__textfield_search_default_holo_dark.9.png | Bin 0 -> 106 bytes ..._textfield_search_default_holo_light.9.png | Bin 0 -> 100 bytes ...field_search_right_default_holo_dark.9.png | Bin 0 -> 105 bytes ...ield_search_right_default_holo_light.9.png | Bin 0 -> 98 bytes ...ield_search_right_selected_holo_dark.9.png | Bin 0 -> 107 bytes ...eld_search_right_selected_holo_light.9.png | Bin 0 -> 107 bytes ..._textfield_search_selected_holo_dark.9.png | Bin 0 -> 109 bytes ...textfield_search_selected_holo_light.9.png | Bin 0 -> 109 bytes .../abs__progress_medium_holo.xml | 34 + .../abs__ab_bottom_solid_dark_holo.9.png | Bin 0 -> 165 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 0 -> 157 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 0 -> 166 bytes ...abs__ab_bottom_transparent_dark_holo.9.png | Bin 0 -> 153 bytes ...bs__ab_bottom_transparent_light_holo.9.png | Bin 0 -> 152 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 0 -> 2878 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 0 -> 2873 bytes .../abs__ab_solid_dark_holo.9.png | Bin 0 -> 163 bytes .../abs__ab_solid_light_holo.9.png | Bin 0 -> 163 bytes .../abs__ab_solid_shadow_holo.9.png | Bin 0 -> 290 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 0 -> 163 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 0 -> 163 bytes ...bs__ab_stacked_transparent_dark_holo.9.png | Bin 0 -> 158 bytes ...s__ab_stacked_transparent_light_holo.9.png | Bin 0 -> 152 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 0 -> 171 bytes .../abs__ab_transparent_light_holo.9.png | Bin 0 -> 160 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 0 -> 109 bytes ...abs__btn_cab_done_default_holo_light.9.png | Bin 0 -> 108 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 0 -> 112 bytes ...abs__btn_cab_done_focused_holo_light.9.png | Bin 0 -> 113 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 0 -> 115 bytes ...abs__btn_cab_done_pressed_holo_light.9.png | Bin 0 -> 113 bytes ...abs__cab_background_bottom_holo_dark.9.png | Bin 0 -> 166 bytes ...bs__cab_background_bottom_holo_light.9.png | Bin 0 -> 161 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 0 -> 174 bytes .../abs__cab_background_top_holo_light.9.png | Bin 0 -> 161 bytes .../abs__dialog_full_holo_dark.9.png | Bin 0 -> 2159 bytes .../abs__dialog_full_holo_light.9.png | Bin 0 -> 2302 bytes .../abs__ic_ab_back_holo_dark.png | Bin 0 -> 741 bytes .../abs__ic_ab_back_holo_light.png | Bin 0 -> 661 bytes .../abs__ic_cab_done_holo_dark.png | Bin 0 -> 970 bytes .../abs__ic_cab_done_holo_light.png | Bin 0 -> 915 bytes .../drawable-xhdpi/abs__ic_clear_disabled.png | Bin 0 -> 2531 bytes ...c_clear_search_api_disabled_holo_light.png | Bin 0 -> 1315 bytes .../abs__ic_clear_search_api_holo_light.png | Bin 0 -> 1447 bytes .../library/res/drawable-xhdpi/abs__ic_go.png | Bin 0 -> 1983 bytes .../abs__ic_go_search_api_holo_light.png | Bin 0 -> 836 bytes ..._ic_menu_moreoverflow_normal_holo_dark.png | Bin 0 -> 167 bytes ...ic_menu_moreoverflow_normal_holo_light.png | Bin 0 -> 184 bytes .../abs__ic_menu_share_holo_dark.png | Bin 0 -> 699 bytes .../abs__ic_menu_share_holo_light.png | Bin 0 -> 935 bytes .../res/drawable-xhdpi/abs__ic_search.png | Bin 0 -> 3784 bytes .../abs__ic_search_api_holo_light.png | Bin 0 -> 3037 bytes .../drawable-xhdpi/abs__ic_voice_search.png | Bin 0 -> 3053 bytes .../abs__ic_voice_search_api_holo_light.png | Bin 0 -> 1414 bytes .../abs__list_activated_holo.9.png | Bin 0 -> 158 bytes .../abs__list_divider_holo_dark.9.png | Bin 0 -> 83 bytes .../abs__list_divider_holo_light.9.png | Bin 0 -> 83 bytes .../abs__list_focused_holo.9.png | Bin 0 -> 163 bytes .../abs__list_longpressed_holo.9.png | Bin 0 -> 158 bytes .../abs__list_pressed_holo_dark.9.png | Bin 0 -> 163 bytes .../abs__list_pressed_holo_light.9.png | Bin 0 -> 163 bytes ...bs__list_selector_disabled_holo_dark.9.png | Bin 0 -> 190 bytes ...s__list_selector_disabled_holo_light.9.png | Bin 0 -> 188 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 0 -> 1362 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 0 -> 1551 bytes .../abs__progress_bg_holo_dark.9.png | Bin 0 -> 174 bytes .../abs__progress_bg_holo_light.9.png | Bin 0 -> 172 bytes .../abs__progress_primary_holo_dark.9.png | Bin 0 -> 1309 bytes .../abs__progress_primary_holo_light.9.png | Bin 0 -> 1309 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 0 -> 184 bytes .../abs__progress_secondary_holo_light.9.png | Bin 0 -> 184 bytes .../abs__spinner_48_inner_holo.png | Bin 0 -> 2769 bytes .../abs__spinner_48_outer_holo.png | Bin 0 -> 2432 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 0 -> 395 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 0 -> 394 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 0 -> 381 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 0 -> 381 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 0 -> 680 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 0 -> 671 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 0 -> 609 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 0 -> 602 bytes .../abs__tab_selected_focused_holo.9.png | Bin 0 -> 147 bytes .../abs__tab_selected_holo.9.png | Bin 0 -> 153 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 0 -> 147 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 0 -> 149 bytes ...__textfield_search_default_holo_dark.9.png | Bin 0 -> 126 bytes ..._textfield_search_default_holo_light.9.png | Bin 0 -> 126 bytes ...field_search_right_default_holo_dark.9.png | Bin 0 -> 125 bytes ...ield_search_right_default_holo_light.9.png | Bin 0 -> 127 bytes ...ield_search_right_selected_holo_dark.9.png | Bin 0 -> 128 bytes ...eld_search_right_selected_holo_light.9.png | Bin 0 -> 128 bytes ..._textfield_search_selected_holo_dark.9.png | Bin 0 -> 114 bytes ...textfield_search_selected_holo_light.9.png | Bin 0 -> 126 bytes .../abs__activated_background_holo_dark.xml | 20 + .../abs__activated_background_holo_light.xml | 20 + .../drawable/abs__btn_cab_done_holo_dark.xml | 24 + .../drawable/abs__btn_cab_done_holo_light.xml | 24 + .../library/res/drawable/abs__ic_clear.xml | 22 + .../res/drawable/abs__ic_clear_holo_light.xml | 22 + .../abs__ic_menu_moreoverflow_holo_dark.xml | 18 + .../abs__ic_menu_moreoverflow_holo_light.xml | 18 + .../abs__item_background_holo_dark.xml | 26 + .../abs__item_background_holo_light.xml | 26 + ...lector_background_transition_holo_dark.xml | 20 + ...ector_background_transition_holo_light.xml | 20 + .../drawable/abs__list_selector_holo_dark.xml | 27 + .../abs__list_selector_holo_light.xml | 28 + .../abs__progress_horizontal_holo_dark.xml | 32 + .../abs__progress_horizontal_holo_light.xml | 32 + .../drawable/abs__progress_medium_holo.xml | 34 + .../drawable/abs__search_dropdown_dark.xml | 22 + .../drawable/abs__search_dropdown_light.xml | 22 + .../drawable/abs__spinner_ab_holo_dark.xml | 25 + .../drawable/abs__spinner_ab_holo_light.xml | 25 + .../drawable/abs__tab_indicator_ab_holo.xml | 34 + .../abs__textfield_searchview_holo_dark.xml | 22 + .../abs__textfield_searchview_holo_light.xml | 22 + ...__textfield_searchview_right_holo_dark.xml | 22 + ..._textfield_searchview_right_holo_light.xml | 22 + .../abs__action_mode_close_item.xml | 40 + .../sherlock_spinner_dropdown_item.xml | 26 + .../res/layout-v14/sherlock_spinner_item.xml | 26 + .../layout-xlarge/abs__screen_action_bar.xml | 50 + .../abs__screen_action_bar_overlay.xml | 49 + .../res/layout/abs__action_bar_home.xml | 38 + .../res/layout/abs__action_bar_tab.xml | 7 + .../layout/abs__action_bar_tab_bar_view.xml | 6 + .../res/layout/abs__action_bar_title_item.xml | 50 + .../layout/abs__action_menu_item_layout.xml | 56 + .../res/layout/abs__action_menu_layout.xml | 23 + .../res/layout/abs__action_mode_bar.xml | 24 + .../layout/abs__action_mode_close_item.xml | 31 + .../res/layout/abs__activity_chooser_view.xml | 70 + .../abs__activity_chooser_view_list_item.xml | 53 + .../res/layout/abs__dialog_title_holo.xml | 46 + .../layout/abs__list_menu_item_checkbox.xml | 26 + .../res/layout/abs__list_menu_item_icon.xml | 28 + .../res/layout/abs__list_menu_item_layout.xml | 59 + .../res/layout/abs__list_menu_item_radio.xml | 24 + .../layout/abs__popup_menu_item_layout.xml | 60 + .../res/layout/abs__screen_action_bar.xml | 57 + .../layout/abs__screen_action_bar_overlay.xml | 59 + .../library/res/layout/abs__screen_simple.xml | 38 + ...abs__screen_simple_overlay_action_mode.xml | 38 + .../abs__search_dropdown_item_icons_2line.xml | 89 + .../library/res/layout/abs__search_view.xml | 159 ++ .../res/layout/abs__simple_dropdown_hint.xml | 29 + .../layout/sherlock_spinner_dropdown_item.xml | 26 + .../res/layout/sherlock_spinner_item.xml | 26 + .../library/res/values-land/abs__dimens.xml | 33 + .../abs__dimens.xml | 33 + .../abs__dimens.xml | 33 + .../abs__dimens.xml | 33 + .../abs__dimens.xml | 36 + .../library/res/values-large/abs__dimens.xml | 29 + .../library/res/values-sw600dp/abs__bools.xml | 19 + .../res/values-sw600dp/abs__dimens.xml | 38 + .../library/res/values-v11/abs__themes.xml | 12 + .../library/res/values-v14/abs__styles.xml | 123 ++ .../library/res/values-v14/abs__themes.xml | 34 + .../library/res/values-w360dp/abs__dimens.xml | 22 + .../library/res/values-w480dp/abs__bools.xml | 22 + .../library/res/values-w480dp/abs__config.xml | 29 + .../library/res/values-w500dp/abs__dimens.xml | 22 + .../library/res/values-w600dp/abs__dimens.xml | 22 + .../library/res/values-xlarge/abs__dimens.xml | 45 + .../library/res/values/abs__attrs.xml | 432 ++++ .../library/res/values/abs__bools.xml | 22 + .../library/res/values/abs__colors.xml | 27 + .../library/res/values/abs__config.xml | 43 + .../library/res/values/abs__dimens.xml | 67 + .../library/res/values/abs__ids.xml | 26 + .../library/res/values/abs__strings.xml | 53 + .../library/res/values/abs__styles.xml | 412 ++++ .../library/res/values/abs__themes.xml | 239 +++ .../src/android/support/v4/app/Watson.java | 144 ++ .../actionbarsherlock/ActionBarSherlock.java | 794 +++++++ .../com/actionbarsherlock/app/ActionBar.java | 956 +++++++++ .../app/SherlockActivity.java | 270 +++ .../app/SherlockDialogFragment.java | 68 + .../app/SherlockExpandableListActivity.java | 259 +++ .../app/SherlockFragment.java | 68 + .../app/SherlockFragmentActivity.java | 303 +++ .../app/SherlockListActivity.java | 270 +++ .../app/SherlockListFragment.java | 68 + .../app/SherlockPreferenceActivity.java | 270 +++ .../internal/ActionBarSherlockCompat.java | 1203 +++++++++++ .../internal/ActionBarSherlockNative.java | 336 +++ .../internal/ResourcesCompat.java | 95 + .../internal/app/ActionBarImpl.java | 1026 +++++++++ .../internal/app/ActionBarWrapper.java | 468 +++++ .../nineoldandroids/animation/Animator.java | 278 +++ .../animation/AnimatorListenerAdapter.java | 54 + .../animation/AnimatorSet.java | 1111 ++++++++++ .../animation/FloatEvaluator.java | 42 + .../animation/FloatKeyframeSet.java | 136 ++ .../animation/IntEvaluator.java | 42 + .../animation/IntKeyframeSet.java | 135 ++ .../nineoldandroids/animation/Keyframe.java | 361 ++++ .../animation/KeyframeSet.java | 227 ++ .../animation/ObjectAnimator.java | 491 +++++ .../animation/PropertyValuesHolder.java | 1012 +++++++++ .../animation/TypeEvaluator.java | 44 + .../animation/ValueAnimator.java | 1265 +++++++++++ .../nineoldandroids/view/NineViewGroup.java | 79 + .../view/animation/AnimatorProxy.java | 212 ++ .../widget/NineFrameLayout.java | 57 + .../widget/NineHorizontalScrollView.java | 41 + .../widget/NineLinearLayout.java | 57 + .../internal/view/ActionProviderWrapper.java | 40 + .../internal/view/StandaloneActionMode.java | 148 ++ .../view/View_HasStateListenerSupport.java | 6 + .../View_OnAttachStateChangeListener.java | 8 + .../internal/view/menu/ActionMenu.java | 264 +++ .../internal/view/menu/ActionMenuItem.java | 278 +++ .../view/menu/ActionMenuItemView.java | 295 +++ .../view/menu/ActionMenuPresenter.java | 714 +++++++ .../internal/view/menu/ActionMenuView.java | 575 +++++ .../internal/view/menu/BaseMenuPresenter.java | 231 ++ .../internal/view/menu/ListMenuItemView.java | 278 +++ .../internal/view/menu/MenuBuilder.java | 1335 ++++++++++++ .../internal/view/menu/MenuItemImpl.java | 647 ++++++ .../internal/view/menu/MenuItemWrapper.java | 310 +++ .../internal/view/menu/MenuPopupHelper.java | 376 ++++ .../internal/view/menu/MenuPresenter.java | 148 ++ .../internal/view/menu/MenuView.java | 120 ++ .../internal/view/menu/MenuWrapper.java | 185 ++ .../internal/view/menu/SubMenuBuilder.java | 134 ++ .../internal/view/menu/SubMenuWrapper.java | 72 + .../internal/widget/AbsActionBarView.java | 291 +++ .../internal/widget/ActionBarContainer.java | 258 +++ .../internal/widget/ActionBarContextView.java | 518 +++++ .../internal/widget/ActionBarView.java | 1548 ++++++++++++++ .../internal/widget/CapitalizingButton.java | 40 + .../internal/widget/CapitalizingTextView.java | 50 + .../widget/CollapsibleActionViewWrapper.java | 30 + .../widget/FakeDialogPhoneWindow.java | 64 + .../internal/widget/IcsAbsSpinner.java | 479 +++++ .../internal/widget/IcsAdapterView.java | 1160 ++++++++++ .../internal/widget/IcsColorDrawable.java | 41 + .../internal/widget/IcsLinearLayout.java | 410 ++++ .../internal/widget/IcsListPopupWindow.java | 644 ++++++ .../internal/widget/IcsProgressBar.java | 1193 +++++++++++ .../internal/widget/IcsSpinner.java | 703 +++++++ .../internal/widget/IcsView.java | 21 + .../widget/ScrollingTabContainerView.java | 546 +++++ .../actionbarsherlock/view/ActionMode.java | 224 ++ .../view/ActionProvider.java | 170 ++ .../view/CollapsibleActionView.java | 39 + .../src/com/actionbarsherlock/view/Menu.java | 447 ++++ .../actionbarsherlock/view/MenuInflater.java | 495 +++++ .../com/actionbarsherlock/view/MenuItem.java | 598 ++++++ .../com/actionbarsherlock/view/SubMenu.java | 110 + .../com/actionbarsherlock/view/Window.java | 65 + .../widget/ActivityChooserModel.java | 1104 ++++++++++ .../widget/ActivityChooserView.java | 827 ++++++++ .../actionbarsherlock/widget/SearchView.java | 1811 ++++++++++++++++ .../widget/ShareActionProvider.java | 316 +++ .../widget/SuggestionsAdapter.java | 733 +++++++ .../internal/ManifestParsingTest.java | 37 + .../plugins/ActionBarSherlock/pom.xml | 212 ++ .../resources/archetype-resources/pom.xml | 1 + .../archetype-resources/proguard-project.txt | 20 + .../archetype-resources/project.properties | 31 + .../res/drawable-hdpi/ic_bookmark.png | Bin 0 -> 4960 bytes .../res/drawable-hdpi/ic_check_default.png | Bin 0 -> 5701 bytes .../res/drawable-hdpi/ic_check_selected.png | Bin 0 -> 8100 bytes .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 4327 bytes .../res/drawable-hdpi/ic_logo.png | Bin 0 -> 4699 bytes .../res/drawable-hdpi/ic_logo_dark.png | Bin 0 -> 4699 bytes .../res/drawable-hdpi/ic_stat_gcm.png | Bin 0 -> 1135 bytes .../res/drawable-hdpi/option_icon.png | Bin 0 -> 5344 bytes .../res/drawable-hdpi/repeat_bg.png | Bin 0 -> 7114 bytes .../res/drawable-hdpi/top_bar.png | Bin 0 -> 34395 bytes .../res/drawable-mdpi/ic_bookmark.png | Bin 0 -> 2919 bytes .../res/drawable-mdpi/ic_check_default.png | Bin 0 -> 3090 bytes .../res/drawable-mdpi/ic_check_selected.png | Bin 0 -> 4182 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2425 bytes .../res/drawable-mdpi/ic_logo.png | Bin 0 -> 3104 bytes .../res/drawable-mdpi/ic_logo_dark.png | Bin 0 -> 3104 bytes .../res/drawable-mdpi/option_icon.png | Bin 0 -> 2894 bytes .../res/drawable-mdpi/top_bar.png | Bin 0 -> 20898 bytes .../res/drawable-xhdpi/appinstall.png | Bin 0 -> 11231 bytes .../res/drawable-xhdpi/applist.png | Bin 0 -> 11689 bytes .../res/drawable-xhdpi/appuninstall.png | Bin 0 -> 10092 bytes .../res/drawable-xhdpi/camera.png | Bin 0 -> 15565 bytes .../res/drawable-xhdpi/changepassword.png | Bin 0 -> 15692 bytes .../res/drawable-xhdpi/encrypt.png | Bin 0 -> 9196 bytes .../res/drawable-xhdpi/ic_bookmark.png | Bin 0 -> 7078 bytes .../res/drawable-xhdpi/ic_check_default.png | Bin 0 -> 8569 bytes .../res/drawable-xhdpi/ic_check_selected.png | Bin 0 -> 12609 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 5994 bytes .../res/drawable-xhdpi/ic_logo.png | Bin 0 -> 6475 bytes .../res/drawable-xhdpi/ic_logo_dark.png | Bin 0 -> 6475 bytes .../res/drawable-xhdpi/info.png | Bin 0 -> 12733 bytes .../res/drawable-xhdpi/location.png | Bin 0 -> 13926 bytes .../res/drawable-xhdpi/lock.png | Bin 0 -> 7210 bytes .../res/drawable-xhdpi/mute.png | Bin 0 -> 18880 bytes .../res/drawable-xhdpi/notification.png | Bin 0 -> 10763 bytes .../res/drawable-xhdpi/repeat_bg.png | Bin 0 -> 16939 bytes .../res/drawable-xhdpi/wifi.png | Bin 0 -> 8153 bytes .../res/drawable-xhdpi/wipe.png | Bin 0 -> 14301 bytes .../res/drawable-xxhdpi/ic_bookmark.png | Bin 0 -> 11958 bytes .../res/drawable-xxhdpi/ic_check_default.png | Bin 0 -> 15668 bytes .../res/drawable-xxhdpi/ic_check_selected.png | Bin 0 -> 23206 bytes .../res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 9581 bytes .../res/drawable-xxhdpi/ic_logo.png | Bin 0 -> 10459 bytes .../res/drawable-xxhdpi/ic_logo_dark.png | Bin 0 -> 10459 bytes .../res/drawable-xxhdpi/repeat_bg.png | Bin 0 -> 18591 bytes .../res/drawable/btn_grey.xml | 37 + .../res/drawable/btn_orange.xml | 37 + .../res/drawable/custom_checkbox.xml | 5 + .../archetype-resources/res/drawable/dot.png | Bin 0 -> 85 bytes .../res/drawable/mdm_logo.xml | 10 + .../res/layout/activity_agent_settings.xml | 26 + .../res/layout/activity_alert.xml | 35 + .../layout/activity_already_registered.xml | 96 + .../res/layout/activity_authentication.xml | 123 ++ .../layout/activity_authentication_error.xml | 91 + .../layout/activity_available_operations.xml | 25 + .../layout/activity_display_device_info.xml | 110 + .../res/layout/activity_entry.xml | 55 + .../res/layout/activity_log.xml | 37 + .../res/layout/activity_main.xml | 129 ++ .../res/layout/activity_notification.xml | 30 + .../res/layout/activity_pin_code.xml | 123 ++ .../layout/activity_register_successful.xml | 100 + .../res/layout/activity_settings.xml | 111 + .../res/layout/custom_sherlock_bar.xml | 14 + .../res/layout/custom_terms_popup.xml | 55 + .../res/layout/footer_repeat.xml | 4 + .../res/layout/header_gradient.xml | 9 + .../archetype-resources/res/layout/login.xml | 77 + .../archetype-resources/res/layout/main.xml | 12 + .../archetype-resources/res/layout/notify.xml | 93 + .../res/layout/row_with_icon.xml | 26 + .../res/layout/simplerow.xml | 8 + .../res/menu/agent_settings.xml | 9 + .../archetype-resources/res/menu/alert.xml | 9 + .../res/menu/all_ready_registered.xml | 9 + .../res/menu/auth_sherlock_menu.xml | 15 + .../res/menu/authentication.xml | 9 + .../res/menu/authentication_error.xml | 9 + .../res/menu/available_operations.xml | 9 + .../res/menu/display_device_info.xml | 9 + .../archetype-resources/res/menu/entry.xml | 9 + .../archetype-resources/res/menu/log.xml | 9 + .../archetype-resources/res/menu/main.xml | 9 + .../res/menu/notification.xml | 9 + .../archetype-resources/res/menu/notify.xml | 9 + .../res/menu/options_menu.xml | 5 + .../archetype-resources/res/menu/pin_code.xml | 9 + .../res/menu/register_successful.xml | 9 + .../archetype-resources/res/menu/settings.xml | 9 + .../res/menu/sherlock_menu.xml | 19 + .../res/menu/sherlock_menu_debug.xml | 28 + .../res/raw/emm_truststore.bks | Bin 0 -> 29 bytes .../res/values-sw600dp/dimens.xml | 8 + .../res/values-sw720dp-land/dimens.xml | 9 + .../res/values-v11/styles.xml | 11 + .../res/values-v14/styles.xml | 12 + .../archetype-resources/res/values/colors.xml | 7 + .../archetype-resources/res/values/dimens.xml | 7 + .../archetype-resources/res/values/ids.xml | 65 + .../res/values/strings.xml | 175 ++ .../archetype-resources/res/values/styles.xml | 64 + .../res/xml/wso2_device_admin.xml | 12 + .../src/org/wso2/cdm/agent/AlertActivity.java | 63 + .../cdm/agent/AlreadyRegisteredActivity.java | 532 +++++ .../cdm/agent/AuthenticationActivity.java | 889 ++++++++ .../agent/AuthenticationErrorActivity.java | 130 ++ .../cdm/agent/DisplayDeviceInfoActivity.java | 138 ++ .../org/wso2/cdm/agent/GCMIntentService.java | 146 ++ .../src/org/wso2/cdm/agent/LogActivity.java | 76 + .../org/wso2/cdm/agent/NotifyActivity.java | 69 + .../org/wso2/cdm/agent/PinCodeActivity.java | 289 +++ .../wso2/cdm/agent/RegistrationActivity.java | 300 +++ .../src/org/wso2/cdm/agent/ServerDetails.java | 358 ++++ .../cdm/agent/api/ApplicationManager.java | 243 +++ .../src/org/wso2/cdm/agent/api/Battery.java | 59 + .../org/wso2/cdm/agent/api/DeviceInfo.java | 348 +++ .../src/org/wso2/cdm/agent/api/ExecShell.java | 74 + .../org/wso2/cdm/agent/api/GPSTracker.java | 213 ++ .../wso2/cdm/agent/api/LocationServices.java | 44 + .../org/wso2/cdm/agent/api/PhoneState.java | 252 +++ .../src/org/wso2/cdm/agent/api/Root.java | 80 + .../org/wso2/cdm/agent/api/TrackCallSMS.java | 138 ++ .../org/wso2/cdm/agent/api/TrafficRecord.java | 36 + .../wso2/cdm/agent/api/TrafficSnapshot.java | 43 + .../org/wso2/cdm/agent/api/WiFiConfig.java | 798 +++++++ .../src/org/wso2/cdm/agent/models/PInfo.java | 30 + .../wso2/cdm/agent/parser/PayloadParser.java | 74 + .../cdm/agent/proxy/APIAccessCallBack.java | 12 + .../wso2/cdm/agent/proxy/APIController.java | 93 + .../cdm/agent/proxy/APIResultCallBack.java | 8 + .../wso2/cdm/agent/proxy/APIUtilities.java | 27 + .../cdm/agent/proxy/AccessTokenHandler.java | 135 ++ .../org/wso2/cdm/agent/proxy/CallBack.java | 26 + .../wso2/cdm/agent/proxy/IdentityProxy.java | 148 ++ .../cdm/agent/proxy/RefreshTokenHandler.java | 122 ++ .../wso2/cdm/agent/proxy/ServerUtilities.java | 235 +++ .../cdm/agent/proxy/ServerUtilitiesTemp.java | 315 +++ .../src/org/wso2/cdm/agent/proxy/Token.java | 94 + .../wso2/cdm/agent/proxy/TokenCallBack.java | 6 + .../agent/security/APIResultCallBackImpl.java | 100 + .../cdm/agent/services/AlarmReceiver.java | 45 + .../org/wso2/cdm/agent/services/Config.java | 22 + .../services/DeviceStartupIntentReceiver.java | 74 + .../cdm/agent/services/LocalNotification.java | 45 + .../wso2/cdm/agent/services/Operation.java | 1857 +++++++++++++++++ .../wso2/cdm/agent/services/PolicyTester.java | 740 +++++++ .../cdm/agent/services/ProcessMessage.java | 249 +++ .../wso2/cdm/agent/services/SMSReceiver.java | 66 + .../services/WSO2DeviceAdminReceiver.java | 137 ++ .../cdm/agent/utils/CommonDialogUtils.java | 159 ++ .../wso2/cdm/agent/utils/CommonUtilities.java | 194 ++ .../org/wso2/cdm/agent/utils/Constant.java | 27 + .../cdm/agent/utils/HTTPConnectorUtils.java | 269 +++ .../wso2/cdm/agent/utils/LoggerCustom.java | 62 + .../org/wso2/cdm/agent/utils/Preference.java | 47 + .../org/wso2/cdm/agent/utils/Responce.java | 45 + .../org/wso2/cdm/agent/utils/ServerUtils.java | 141 ++ .../cdm/agent/utils/WSO2SSLSocketFactory.java | 64 + product/modules/tools/pom.xml | 38 + product/pom.xml | 1 + 613 files changed, 52282 insertions(+) create mode 100644 product/modules/tools/mdm-android-agent-archetype/pom.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/readme.txt create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/AndroidManifest.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/README.md create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/assets/config.properties create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/build.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/lint.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.gitignore create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.travis.yml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CHANGELOG.md create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CONTRIBUTING.md create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/LICENSE.txt create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/README.md create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/checkstyle.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/AndroidManifest.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/README.md create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/build.gradle create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/pom.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/project.properties create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_solid_inverse_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_solid_shadow_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_focused_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_focused_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__dialog_full_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_ab_back_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_cab_done_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_disabled.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_normal.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_search_api_disabled_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_go.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_go_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_share_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_search.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_voice_search.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_voice_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_activated_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_divider_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_divider_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_focused_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_longpressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_selector_disabled_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_bg_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_primary_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_primary_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_48_inner_holo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_48_outer_holo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_selected_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_selected_pressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_selected_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_selected_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_selected_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_selected_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_solid_inverse_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_focused_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__cab_background_bottom_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__cab_background_top_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__cab_background_top_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__dialog_full_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__dialog_full_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_ab_back_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_cab_done_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_disabled.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_normal.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_search_api_disabled_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_go.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_go_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_menu_share_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_search.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_voice_search.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_voice_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_activated_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_divider_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_divider_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_focused_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_longpressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_bg_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_bg_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_primary_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_primary_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_secondary_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_secondary_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_48_inner_holo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_48_outer_holo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_disabled_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_disabled_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_focused_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_unselected_pressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_selected_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_selected_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_selected_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_selected_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-v11/abs__progress_medium_holo.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_solid_inverse_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_share_pack_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_top_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_top_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_cab_done_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_clear_disabled.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_clear_search_api_disabled_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_clear_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_go.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_go_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_search.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_voice_search.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_voice_search_api_holo_light.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_activated_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_divider_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_divider_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_focused_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_longpressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_selector_disabled_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_bg_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_primary_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_secondary_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_48_inner_holo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_48_outer_holo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_focused_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_selected_focused_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_selected_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_unselected_pressed_holo.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_default_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_default_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_selected_holo_dark.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_selected_holo_light.9.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_medium_holo.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__tab_indicator_ab_holo.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_dark.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_light.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-large/abs__action_mode_close_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_dropdown_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar_overlay.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_home.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab_bar_view.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_title_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_item_layout.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_layout.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_bar.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_close_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view_list_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__dialog_title_holo.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_checkbox.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_icon.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_layout.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_radio.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__popup_menu_item_layout.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar_overlay.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple_overlay_action_mode.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_dropdown_item_icons_2line.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_view.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__simple_dropdown_hint.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_dropdown_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_item.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-land/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-hdpi-1024x600/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-hdpi-1024x600/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-mdpi-1024x600/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-mdpi-1024x600/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__bools.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v11/abs__themes.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__styles.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__themes.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w360dp/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__bools.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__config.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w500dp/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w600dp/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-xlarge/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__attrs.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__bools.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__colors.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__config.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__ids.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__strings.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__styles.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__themes.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/android/support/v4/app/Watson.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/ActionBarSherlock.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/ActionBar.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockDialogFragment.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragment.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragmentActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListFragment.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ResourcesCompat.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarImpl.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsSpinner.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionMode.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionProvider.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/CollapsibleActionView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Menu.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuInflater.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuItem.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/SubMenu.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Window.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserModel.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SearchView.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ShareActionProvider.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SuggestionsAdapter.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/test/com/actionbarsherlock/internal/ManifestParsingTest.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/pom.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/pom.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/proguard-project.txt create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/project.properties create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_bookmark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_check_default.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_check_selected.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_launcher.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_logo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_logo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_stat_gcm.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/option_icon.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/repeat_bg.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/top_bar.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_bookmark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_check_default.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_check_selected.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_launcher.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_logo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_logo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/option_icon.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/top_bar.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/appinstall.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/applist.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/appuninstall.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/camera.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/changepassword.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/encrypt.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_bookmark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_check_default.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_check_selected.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_launcher.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_logo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_logo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/info.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/location.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/lock.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/mute.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/notification.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/repeat_bg.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/wifi.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/wipe.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_bookmark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_check_default.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_check_selected.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_launcher.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_logo.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_logo_dark.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/repeat_bg.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/btn_grey.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/btn_orange.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/custom_checkbox.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/dot.png create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/mdm_logo.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_agent_settings.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_alert.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_already_registered.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_authentication.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_authentication_error.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_available_operations.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_display_device_info.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_entry.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_log.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_main.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_notification.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_pin_code.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_register_successful.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_settings.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/custom_sherlock_bar.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/custom_terms_popup.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/footer_repeat.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/header_gradient.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/login.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/main.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/notify.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/row_with_icon.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/simplerow.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/agent_settings.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/alert.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/all_ready_registered.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/auth_sherlock_menu.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/authentication.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/authentication_error.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/available_operations.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/display_device_info.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/entry.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/log.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/main.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/notification.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/notify.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/options_menu.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/pin_code.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/register_successful.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/settings.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/sherlock_menu.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/menu/sherlock_menu_debug.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/raw/emm_truststore.bks create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values-sw600dp/dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values-sw720dp-land/dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values-v11/styles.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values-v14/styles.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values/colors.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values/dimens.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values/ids.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values/strings.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/values/styles.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/xml/wso2_device_admin.xml create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/AlertActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/AlreadyRegisteredActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/AuthenticationActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/AuthenticationErrorActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/DisplayDeviceInfoActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/GCMIntentService.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/LogActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/NotifyActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/PinCodeActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/RegistrationActivity.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/ServerDetails.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/ApplicationManager.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/Battery.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/DeviceInfo.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/ExecShell.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/GPSTracker.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/LocationServices.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/PhoneState.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/Root.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/TrackCallSMS.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/TrafficRecord.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/TrafficSnapshot.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/api/WiFiConfig.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/models/PInfo.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/parser/PayloadParser.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/APIAccessCallBack.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/APIController.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/APIResultCallBack.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/APIUtilities.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/AccessTokenHandler.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/CallBack.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/IdentityProxy.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/RefreshTokenHandler.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/ServerUtilities.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/ServerUtilitiesTemp.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/Token.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/proxy/TokenCallBack.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/security/APIResultCallBackImpl.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/AlarmReceiver.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/Config.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/DeviceStartupIntentReceiver.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/LocalNotification.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/Operation.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/PolicyTester.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/ProcessMessage.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/SMSReceiver.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/services/WSO2DeviceAdminReceiver.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/CommonDialogUtils.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/CommonUtilities.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/Constant.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/HTTPConnectorUtils.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/LoggerCustom.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/Preference.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/Responce.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/ServerUtils.java create mode 100644 product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/src/org/wso2/cdm/agent/utils/WSO2SSLSocketFactory.java create mode 100644 product/modules/tools/pom.xml diff --git a/pom.xml b/pom.xml index 114eda3ab6..fef205738f 100644 --- a/pom.xml +++ b/pom.xml @@ -242,6 +242,7 @@ 1.2.140.wso2v3 1.2.1 7.0.52.wso2v5 + 1.0.0-SNAPSHOT diff --git a/product/modules/distribution/src/assembly/bin.xml b/product/modules/distribution/src/assembly/bin.xml index 29a3c19678..4e7879f718 100644 --- a/product/modules/distribution/src/assembly/bin.xml +++ b/product/modules/distribution/src/assembly/bin.xml @@ -280,6 +280,19 @@ 755 + <--> + + ../tools/mdm-android-agent-archetype/target/mdm-android-agent-archetype-${mdm.android.agent.archetype.version}.jar + wso2mdm-${pom.version}/repository/tools + + 755 + + + ../tools/mdm-android-agent-archetype/readme.txt + wso2mdm-${pom.version}/repository/tools + + 755 + + + 4.0.0 + org.wso2.mdmserver + mdm-android-agent-archetype + 1.0.0-SNAPSHOT + WSO2 MDM Agent Android Archetype + Creates a MDM-Android agent project + maven-archetype + + + WSO2 Inc. + http://www.wso2.com + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + org.apache.maven.archetype + archetype-packaging + ${archetype.packaging.version} + + + + + + maven-archetype-plugin + ${archetype.plugin.version} + + + + + + + 2.2 + 2.2 + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/readme.txt b/product/modules/tools/mdm-android-agent-archetype/readme.txt new file mode 100644 index 0000000000..dbedfd74b0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/readme.txt @@ -0,0 +1,12 @@ +How to use CDM-Android-agent archetype + +1. Install the archetype jar by executing the following command in the cmd. + +mvn install:install-file -Dfile= -DgroupId=org.wso2.mdmserver -DartifactId=mdm-android-agent-archetype -Dversion=1.0.0-SNAPSHOT -Dpackaging=jar -DgeneratePom=true + +2. Execute the following command to generate a cdm-android-agent project. Use the generated client-key & client-secret for API subscription as the values for -DclientKey & -DclientSecret arguments. The default android target version used here is 17. If you need to change that please provide -Dplatform argument. + +mvn archetype:generate -B -DarchetypeGroupId=org.wso2.mdmserver -DarchetypeArtifactId=mdm-android-agent-archetype -DarchetypeVersion=1.0.0-SNAPSHOT -DgroupId=org.wso2.carbon -DartifactId=mdm-android-agent -DclientKey= -DclientSecret= -Dplatform= + +3. Navigate to the created cdm-android-agent directory through the cmd. +4. Execute ant release / ant debug to generate the apk file \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml new file mode 100644 index 0000000000..a2507bffb8 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -0,0 +1,86 @@ + + + + + + 16 + + + iwriqwyriqrqro + + + wrhqwriqwyroiwq + + + + + + src + + **/*.java + + + + assets + + **/*.* + + + + libs + + **/*.* + + + + plugins + + **/*.* + + + + res + + **/*.xml + + + + res + + **/*.png + + + + res + + **/*.bks + + + + + + *.xml + + + + + + *.properties + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/AndroidManifest.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/AndroidManifest.xml new file mode 100644 index 0000000000..6d1ba6daaa --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/AndroidManifest.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/README.md b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/README.md new file mode 100644 index 0000000000..b66bd049b9 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/README.md @@ -0,0 +1,18 @@ +WSO2 EMM Agent +================= + +Configure and build the Android client application +---------------------- +Follow the instructions below to configure and build the Android client application: + +1. Get a Git clone of the project. +2. Download Android ADT plugin and configure it in your Eclipse. +3. Open the project in your Eclipse IDE. +4. Import the project as an Android project using "File-->Import-->Existing Android Code Into Workspace" +5. Two projects will show, a library and the agent. Clean the Library first and build it. +6. Open the file properties of the Agent project. +7. Under "Android" scroll down (past the Build targets). +8. The library project will show with a red "X" next to it. Remove it. +9. Add the library project you just built in step 3 +10. Ensure the Library is also on your "Java Build Path" under Libraries. +11. Clean and build. diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/assets/config.properties b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/assets/config.properties new file mode 100644 index 0000000000..7d9009c35f --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/assets/config.properties @@ -0,0 +1 @@ +SHOP_URL="" \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/build.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/build.xml new file mode 100644 index 0000000000..54c3f3380a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/build.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/lint.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/lint.xml new file mode 100644 index 0000000000..ee0eead5bb --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/lint.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.gitignore b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.gitignore new file mode 100644 index 0000000000..6d0dc1c163 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.gitignore @@ -0,0 +1,34 @@ +#Android generated +bin +gen +lint.xml + +#Eclipse +.project +.classpath +.settings +.checkstyle + +#IntelliJ IDEA +.idea +*.iml +*.ipr +*.iws +classes +gen-external-apklibs + +#Maven +target +release.properties +pom.xml.* + +#Ant +build.xml +ant.properties +local.properties +proguard.cfg +proguard-project.txt + +#Other +.DS_Store +tmp diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.travis.yml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.travis.yml new file mode 100644 index 0000000000..e9a32d4fac --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/.travis.yml @@ -0,0 +1,11 @@ +language: java + +notifications: + email: false + +before_install: + - wget http://dl.google.com/android/android-sdk_r20.0.3-linux.tgz + - tar -zxf android-sdk_r20.0.3-linux.tgz + - export ANDROID_HOME=~/builds/JakeWharton/ActionBarSherlock/android-sdk-linux + - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools + - android update sdk --filter 1,5 --no-ui --force diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CHANGELOG.md b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CHANGELOG.md new file mode 100644 index 0000000000..432230bf02 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CHANGELOG.md @@ -0,0 +1,469 @@ +Change Log +=============================================================================== + +Version 4.2.0 *(2012-10-07)* +---------------------------- + +**Maven `artifactId` is now to 'actionbarsherlock'.** + +Note: The `.Dialog` themes are now deprecated. These will be removed in a future +version of the library. + + * Add `SearchView` widget for standard search interaction (API 8+ only) + * Fix: `ShareActionProvider` in the split action bar no longer fills the entire + screen. + * Fix: `ShareActionProvider` now does file I/O on a background thread. + * Fix: Automatically correct `ColorDrawable` not respecting bounds when used as + a stacked background. + * Fix: Ensure fragments collection is present before dispatching events. + * Fix: XML-defined `onClick` searches the correct context for the declared + method. + * Fix: Ensure action mode start/finish callbacks are invoked on the activity + for the native action bar. + * Fix: Allow tab callbacks to have a fragment transaction instance for any + `FragmentActivity`. + * Fix: Ensure `CollapsibleActionView` callbacks are dispatched in both native + and compatbility action bars. + * Fix: Remove `.ForceOverflow` themes. These never should have been included. + + +Version 4.1.0 *(2012-05-17)* +---------------------------- + + * Fix: Altered technique used for menu event dispatching through the fragment + manager for greater control. + * Fix: Do not dispatch menu creation event if the activity has been destroyed. + * Fix: Correct potential `NullPointerException` when expanding an action item. + * Fix: Correct potential `NullPointerException` when the hardware menu key was + pressed in an activity that is forcing the overflow menu. + * Fix: Do not set a listener on the native action bar tab wrapper unless a + compatibility listener has been set. + * Fix: Ensure the compatibility animation framework is always available on + views even if they were previously detached from the view hierarchy. + + +Version 4.0.2 *(2012-04-15)* +---------------------------- + + * Upgrade to r7 support library. + * Fix: Do not trigger menu creation after `onCreate` if activity is finishing. + * Fix: Prevent overflow from displaying if there are no overflow action items. + * Fix: Long-pressing menu key no longer triggers overflow. + * Fix: Use proper tab state-list drawable to mimic ICS. + * Fix: Ensure dispatching menu creation and preparation to fragments can + properly return `false` when appropriate to avoid rendering artifacts. + * Fix: Properly save and fetch action mode tag on ICS. + * Fix: Add missing density-specific resources for certain asssets and remove + unused assets. + + +Version 4.0.1 *(2012-03-25)* +---------------------------- + + * Add `ShareActionProvider` widget for use as action items. + * Re-add 'Styled' sample to provide a more comprehensive theming example. + * Fix: Do not dispatch options item selection to fragments if the activity + handles the callback. + * Fix: Prevent menu key from opening the overflow menu when an action mode is + currently displayed. + * Fix: Ensure fragment transaction instance is not `null` on initial tab + selection callback. + * Fix: Displaying an action mode while using stacked tab navigation no longer + throws an exception. + * Fix: Using expandable action item callbacks no longer results in a possible + exception on older devices. + + +Version 4.0.0 *(2012-03-07)* +---------------------------- + +Complete rewrite of the library to backport the Android 4.0 action bar. + + * The minimum supported version of Android is now 2.1 (API 7). + * New base activities are provided (e.g., `SherlockActivity` and + `SherlockFragmentActivity`) which extend from the native activities. + * The support library sources are no longer included in the library. You must + include `android-support-v4.jar` in your project separately. + * Theming now mirrors that of the native action bar through the use of multiple + styles rather than through `ab`- and `am`-prefixed attributes in the theme. + * The action bar can be statically attached to an activity view without the + requirement of using one of the provided base activities. + + +Version 3.5.1 *(2012-01-03)* +---------------------------- + + * Fix: `NullPointerException` in `FragmentManager` can no longer occur when an + attempt is being made to save to a `Bundle` that has not yet been created. + * Fix: Pre-3.0 action item submenu dialogs now properly dismiss themselves when + an item of theirs is selected. + + +Version 3.5.0 *(2011-12-18)* +---------------------------- + + * Library now uses the `r6` version of the compatibility library for its base. + Ice Cream Sandwich-specific implementations are currently disabled, however, + but will be added in a future version of the library. + + `MenuCompat`, `MenuItemCompat`, and `ActivityCompat` have be added back in + to ease transition to this library but all their methods and the classes + themselves have been deprecated. + * Rewritten menu and action item support from Ice Cream Sandwich. + + * Removed the need for the custom `Window.FEATURE_ACTION_ITEM_TEXT` flag. + You should now use the `showAsAction` attribute and/or the + `setShowAsAction(int)` method on each `MenuItem` to control whether or + not text is shown + * Action item dividers are now added automatically only when necessary + to distinguish possible confusion between action items. + * Fix: Action views now properly size themselves within the bounded space + of the menu. + + * Fix: List navigation no longer becomes unusable on certain device + configurations. + * Fix: `SubMenu`'s `findItem(int)` method now properly returns the support + version of `MenuItem`. + * Fix: Invisible sub-menu items are no longer shown on the pre-3.0 popup list. + + +Version 3.4.2 *(2001-11-09)* +---------------------------- + + * Fix: Stacked action bar now properly sets the tab bar background based on + the theme. + + +Version 3.4.1 *(2011-11-09)* +---------------------------- + + * The `makeFragmentName` method in `FragmentPagerAdapter` has been changed to + `public` scope to allow for easier access to your fragments that it is + managing. + * Action bar will now animate when calling `show()` or `hide()`. + * `SherlockPreferenceActivity` now provides full fragment and loader support. + * Examples for the plugins are now in their own sample application. + * Fix: Home icon no longer erroneously clipped when it exceeds the size of the + action bar. + * Fix: Tabs will now scroll horizontally to mimic the native action bar + behavior. + * Fix: Plugins now properly DO NOT inline their `R.java` integer constants. + * Fix: Tabs below the action bar are now styled with a default background so + that they do not incorrectly inherit an applied background unless explicity + declared. + + +Version 3.4.0 *(2011-10-30)* +---------------------------- + + * Library now uses the `r4` version of the compatibility library for its base. + Ice Cream Sandwich-specific implementations are currently disabled, however, + but will be added in a future version of the library. + * Context menu callbacks now use the support version of `MenuItem` to maintain + consistency. + * Added preference plugin which provides an action bar enhanced preference + screen. + * Fix: `abHomeLayout` theme attribute is now honored. + * Fix: `onPrepareOptionsMenu` is now properly dispatched upon menu + invalidation. + + +Version 3.3.1 *(2011-10-20)* +---------------------------- + +ADT 14 is now required. Maven 3 is required if building from the command line. + + * XML-defined `onClick` attributes will now check for an `onClick` method that + takes an `android.support.v4.view.MenuItem` instance. + * Tabs on medium screens in landscape now display inline rather than below the + action bar to mirror how Android 4.0 behaves with the same configuration. + * Fix: Menu inflater properly checks activity context for `onClick` method + declared in the XML. + * Fix: Dialog fragment properly saves its `showDialog` state when not being + used as a popup. + * Fix: Return `-1` when in tab navigation but no tab is selected. This brings + the library in line with the post-3.0 behavior. + * Fix: Removing a menu group no longer throws an `IndexOutOfBoundsException`. + * Fix: `getSelectedTab` and `getTabAt` no longer throw `NullPointerException`s + on post-3.0 when no tab was selected or no tab existed at the specified + position, respectively. + * Fix: `findFragmentById` now properly returns fragments attached to + `android.R.id.content` when run on pre-3.0 devices. + + +Version 3.3.0 *(2011-10-11)* +---------------------------- + + * Tabs are now displayed below the action bar on all medium-screen devices and + portrait large-screen devices. + * Fix: Dialog fragments no longer throw an `IllegalStateException` when being + used as a regular fragment (i.e., not as a popup). See + [StackOverflow](http://stackoverflow.com/questions/5637894/dialogfragments-with-devices-api-level-11/7560686#7560686) + for more information. + * Fix: Popping a fragment off of the back stack now properly assigns its parent + activity. + * Fix: An activity result no longer causes a `NullPointerException` when the + target fragment no longer exists. + * Fix: Action item dividers are now properly initially hidden when their + associated action items are as well. + + +Version 3.2.3 *(2011-09-16)* +---------------------------- + + * Fix: Fragments in a `ViewPager` that contributed items to the options menu + were caught in a race condition causing inconsistent results when a new page + was selected. This regression was introduced in version 3.2.2. + + +Version 3.2.2 *(2011-09-15)* +---------------------------- + + * Fix: Side-effects related to using `FragmentMapActivity` due to how it was + referencing resources from the main library. + * Fix: Fragments adjacent to the currently selected fragment in a `ViewPager` + no longer receive context menu events. + * Fix: Eliminate exception when inflating context menus on 3.0+ when using + `getMenuInflater()`. + * Fix: `ViewPager` now determines whether or not an activity menu invalidation + is required independently of whether or not fragments were created or + destroyed. This should fix an edge case where an activity with a `ViewPager` + containing only two fragments would not get its menu properly invalidated. + + +Version 3.2.1 *(2011-09-12)* +---------------------------- + + * Fix: Action mode API incorrectly using the native `Menu` and `MenuItem` + classes causing an easy pitfall for `ClassCastExceptions`. + * Fix: Large action bar backgrounds increasing the size beyond that alloted in + the theme. + + +Version 3.2.0 *(2011-09-05)* +---------------------------- + + * Added support for `MapView` and the Google APIs through the use of + `FragmentMapActivity`. If you are using a map within a fragment you must + ensure it is always attached to an activity which extends from this new base + class. + + Since supporting maps requires compiling against the Google APIs, this + functionality is implemented in the form of a plugin which is to be used + alongside the normal library. You can choose to add it as an additional + library project or by including it as a `.jar`. Maven users may simply + include the additional dependency (artifactId: `plugin-maps`). + * Fix: Fragments adjacent to the currently selected fragment in a `ViewPager` + no longer contribute to the activity menu. + * `ActionBar.Tab` has been changed from an interface to an abstract class to + mirror its native counterpart. + + +Version 3.1.3 *(2011-08-14)* +---------------------------- + + * Renamed all resources to be prefixed with `abs__` to avoid conflicts when + including in your project. + * Fix: Action bar background being set on two views causing artifacts to remain + on screen when the action bar was hidden. + * Fix: Incorrect sub-menu item being selected by default when the sub-menu was + triggered from the native options menu on pre-3.0. + * Fix: `MenuItem.setVisible` now properly updates the associated action item and + native menu item visible state. + * Fix: Adding items to a menu now honors its ordering and category. + * Fix: Fragment options item selected callback now uses the proper version of + `MenuItem`. + + +Version 3.1.2 *(2011-08-07)* +---------------------------- + + * Fix: `MenuItem.getMenuInfo()` was throwing runtime exception. Will now just + return `null`. + * Fix: Dragging over a `WebView` contained in a `ViewPager` would not register. + * Fix: Inflation of context menu incorrectly being handled by the custom menu + inflater for the library. + + +Version 3.1.1 *(2011-07-31)* +---------------------------- + + * Fix: `MenuItem.getSubMenu` now returns a support instance rather than a + native instance. + * Fix: Fragment methods `onAttach` and `onInflate` incorrectly regressed to use + `Activity` instead of a `FragmentActivity` in their method signatures. + * Fix: Retained fragments not being re-attached on pre-3.0 when attached to + `android.R.id.content` upon activity recreation. + * Fix: `onPrepareOptionsMenu` not dispatched to fragments. This still will only + occur if the activity method returns true (which is the default). + * Fix: `Menu.findItem` not returning `null` when the item was not found on + Android 3.0+. + + +Version 3.1.0 *(2011-07-22)* +---------------------------- + +Due to shortcomings in the Android theming system, a small change must be made +in how this library handles themes. If you were using a custom style for +`actionBarStyle` you must now specify its attributes in the root of the theme +and prefix them with 'ab'. + +You can see an example of this in the `SherlockCustom` theme in +`samples/demos/res/values/styles.xml`. + + * Library now uses the `r3` version of the compatibility library for its base. + * `actionBarStyle` is no longer a valid theme attribute (see note above). + * Added the demo project included with the new compatibility library under + `samples/demos/` and merged in the old 'featuredemo'. + * Dividers are now shown on pre-3.0 devices between all action items. + * `Window.FEATURE_ACTION_BAR_OVERLAY` is now honored on pre-3.0 devices. + * Inflation of XML menu resources will now honor `android:actionLayout` and + `android:actionViewClass` attributes. + * Buttons for displaying the determinate and indeterminate progress bars have + been added to the feature toggle demo. + * Added support for indeterminate progress bar. Due to the `final` modifier on + the native type, you must use `setIndeterminateProgressBarVisibility(Boolean)` + and pass `Boolean.TRUE` or `Boolean.FALSE`. + * Fix: `MenuBuilder#removeItem(int)` and `MenuBuilder#findItem(int)` throwing + `IndexOutOfBoundsException`s when the item was not found. + * Fix: Theme attributes for home item data (e.g., icon, logo) will not be + overwritten by the special `MenuItem` instance for home. + * Fix: Native strings can now be specified for an XML menu `` in + `android:title` and `android:titleCondensed`. + * `Window.FEATURE_ENABLE_ACTION_BAR_WATSON_TEXT` is now + `Window.FEATURE_ACTION_BAR_ITEM_TEXT`. + * `Widget.Sherlock.Spinner.DropDown.ActionBar` and + `Widget.Sherlock.Light.Spinner.DropDown.ActionBar` styles are now + `Widget.Sherlock.Spinner` and `Widget.Sherlock.Light.Spinner`, respectively. + * `Widget.Sherlock.ActionBarView_TabXXX` styles are now + `Widget.Sherlock.ActionBar.TabXXX`. + + +Version 3.0.3 *(2011-07-17)* +---------------------------- + +This version is a hotfix for incompatibilities introduced with the SDKs for +3.1 r2 and 3.2 r1. Due to unavoidable changes in the underlying SDK, the library +must now be compiled against API level 13. + + * `actionModeStyle` and `actionModePopupWindowStyle` are no longer valid theme + attributes. + + +Version 3.0.2 *(2011-06-23)* +---------------------------- + + * Sub-menus for action items are now shown in a list dialog. + * Moved certain classes to the `com.actionbarsherlock.internal` package which + were not meant for public consumption. Despite being given `public` scope in + this new package, these classes should **NOT** be used under any circumstances + as their API can be considered highly volatile and is subject to change often + and without warning. + + +Version 3.0.1 *(2011-06-08)* +---------------------------- + + * Fix: `onOptionsItemSelected()` not being called in fragments if the activity + version returns `false`. + * Fix: `onCreateOptionsMenu()` not being called in fragments on Android 3.0+. + * New: Enable action item text display on pre-Android 3.0 by calling + `requestWindowFeature` with `Window.FEATURE_ENABLE_ACTION_BAR_WATSON_TEXT`. + * Fix: `setCustomView()` no longer automatically enables the custom view on + pre-3.0. You must call `setDisplayShowCustomEnabled()` in order to display + the view. + + +Version 3.0.0 *(2011-06-05)* +---------------------------- + +The API has been rewritten to mimic that of the native action bar. As a result, +usage now only requires changing a few imports to use the support versions +of classes and calling `getSupportActionBar()`. See the README for more info. + +The rewrite necessitated tight interaction with the +[compatibility library](http://android-developers.blogspot.com/2011/03/fragments-for-all.html) +to the point where its sources are now included. You are no longer required to +have the standalone `.jar` file. + +Also included is a default custom action bar for use by default on pre-3.0 +devices. This custom implementation is based off of Johan Nilsson's +[Android-ActionBar](https://github.com/johannilsson/android-actionbar) and the +[work that I have done](https://github.com/johannilsson/android-actionbar/pull/25) +on it. + +More details are available at http://actionbarsherlock.com + + +Version 2.1.1 *(2011-03-21)* +---------------------------- + +**No changes to library code.** + + * Moved library to the root of the repository. + * Added `samples/dependencies.py` script to automatically download the needed + dependencies for the sample projects. + + +Version 2.1.0 *(2011-03-21)* +---------------------------- + +**WARNING**: The +[Android Compatibility Library (v4)](http://android-developers.blogspot.com/2011/03/fragments-for-all.html) +is now required. + + * Added `ActionBarSherlock.Activity`, `ActionBarSherlock.FragmentActivity`, + and `ActionBarSherlock.ListActivity` for extension by implementing + activities, the latter of which is deprecated. This affords a much tighter + integration and allows for the use of other new features listed below. + * New API method: `layout(Fragment)` will use the fragment argument as the + content to the activity. + * New API method: `menu(int)` allows for the inflation of menu XMLs from a + resource. For the non-native implementation, the XML can be inflated to a + custom Menu which can then be applied appropriately to the third-party + action bar. Sub-menus are also supported. Third-party action bar handlers + should implement `ActionBarSherlock.HasMenu` for this functionality. *This + feature requires that activities extend from one of the provided activity + base classes.* + * New API method: `homeAsUp(boolean)`. This mimics the native method + `setDisplayHomeAsUpEnalbed` on the native action bar. Third-party action bar + handlers should implement `ActionBarSherlock.HasHomeAsUp` for this + functionality. + * New API method: `useLogo(boolean)` will trigger the action bar to hide the + application icon/home button and title and show a larger logo representing + the application. Third-party action bar handlers should implement + `ActionBarSherlock.HasLogo` for this functionality. + * New API method: `listNavigation(SpinnerAdapter, OnNavigationListener)`. Tells + the action bar to use drop-down style navigation with the specified list of + items and callback listener. Third-party action bar handlers should + implement `ActionBarSherlock.HasListNavigation` for this functionality. + * Javadocs are now available at + [jakewharton.github.com/ActionBarSherlock](http://jakewharton.github.com/ActionBarSherlock/). + * A standalone JAR is now available via the + [GitHub downloads page](https://github.com/JakeWharton/ActionBarSherlock/downloads) + or in my + [personal maven repository](http://r.jakewharton.com/maven/) + as `com.jakewharton:android-actionbarsherlock:2.1.0`. + + +Version 2.0.1 *(2011-03-11)* +---------------------------- + + * Use `Class.forName()` for detection of native action bar. This provides + compatability all the way back to Android 1.5. + + +Version 2.0.0 *(2011-03-09)* +---------------------------- +Complete rewrite! + + * New and better API. + * More sane logic and attachment to activity. + * Extensible via generics. Implement any ActionBar or roll your own with + minimal effort. + * Now a library project for easy inclusion in applications. + + +Version 1.0.0 *(2011-03-07)* +---------------------------- +Initial release. diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CONTRIBUTING.md b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CONTRIBUTING.md new file mode 100644 index 0000000000..30d383364e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/CONTRIBUTING.md @@ -0,0 +1,11 @@ +Contributing +============ + +If you would like to contribute code to ActionBarSherlock you can do so through +GitHub by forking the repository and sending a pull request. + +When submitting code, please make every effort to follow existing conventions +and style in order to keep the code as readable as possible. Please also make +sure your code compiles by running `mvn clean verify`. Checkstyle failures +during compilation indicate errors in your style and can be viewed in the +`checkstyle-result.xml` file. diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/LICENSE.txt b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/LICENSE.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this 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. diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/README.md b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/README.md new file mode 100644 index 0000000000..6506c361d2 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/README.md @@ -0,0 +1,60 @@ +ActionBarSherlock +================= + +ActionBarSherlock is an standalone library designed to facilitate the use of +the action bar design pattern across all versions of Android through a single +API. + +The library will automatically use the [native ActionBar][2] implementation on +Android 4.0 or later. For previous versions which do not include ActionBar, a +custom action bar implementation based on the sources of Ice Cream Sandwich +will automatically be wrapped around the layout. This allows you to easily +develop an application with an action bar for every version of Android from 2.x +and up. + +**See http://actionbarsherlock.com for more information.** + +![Example Image][3] + +Try out the sample applications on the Android Market: [Feature Demos][4], +[Fragments][5], and [RoboGuice][6]. + +Continuous integration is provided by [Travis CI][7]. + + + +Developed By +============ + +* Jake Wharton - + + + +License +======= + + Copyright 2012 Jake Wharton + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this 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. + + + + + + [1]: http://android-developers.blogspot.com/2011/03/fragments-for-all.html + [2]: http://developer.android.com/guide/topics/ui/actionbar.html + [3]: http://actionbarsherlock.com/static/feature.png + [4]: https://play.google.com/store/apps/details?id=com.actionbarsherlock.sample.demos + [5]: https://play.google.com/store/apps/details?id=com.actionbarsherlock.sample.fragments + [6]: https://play.google.com/store/apps/details?id=com.actionbarsherlock.sample.roboguice + [7]: https://travis-ci.org/JakeWharton/ActionBarSherlock diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/checkstyle.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/checkstyle.xml new file mode 100644 index 0000000000..a2119a1ba1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/checkstyle.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/AndroidManifest.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/AndroidManifest.xml new file mode 100644 index 0000000000..c4a3d80f14 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/README.md b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/README.md new file mode 100644 index 0000000000..e8a2c080e6 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/README.md @@ -0,0 +1,15 @@ +ActionBarSherlock Library +========================= + +This folder contains the main library which should be linked against as an +Android library project in your application. + +For more information see the "Including In Your Project" section of the +[usage page][1]. + + + + + + + [1]: http://actionbarsherlock.com/usage.html diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/build.gradle b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/build.gradle new file mode 100644 index 0000000000..88ae49ebf3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/build.gradle @@ -0,0 +1,32 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:0.4' + } +} +apply plugin: 'android-library' + +dependencies { + compile fileTree(dir: 'libs', include: '*.jar') +} + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = ['src'] + resources.srcDirs = ['src'] + aidl.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + res.srcDirs = ['res'] + assets.srcDirs = ['assets'] + } + + instrumentTest.setRoot('tests') + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/pom.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/pom.xml new file mode 100644 index 0000000000..3b6ce40ce1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/pom.xml @@ -0,0 +1,148 @@ + + + + 4.0.0 + + actionbarsherlock + ActionBarSherlock + apklib + + + com.actionbarsherlock + parent + 4.2.0 + ../pom.xml + + + + + com.google.android + android + provided + + + com.google.android + support-v4 + + + + junit + junit + test + + + + + src + test + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + true + + ignored + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + + com.google.code.maven-replacer-plugin + maven-replacer-plugin + 1.4.0 + + + process-sources + + replace + + + + + false + target/generated-sources/r/com/actionbarsherlock/R.java + target/generated-sources/r/com/actionbarsherlock/R.java + false + static final int + static int + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + ../checkstyle.xml + + + + verify + + checkstyle + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + package + + attach-artifact + + + + + jar + ${project.build.directory}/${project.build.finalName}.jar + + + + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + com.google.code.maven-replacer-plugin + maven-replacer-plugin + [1.4.0,) + + replace + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/project.properties b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/project.properties new file mode 100644 index 0000000000..f557f8397a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/project.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "ant.properties", and override values to adapt the script to your +# project structure. + +android.library=true +# Project target. +target=android-15 \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_dark.xml new file mode 100644 index 0000000000..ea7459aaf5 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_dark.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_light.xml new file mode 100644 index 0000000000..0edb33b4be --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_disable_only_holo_light.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_dark.xml new file mode 100644 index 0000000000..2bcfd0b630 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_dark.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_light.xml new file mode 100644 index 0000000000..198384fede --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/color/abs__primary_text_holo_light.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..769463b369a5185ba2d2fdf26abf058086ebcd08 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S!aZFaLn02py|Iz^fCC51!MDwC ze!c%VXGhEQ)_dJsezHtpNMD|7Dac@a*_ZJyulFV2w{5C|YCbaz5)ZX-3ak0tIJ#lm tp_aeGY*)k&iW*FhzahTiJD1r}=BlLiI{(TJ=>e@^@O1TaS?83{1OUpzopr0A6)2vH$=8 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..73050476e77aa798919b829a5566973e231f9d49 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S!aZFaLn02py|Iz^fCC51!MFRR zxpqaJ>-4UOe6iPKwm$=BLD{Wo!i)yScSSDT-Jo*!N?wFe;-MB!VKtu_20%tEPqwzt q4f{lgTEQ5`;-9UxjMeKCf^DQ_uhd?;-Btm#g2B_(&t;ucLK6V6dokDm literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..712a551ece87b2544433ac982382a087e7f1731d GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S{5)M8Ln02py}Xf^L4oIp!}}xu zHrx6hVG;aws8xB@i!KMDZA_cCWy>wsRQS4KRST!En$HY_#6vK~{lt8cLjun}a%VT6 c)z9eScC>M27UGHi05qAw)78&qol`;+0QSr+Bme*a literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..bf3b9438b16543294498ba27e51d4e878c8ead5a GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sd_7$pLn02py}Xh4fCCS+;oB*H z(}QQZt5vXQMa=PTZk@YrXXvE3+ofW5$)(cU#3WF_jrSY!c@8l>`*HAE!gKCvr?`99 W=bm|#aNiDSFoUP7pUXO@geCw#94y)Z literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..81b87b86c959a98c478177270c979763831ebf66 GIT binary patch literal 2863 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 N002ovPDHLkV1kHdRS^IH literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..8fc83e22efde5509c563c97a836d869d05ff5dc6 GIT binary patch literal 2859 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 JPDHLkV1neRPs;!R literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_solid_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_solid_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..cbbaec588ec98bbc8a518a9ab5a9c469482341ba GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0XIkLn02py}Xe3KmgB?fcJu8 z^Zp*+-L#E6MBZg;W9F9wttxZ4PHc?!oG~+pYe(tbxxSpjYCbaz5)ZY&8G8*Bq7ylO npZ&2~Yqrog$!|3Wm+fFU5UE)t_U_Fapd}2Ru6{1-oD!M-^V;Vpy{TG>rs2jRbt|WpWjh#Ji#?9Gi^wblTEgJz>gTe~DWM4fZg4bX literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..1e39572224b24a81ed4d73923280ba2724dbaf6e GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sf;?RuLn02py|Iy(L4oIp!})_Q zZ}wlfoYKNk`|wbZR*CB+2cd0Do4#G+S+1#YsD)El&1Z%|BAjt`!_S2)TNKYc{m-!5 f_v_(jT(cfAPEEXE)c4^Y$T|j3S3j3^P6 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..a16db853e94af78c0739d9b89b578e2a8021c856 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sd^}woLn02py|j?`fP(zopr08IHUH2?qr literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0eff695d82911a73874d871f3a7b23b71dd8ab44 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sl001;Ln02py?l}LfC5j;!{`N< zEvnsL$t-6rWU%$psDGg1|4DLDj`q~RzPqNgR|nl=*Rt6dx_ol~p-I||JQ4;82O1ce y*`SQyBHQ|!3>bf({j~je;Zla%ZD->HG+$+yO5M3zoXrBXjlt8^&t;ucLK6T4R5w)s literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..219b170fa67aa2ef8e0b11ebff90c1629ba7e97a GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0OCjLn02py?l|AL4l*?;q8?- zrB_<6lUu~-<@8GYocm9fskyGHQx2!G9uAwU_k&&MlS%_4GaHYDLBatTBRp}nY76HL mkjg^D5fnx&0glSHJj>3%>1Jqp^q#PeS;bnL@oAJ;NJ=s*Cb_P#ZKbLh* G2~7YBfgFPX literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..66adffed632f0f6267afe6dc2f518adb6a83ca4a GIT binary patch literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Qo!3HFq_#{<Lb literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..1d836f65a1fffea301e9cf36770b21b48b3b8132 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SVmw_OLn02py|R(B!9jra;>r_8 z?%b*io|Yn;UGT9};ZTu}!9}%xc^%IgtXD4oJ@0X-F7B%4f|j+c$=0hv54CU#tNF|@ sNQ5wMgi8eI0r?xYZ}@0_Yf6jsMX$B_pXOhT0oudh>FVdQ&MBb@0DzD;x&QzG literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5818666d4e64b93da73bc3d6dc2764bcb500359c GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0OCjLn02py|R(>fCCT9!M7)Q zv literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..564fb34b4308750b6922f320e9e114b080ecd538 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SqC8z3Ln02py}XdO!9jra;!2L@ z<=I|~`ucZlc5hPnsi>TGwM)Is^N?0TPy5{UQpwgqqAoKG5)ZX-3ak0R7;B{1mWZ}( p*lxaUe)ue*Z}vC-G%ee~_}P|!&DqTD7lF1gc)I$ztaD0e0st(KG%NrB literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..ae21b760fb1ebecac3389164251b0fa14f580f5a GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SqC8z3Ln02py>gKAfB^?4dC zy{Qwe+I<(;Zrk3}qFy7o$Hqotreyxi(D>i`gF-*@tj&^T;Xws!Omj@dZ?l#4Y_?*} ivA^-x{8q}NM@;fbHo20HF^oW47(8A5T-G@yGywny6)bE3 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..79e56f522b2837bd9f579b28f037ad5eafaaee8e GIT binary patch literal 1414 zcmV;11$p|3P)cSnqT^=WQ7*OFqW%ysfqGq3fLYCng$eebY1E zq0h)!qMt>^T{!1KLrdv5=!(bMwnfb7mMF4BgVA@!3k##^X|etG%o8VLfn)&kp1$5* zAHx|3EF9@?)w)=}!OothSF(h}LSVs2n}u~V8rR2gA&m?6GFm9LT5i!5ovh2$`aOLf zDMwpCv(UIN+s(qhT71rU;E=VYR%2(wIy9)U9BqNMU?EvKj~0!zxmxOREjkZzh+iq_n}2*GaEP(@ILD!5 zWBguqUH^M`clY;tz5a@wsI&tR0g7j89WEv$&WS`s3jmAj>+65+@9$R+4-crSDsl+t zoXD~ai^by4tE;Qe>-G9CHN@f2j4rXz#$jzQA^^+B$H$Mix3`1-5a+ZsO@p#5Q53}= z0G4QnFC7vyL_!;@%<@Jv>_k)mSUx>Hz18n=PE3d}%kYsC@*I)N0NNv^lI%s;wg9j! z%knLLgEIoQ+bysY63^&#(^_eOc(NT6QxTdoZI(#S<~ro`ne!tS(gH7T&zUX-UZRk7 zy|5!F77`FowzZg?X(M)KAw}<4SRP51e8qZ>m)V;$Z3?tS#CiaZ^hhEi?U_=yRh(%c zcGk9kwMUBGYjYt@pHyCSltyExNUHHFevMy@-l#r~QEjQ;(4?Q~r4samHh{FF{bU7StYxgeBAZQ`6E7N`VLYGS_ z;oj>aHT`D+d1$*FJhVBd!G+`uf(ywR1Q(Js2reXN5G)~C&xiARXWFDHmGF81Z6U>K z;#g%)oXa8RP+ENtZO$MZBP0)Pm&4Jv?h_KbHF>VdnKo?a-t;CVB(9^gh389`0#_~3 z>r7%ovdX{d8amFjk%uF>Vp~*9sp-GKg_vAO(?{&AZLdjA|Mdo3?oA8H>)1>mc|==# zB~EQxV&cD40$n%8&w#s-rjOWJ+ddiIQXYxR!^y#)tE&3)24CJ80l~J_MCXPu>Ml3AI+9BHcJ4%0r(Kw z@2dYHj4#nGKH!fqjRVUuh**Aw_CvMrs{b>Lm!YwzO4di>6N@*}Phg5Tw&B1fy2S@v zNaMh=r`Sx3>1SxA8q+hl==5I;NtblfC(XkF^KkH7ZKuDGcq0~@mC!ryi=K7WXgde? zOwz>rq{P&!A!(hIr~D!&pe-W#G7`?LQYh|`P7hzs(O!weT#2|xih3m$l64(P7wFd8 z$(YnkvI-Blh{l8EAha{kf+|%%mTX6hk;YCcRo{6`6g>|oKBz>Tb24JLyVyI4p!izS z!8wv9b%$RIiIZ@y?B&nGjRPyvaF~-xlb-U|=!P~^8?n&FNw@wIvQA!p;xDy1AK0dR zu~CaAl^btMM>A?9->NQ&|AnVmzdt!!WF>xutSl`;$84s2a_=ari#ecl- zo|KSyJXTD=1$2JI1Ql!6el7Y8-dCZ-i%gs^mMBu<;eLzP8a;YIXA&Hxi>7JtAFa#2 UvCQ(L;{X5v07*qoM6N<$g1g$KMgRZ+ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__dialog_full_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__dialog_full_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e029f210b9a81ed4765d31e90b6e49dc8aa37bed GIT binary patch literal 1537 zcmV+c2LAbpP)P*hY@RCILOyI+)4*Y%ioMH6eaT8-v42qXrI z0|4iGEk=d4Xm52^#H?WUz%bBygG}I|;L!cJM*+u%I9T*&&%x@0sx#0Qk0mTmeRX1h$MIxNMY&% zsz{Hz01C^N@8p~dFgXbIRub%{CUOKKzAQ3rfl0r3M&j^DZL~BnC0R+zNTfH*0>l>% z6xe!^4oO*vg0sbY%(i4Znw@-;nUbs&1zN~PIe02zy)Qcz&8uA?+OU=`?e2Zs5}uJN0M*6C#a{)YX?>^k&iO8v%U{pV&i+9YXUL@sAe1fQs10%V6ikBo z^7Qod_s{$xhgN}Tci-i5`3pX{;N4;1Au(Bm7x@)z#1I9LmdL~RrF4uC5rsHs>tE+w zbjvJ)LKv+{MYbuBrU=TBLj=6Xm=@t7;baF+QjNr0K02$09MPPz_Q^dZ5CLh8#Oov4 z0!TsP8|Jz<^->fRi@r;w5OrSCkw6L?N(J|#V;?nA78HxV{Q97DD=gWeOHxKs4U)p3 zSoD>;waz;geHn?ahed6Tq%7rduPgn zV$nDE$&ajtWS5-`4=n>hvFJNE&bxxNGnt2!k)T-g9UO0!_0BFb6cm%bLuC>qYeBK* zyN@VHxuTkNE#cFa@PaJz!! z*)p0eo;YjAyoc}Lcn`@)ql2XA#Le!l%y)3C`#|D`qk*LC#Leoh&{v9irz@IDt(4j|E-ey3YJCdAoj z17Q35`nvale)TKB+I=4%AAxk%w!OMGAf++t+Mb@Cemp-vW4j&J%V|A%#TR&cd&9%S z1Mctdf1tZ-6W>Id5JKwGXhvG!+}wOSKR^Gos;Zyq!S}5X*>+05G4|7V9G{hQ?!VjH z+iw8YkTX)YMrymYx~{`?w$U_yh$q-O1#m*zu<(hQDx}lJ70s)V5Io{ZN7v2rMwVC7 zhTm_2@1*&pTK&uP8_~o&lye*5+om^+1{h zqafFH?O0X{OUO1M^YAPb=F`bd6<0LB=s!LE=ilN39Gach?DYt$CL6UhXTc;$2zpT2dqqQrIZWT*_yH->_|IcgE|Y&S_AJ4lX{3 zlIkT6RWeyS^JtZ1q^3@yK=Cm?J&*-y*C;dpYgTSF&bztX%>V7a(kL+ra#JUT-|=or zs-McUNbE?uO3e#!@v#wf-Fu%ryG^`~69lNs`%MmnTRbrM$471B$+eE{K4hK$mCQ9h-Z$E`tJc<=E)8`p?U8s&`700000NkvXXu0mjfb2aWW literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..897a1c11a06923f0ee630a3ec44b40118c1fa4d3 GIT binary patch literal 602 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877l!}s{b%+Ad7K3vkswhI zFm^kcZ3hx8D{xE)(qO#|6+TOsF)%PDdAc};Se)*?;+-wxD8l++z18QgepiI9o*=R4AA9|r|3}>uTm;M6YILUxmVi!uBjgaN)~;(wEWpmNk!cW z(d%Z<{E>P~YK!lT=8FgRsYuTJwQ$0$u+I~@?rdLb^6_f+5jpHV#tRQqPS1ijb30F2_W#pYUFO#_XV=?h zOHP?#2^DqDa literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_ab_back_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_ab_back_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..0c89f71407e8d51f92ff6a10b1ae40ec902aa04e GIT binary patch literal 546 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877l!}s{b%+Ad7K3vkswhI zFm^kcZ3hx8D{xE)(qO#|6+TOsF)%P{dAc};Se%}E<)W9gqsXz3_j5LNPFu1pO1DK} z+N#=yeg8w_ofMzAMJao1SUGXl-8U7Joy@GYEX@zknfd?wSxaLcYqyHhr&soQ-EO{p zw!~UfNcQJK)l+|B(yvWaZRmKvsC8=g<+E=!6%t;!XnxPxBUZuOVKlwt*0FipR-Y02 zmCh$xWIQ?dubRMH%k4r1TjlOEFztJ(`Lu4f+1J+&0<|T}CPeP?x_?Pcpm5>hNwa5M zzkQR1sjpY$)<2WmGuJ)*zvffcmaNUK`~10Vr~dw8eVc_z%*|+OqxE^sCGQ0OTrOO6 z<>J@Zf0Ym33CMeTp!xW+<7NU=B(%1ExnpuV-^$?oQTEn-hjMN&=46?A$U{|X$JUzr zjr;q)=$3Bvc`c`@@Ze;4?7{TSRWGgUnXHd<-`o)9JVUa&78r!8C9V-ADTyViR>?)F zK#IZ0z|c_Fz+BhBFvQT<%Fw{d$P~!6GB7Z{-*6d4LvDUbW?Cg~4NgrK`9KYlARB`7 r(@M${i&7aJQ}UBi6+Ckj(^G>|6H_V+Po~-c6)||a`njxgN@xNAF&x-_ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..d8662e3f0fdae62cdee68c184a30fa9e421dc338 GIT binary patch literal 713 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3Cn7d>4ZLn02pop#z!+EApeUwz>goe2TrwSq2J zirU3kvaXhOUTIG}?do{Paly7dd_m%&JI?q_-onB2%KO8{j^-Q>wzNlYp6R5&dH;Rm z|KbvtPbZZ7*R_9QUBqkhp({MdL+G`PeiKVkcC&4Y!{nAd6Z!S-oqj3U!mzMkIqyf? zf)_G(nEp@p{`aZ-I!9g5h7aq1927O&FPT&GvG@NuQA5$TGve!iOqW^IxiY{>!{pzO z!{3V<)Sk6$zkBfg;!caFvF0E2Z#WAV9{aHQL)vPusEmizHw=GVH2J}B^#kKc_ZNxM zzDF#RGe0;TaIo&I-m~b0*sP8To$2@Yde+QKc8kg_`XHU5q@;HFk@ug+O{X5aZ~nk~ zjknIKwfM~0Z^b864VUMM@zwGAdYt)v<(Nz4IlImB@8#qJ%zn(A@Z29bd}4MpKn$sTM506307QmPCTFYr(@#O zpZ-(V%YE!?30QE(DXivDMdI0PFM+AKOT1>hnX-6tX;O6(d#2d)iSBZ_kN7m7WzTRr zzEA`h)2bz|5hW>!C8<`)MX5lF!N|bSP}jgh*T6i)(9Fuf$jaCl$hI;t2>JhQGm3`X z{FKbJN)!#IR;K1a1kqq?mJtlpAPKS|I6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZZ8 Q4Nwt-r>mdKI;Vst0K3d3fB*mh literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_cab_done_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_cab_done_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..ed03f620f8ef9e969d0471ab76329038e25c9f0d GIT binary patch literal 737 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3CnFFjoxLn02py%z6(IY8q0$M=`{k_{&Q=;t<2 zt8!*r>&D`|W2$+>pS=eAb}M##+^cbdA4dCLPr0$oL~Mm8Bn#4$+9@L$(#*Pp%fW0&@t4F~+Q4$6OeIrG`|nG22@uVa-C zJ=H0n)NABBE9V2ZrDh$}Ob?>#U7^{{%b z^;_|*S@)*|RLscvyw85$_Y2}8p?L-UY)vO;|NFUQJ(sNEA?BESpVrme#d7mboB7l} z-Tl+e|M{(6F|!lpnSU$jtXi?CXvKcs<;$n_y<4FKOaZDTt`Q|Ei6yC4$wjF^iowXh z&`{UFLf61N#L&#jz{twj7|6CVFbMhoZ8M67-29Zxv`Q2WrdForKm^fXYnBlV)F276 tAviy+q&%@GmBBG3KPgqgGdD3kH7GSPrLyp3str&PgQu&X%Q~loCIB{EJ2wCT literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_disabled.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..d97c342d53690e6d286efbe5f37562747a49b96d GIT binary patch literal 1774 zcmVU8P*7-ZbZ>KLZ*U+lnSp_Ufq@}0xwybFAi#%#fq@|}KQEO56)-X|e7nZL z$iTqBa9P*U#mSX{G{Bl%P*lRez;J+pfx##xwK$o9f#C}S14DXwNkIt%17i#W1A|CX zc0maP17iUL1A|C*NRTrF17iyV0~1e4YDEbH0|SF|enDkXW_m`6f}y3QrGjHhep0GJ zaAk2xYHqQDXI^rCQ9*uDVo7QW0|Nup4h9AW240u^5(W3f%sd4n162kpgNVo|1qcff zJ_s=cNG>fZg9jx8g8+j9g8_pBLjXe}Lp{R+hNBE`7{wV~7)u#fFy3PlV+vxLz;uCG zm^qSpA@ds+OO_6nTdaDlt*rOhEZL^9ePa)2-_4=K(Z%tFGm-NGmm}8}ZcXk5JW@PU zd4+f<@d@)yL(o<5icqT158+-B6_LH7;i6x}CW#w~Uy-Pgl#@Irl`kzV zeL|*8R$ca%T%Wv){2zs_iiJvgN^h0dsuZZ2sQy$tsNSU!s;Q*;LF<6_B%M@UD?LHI zSNcZ`78uqV#TeU~$eS{ozBIdFzSClfs*^S+dw;4dus<{M;#|MXC)T}S9v!D zcV!QCPhBq)ZyO(X-(bH4|NMaZz==UigLj2o41F2S6d@OB6%`R(5i>J(Puzn9wnW{e zu;hl6HK{k#IWjCVGqdJqU(99Cv(K+6*i`tgSi2;vbXD1#3jNBGs$DgVwO(~o>mN4i zHPtkqZIx>)Y(Ls5-Br|mx>vQYvH$Kwn@O`L|D75??eGkZnfg$5<;Xeg_o%+-I&+-3%01W^SH2RkDT>t<8AY({UO#lFTB>(_`g8%^e z{{R4h=>PzAFaQARU;qF*m;eA5Z<1fdMgRZyw(kRs!-6#o(LP%Wr3O<1=S3ZFo9z$bj(u70=3}tI#6DWj&F;Ob99q4>t z7t_JEGi|0s7bcyiT{LI@zd7fguOSTo_Tn%A3;+W_$om&@e+U59{C2xK>{t*000Isi zc-XLE_dt-QB?k*OY(G1$>uu7@#B2;ALf{;yd>Fer3 zxz>Q~gZLw#9*+Wwy1biLp*!&n>VXAqU0c|%HDJZ1jZ6!oDKES7+VWmrg9gjr1HUt9 z$&h=(yP22-u6mx^E9uZ+0pKCX;bJ-&1r%+uT+pDpXT$;nS`cq%Mnv${vs}4kKnFnO zP;ojL1*vOGZSwsAS`q0H5q$MLS1wr~GAT|cBOrBcX}?{*UqB~HsT)hjem%$S zQCYe=d4(eMUA?{!rJtE>6>2uC>s{nMUVQiovq!7(tSuZUVsBCpu612n+{HyeG&{C3 zg%Qx;Ym2+tg`4}D-D9)knmeH3*ac5hx88#8rcKL0fWiC005AajcYxmm08)I=nXx}} QjQ{`u07*qoM6N<$g6k0wDF6Tf literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_normal.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..33ad8d4b891b14d934e470b2222571ea859c77a6 GIT binary patch literal 1945 zcmV;K2WI$*P)U8P*7-ZbZ>KLZ*U+lnSp_Ufq@}0xwybFAi#%#fq@|}KQEO56)-X|e7nZL z$iTqBa9P*U#mSX{G{Bl%P*lRez;J+pfx##xwK$o9f#C}S14DXwNkIt%17i#W1A|CX zc0maP17iUL1A|C*NRTrF17iyV0~1e4YDEbH0|SF|enDkXW_m`6f}y3QrGjHhep0GJ zaAk2xYHqQDXI^rCQ9*uDVo7QW0|Nup4h9AW240u^5(W3f%sd4n162kpgNVo|1qcff zJ_s=cNG>fZg9jx8g8+j9g8_pBLjXe}Lp{R+hNBE`7{wV~7)u#fFy3PlV+vxLz;uCG zm^qSpA@ds+OO_6nTdaDlt*rOhEZL^9ePa)2-_4=K(Z%tFGm-NGmm}8}ZcXk5JW@PU zd4+f<@d@)yL(o<5icqT158+-B6_LH7;i6x}CW#w~Uy-Pgl#@Irl`kzV zeL|*8R$ca%T%Wv){2zs_iiJvgN^h0dsuZZ2sQy$tsNSU!s;Q*;LF<6_B%M@UD?LHI zSNcZ`78uqV#TeU~$eS{ozBIdFzSClfs*^S+dw;4dus<{M;#|MXC)T}S9v!D zcV!QCPhBq)ZyO(X-(bH4|NMaZz==UigLj2o41F2S6d@OB6%`R(5i>J(Puzn9wnW{e zu;hl6HK{k#IWjCVGqdJqU(99Cv(K+6*i`tgSi2;vbXD1#3jNBGs$DgVwO(~o>mN4i zHPtkqZIx>)Y(Ls5-Br|mx>vQYvH$Kwn@O`L|D75??eGkZnfg$5<;Xeg_o%+-I&+-3%01W^SH2RkDT>t<8AY({UO#lFTB>(_`g8%^e z{{R4h=>PzAFaQARU;qF*m;eA5Z<1fdMgRZ<`$>NYxmjX{xd; z@m&{rFo*<6ia-&%?9S}Yj1NoMU6_?!qi=gB^D?>lzI)G{bI*)0`G1E*K~NAB1j^1w z0>tKJZeH2PwwY!w0t6BY3JN+p33SuQLYI(HkdcX#K*!j*7|BwgVB_Kabv%L#JBpC9 z;EQnJ<+1&B?8Szh`#X@?^XlV2b_Y-K5FTsACcc7-srF!J%cFRa5f;nX88so}^!n$z zoaNXjzHYk7GONT$qz7ti^`5C0{0Fct&sMz04AGszwAz7*v3&RHh^`S091pfpv3(b5 z_*4F8KwG3jHT04 zL)Y{;8%;+;M^cIuK77Jo4_dVE!}GH&5hG!l3Z``(DA*|D!7J6TwaW^Q$!{BPvBY1f zfE_QM@bQ{@gcj@j`1~x3tfQh^)q%AjL($PLWE_*Djkj1Kg2074d~6f{Nje^K7u;94 zsJv3$@rsafhDHP55kG-dHIPmFAA9=;s{MWcddV( zJFI2mtpvLr*Csj|Q8r$mAN(8x6+<_AKkZ*4LX3DO{@?b4Jsi2Lc%zUffeHejlb9+rq0PNT9OD z;u|vq-{=}^jSayj%5h_}ZkgGdzKgPOi{A&T+VkZWUN=qCxUcB??b4_oXFbpmY{r8l zAAy7`+*;!URqf8e1DIx-VoXo49%u+2!egDT);TPBON$juHQN2v;6f%oLvg2T=HjTH zV68;SR?~`g%UoVKaQk-bqv^ppmWX8HlM0b+kmj2@1ok$Lvua%nR#_xaD8_}Gdqhyt zw&OGA*(k-%DiJgiJLg#o1Tr!L6T|w0FfHFCBm_osWr=J^mg5%t6~${t-Jw00000NkvXXu0mjfxs7-r literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_search_api_disabled_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_search_api_disabled_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..3edbd740858acce452a65675b594d87cd85c4cde GIT binary patch literal 1504 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%xRe+5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8nflaTYtD^x(vzwcwbv89=@ zo12R>knQRQ)9aa6T#}fVoC>oy6KF3~uNhvwR?bDKi6!|(A^G_^uoMuGkzbNuoRMFk z;2dnK;G3A7nFr#7q6gwzm(-%nveXo}qWoM1aQIqfVzJ-F(A>z`+0Dqw5#euVHw$9} zR|{85phuLTdQ->=Gku_A^g)RODY3wWfGH5fgeQF<2cCIS^ME;~2$(fE*e!Y)7?=b+ zT^vIyZoLURops1T#P^YM)`G6?uC=+kf7_B4{*@J9^x)duU6<$Tu^imLQtVB+#DuWI zKp&sr#e2ikRF+h_7hGg6C3|* z?e*8ufgcND|MEKid{9C;-~RZ9Bc^sP~EP3ND_zG5Dxwk6j&$wE~4;Qc*`ssan{ zzn`9=dZ&RsirvSfCP;`whUHEmQ}f9$MSB`#rfaa*Eq?H{s4_-JY+eJUGP9%1oq zJCJw4f2WB2si`MZ$~H#$*nP`3S@opI(pSE?i0N0@>$2Vb7oL|#u)gB_!dQ1$La5q` zDeOVQ4#QJ|EiB?JGJhRxA5Ld^&RpYp@TAicHpRs4(vR3C88QC9{5(weR))#4lPN-s z1=7=NbKU$Nr0Hgbao(RTxaH2IZ#(aDrMoH3_0umA{h;I6BI6;^&o0#XM(`ImzsjuT zTnrQ3)U=jJbp=fS?83{ F1OTcH9Pt1E literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_search_api_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_clear_search_api_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..90db01b5bcf1246d6a94e83930cac63c93a6cf83 GIT binary patch literal 1540 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..2abc45809c62513224e9d695542cb8dd8e8087b9 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezt=sPZ!6KjC*gdALL|E;9+*q=6m<7 zlueVX_4IZHnJ0qE#_rG0T(kiyWMEjjhCTn?qu5pu`=4q}27?c$C=-xvpo(CHaDZeV Zn6Yoz!5==w*?y}vd$@?2>|OKBsl;8 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..bb6aef1d069a14a7fc1cea9780c919c61679e4fa GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUtXipc%kc@k8uWjUIP~c#3xZ62X z=G4p^oaPsfxfS0Jish)R3f(&WG9yqa14Evg(y_dGGlfCy2iXqR3?>_SEs{VyhV?DH iJ0OaDc|iOR772{!kNsXaOPT8&i0|p@=d#Wzp$Py$I4IEo literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6f747c8f065940a8844587c682fb3c9443ad1ca2 GIT binary patch literal 467 zcmV;^0WAKBP)SO)@i{}u0qYYqHziBfu2L*;{L?D;GxhmUqDjP ziMkTn=nm+BxmDP>FsP2fGnnz3AAnfGAiD%ptMDlguG*u-2|uL;kN%Xenfoz6Wm9neQuJ_f08buH`WL4SA>8mzG9{4uwy+$BT^9a|eO3@D0j4;gS>^u3i8D002ov JPDHLkV1mHE(I@}_ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_share_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_menu_share_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..682b2fdec4cdcffe042a0eaba5574fcb553c6fab GIT binary patch literal 505 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 AsQ>@~ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_voice_search_api_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__ic_voice_search_api_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..3481c982862cd524654e200187445a774446567f GIT binary patch literal 1833 zcmbVNX;2eq7~YUb1P`!K89?kB6p2E1Hz5g$1PR%s1`Ngo6*2bY*3mT(eCwGjDt30z@ADk&)ul!ycbSpXq2nas~26ecnniH=emg*g*#j@Uj16nB_N zi=DC%Hqg(A)tr+Y(ebG%LzlQPJO*&###LsqLlu9w;l%7DLh{2@p8E^+tOq!T_lW zAkrjQDugA;2orvi3RR;rF{(mPu~6K{@h+@VEmI|-Ny!?GN`oM%Mu|v7GKol|K~;>b z*7RYuHV1{-On9GN3uBkTDuptM`n_1Wio`LBAhQXgsILR`g#<-73JE)?GKxVRX0q7) zdw+ReMT_F3WiD>kkc1U{nP0i(9rjT~DpaX7!gS@^xK)~D5v)#TJVPYB*I4ua$r;2r z1NocdKh4s2#B`uveAD{O=FRZnHfCZ-W;Dvr_J%MMH(iS=vz?dnp7r*Q|0OM8=!_4l zs;ZL3zhAiUWdL6Q-YyURf{oFuq)uPWZD82qEi67Cysi1BvmZvMgw)Irq>e&MQ~pM`Lu=nbBxwasjL&Tsbadl%z!58�PUR2s z;--Gn6L-Y44d%`7eX(hACTrQSaf!p)CX^44OWKiL4CvZ6umi8K5;zZ2#*ykw_khy5-2;-x4w&2R z09{9x#xx})BvjJ}TI2cLeM%Juon}o2C0ni%oPP$#W_j{v7Fn&)Y4-+12-XAz2ixMp zdk-dG3-j7Z^7|(bZX9v*jq7?`Wn~?YeZGM=J3B9(I(X1G#M{BXSmw#wPX}s^Mx$a& zd* zptYy_ughebWX6!_=*!|<*LPvVhwlqoZlfEYtjvv>6wjfX3p_g?JMFdJ!co__^o#We zw=b#O^i`T}%SWdnY zptrVi4hONM1>8N+Q_^*Hw7fWo0bv~uaDGTec^ju?7ft7iw};GWFmT;t zmqkFIFYh$^o^;LBh6ZkJNGZ)@ubCQlP9ArdMLX{p^!g2)d{G45wZD$82#Akx7wY?a zz21Agb)mdb(PM7iyy?!^d2(dCvbWL2&n$1d$2oqkM7b5PX3wkWY%R=ajlH#S8mQ3! ge6yDA3jkPwzzE(HQ|OAY)&8HCR-J`5r{^yG7imhbuK)l5 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_activated_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_activated_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4ea7afa00e2bfe057472ed5a196080fc80ad7383 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr2)kE{-7*QBRJJkl{&7FVVepxUS$Rt1LT2VAvn7lLLt0oo!v4%( tpjG6n=4tr&fORvYRP%q%M>EqU82;Q9of*be(FHVz!PC{xWt~$(699PnDoy|Z literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_divider_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_divider_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..986ab0b9746301f2dd9401829da09e00995621b3 GIT binary patch literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~qMj~}Asp9}6B-)+^BAxRtXRm= az`@Yw&#rLZUbzUUfWgz%&t;ucLK6T(%Mo}0 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_divider_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_divider_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0279e17a123f8cbb3c7e3a9ce5c5af8e693b6977 GIT binary patch literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~!k#XUAsp9}6B-)+^LX%RmN2q0 Ycy4A9FVZ~13zTN?boFyt=akR{01+Y(GXMYp literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_focused_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_focused_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..516f5c7399c853d112a31d1e17c8c7f17180f9bd GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QpO1)z4*}Q$iB}R!lH3 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_longpressed_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_longpressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4ea7afa00e2bfe057472ed5a196080fc80ad7383 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr2)kE{-7*QBRJJkl{&7FVVepxUS$Rt1LT2VAvn7lLLt0oo!v4%( tpjG6n=4tr&fORvYRP%q%M>EqU82;Q9of*be(FHVz!PC{xWt~$(699PnDoy|Z literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5654cd69429fd0a3502a05b5f827bffab89cc7e0 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QD_LZ%D`aoRl?HIGCc%n7=x#)pUXO@geCyJM=ZAh literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_pressed_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_pressed_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5654cd69429fd0a3502a05b5f827bffab89cc7e0 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QD_LZ%D`aoRl?HIGCc%n7=x#)pUXO@geCyJM=ZAh literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f6fd30dcdc9c39c836e509486854f9da03486892 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^;y~=k!3HF){@Qy1DVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?cuyC{kcif|*A4j^95`Gq9-KV8B6o6ra`I!Z80pW;7d5zZGhRBg zm{FnhT6Xzih3ZMUGkfBc^kAT_eS7{3zPQ8d#DAm9s(?cuyC{kcif|*Eb3_81S$-+V)J@yPBVWyvqG&GeYz~KYxJdw0eeyIoHJnOEfn# R{sUUY;OXk;vd$@?2>|r{LWckV literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4d3d208578c61662986fdc16bd15c69759b48d6a GIT binary patch literal 922 zcmV;L17-Y)P)!ytdud6iMT7O&4bD*mP3eKws)UN7D2k#e z%DbYt@4NEYnkjlINEK7=*RV3zwml#Px9r!q%}Y$QM*NqHEZ-wscn^ zf4p9=Kg#ZZAKY%YZvc!aCbL}F6eGxtBSzy=smEUmc6C{?q1YCQrid~5o$!73+BeU$Ee{DI^Yo4#-o87 zao*xiE9Z<+s}ttlWw19HGlEA1nW09+*~|#}a;CkeJh%bU1g9CP5h0^O2}4Hs%y=Lc z5q!OY8j*^uk~rBBK?ljmh#jL84Ev;rDo>_H#K|6e%Mo=CgLzw$rI$Y4Z-kUy6U47Z zMI2w^tmuV~pH%tJq!^(yWY-hbFl2;G2g)+VPqud2Sicc+jL>MvBTKK;HbN#jlrS<8 zl+;FqdPULzJ~Kh_!?j8>!xs^*nQAm$#290~ue;BBnY1w&wMw4#m(pwEDZd_oY1{Ux z>$>N)H(eWD*FCpw`-IsDKF28-6~1bz!JGs-W6Z&R1n>#KR{&q8us99Q}8ID#(NJr3oa@N-D4Rc$qhA--bT2} z_Wpf@Z`4749}#V+fwWJz^oyZKO1~J&exY-1*Kg?D$hu!fixvAiNfpmG;mo&f5BSEA wlE;@gYed_N;JFm#Y)Zw{1W}kQU9GkF3xsHEK4Myn7XSbN07*qoM6N<$g18=|djJ3c literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..924a99d173082ba58ca7527822359f228bb14dec GIT binary patch literal 1061 zcmV+=1ls$FP)#d)-&;4-At916hopygyW1WQa|lkCWZ4-q&QLYwjy>%Jd>?UvK6*fy zdt!`Ep~K-gOUxeEG;B7TCA&L&Y`5FR`f3tF5S^VH!lJsKJqkfK0&PN7nPcRS?`4Ev z7V~vPKouy~L@5%v*=&-(hy0cgM*ETwjWz&8F3NVhH7#V4$3+kVgi2lPw-adOTXm|2 z;f`P0rx+seIw-H@dwPaOx@-q(hY$i2BS4u1XM~+%LI5%mN(D;0XOsl63U@~43e6EU z5mrW96C~;L2O}H%p$jmGc5)7LM&^oyAacV=14{s_wp`K^YIpyDFEM02mXk3OSEw-p zdORS~SGTvf|Cjl{`o#71_3u-2KzcK(ZU7La5JAil5&>9olp#5yVJhG_L?OnQ2x7(v zIfg2+Q2z$cZ7gkJK~)>%8)`3CJSNBlBGKwWz;6QnLDPCN+(q9 zAJ*09wM4d_hZLYxWa z2;mvCbu@F-B1H21)loz{?U-+?@nqk8kw`Vm31QkJFg_V%{OMfZr8mlq(-<|uJGVoHpVClAlh&-bsduQ(hI zi(GsU`1tt1hf_X{d`3<68b|S{tXYwd2YXzXl8Izg4y^21 zp<@H92ON{kB3P1HizBE$;EP~xzks74y{^`3Ur7(FmPO0@t2+WXW`VN|Gc9|AJ43ds z=_5ZJGT6$YN8bIa6HYZ^jFIn`&>W#9La9l$?6@3`ET&WsUkjFK0@?|yO)(6`*1l_s~_L1z$~& z@jZM)qqe)$B+Pe}79nG2sji9uR0#8Z){~%#a(p4yPG;@1CipK8G=YCTO^$u*mj`Me f=rGa5Ym5<}3Pv>t$oVA_00000NkvXXu0mjf+qu}} literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..310c368e7a68479307866c479d1e4eefcf5db311 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`h^LEVh{nXLlN`Ak3Qu?vqkba5WyT9CKZ;N%wBhP~?hKK2LK3q{Q@b8ror6q0>Kp=4vJYD@<);T3K0RYm>I5PkM literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_bg_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_bg_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..70cb7fc7e0bcfb850d4b365f1bccb5b743913e21 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`fTxRNh{nXLlN`Ak40u@7AASF0zb~yy)74d)-}Q|XM+&=H%L1l~ z70X`DZ5Q8J;=>T6aJiv_zhUdQx9rw$B!4Wi^!v;8!uD-LM?h!CZ3$B@rZO?tz^Iy& QK(iSCDOJO>Ym5d24oA2hD9A9kkZ#C-ocYxQulY$%dG^s1`jD zWrBMf{hI5z?Ps6d&cAMwxpu9tAQSLC;sV+l?CI!atlqGv_K~X}S&7D6#irA$G%zcr zGa^}SvXODrvrsWB#ZkB-c}-Y}>Q0!#L#9IQCX$ZI#7DnF9fJ8(R=8iR{NJvIR3GfdBS0fGXvSYugM@B@Fy~s_l`Jy)|ccqHxmVzApHz{x4N{y z#Xj0V$LH=@zsWY)$4Z)6--edG^VYGh&b$}$F3XeLt5=Uu0`p37@FaypB&t$KuAm9R zq*|yt7WOdr(m%g{dU1bs0-qy(nh~3JDc<<|K^(;cR4G!8UrKd|p;N zi5zZftW#Kk#vM}fdS+hLQ#;Dq?H?_`8P1nhqmR=j>Au${MMR)hh&5HCA z?cjx6pHV1ZFFx`ra1m|YMALE$u3RAxZp(6Eus@DJwzn!G7Cw2Mm%K&AN5Ia`DuuPd r`dvHM#yxB2nYDo;0!e2cs)*3P7gB8$K+RT%00000NkvXXu0mjfr&_ZI literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_primary_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_primary_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..1c269205e874bc6addc308efe5be4fb7c5da0edc GIT binary patch literal 917 zcmV;G18V$CDOJO>Ym5d24oA2hD9A9kkZ#C-ocYxQulY$%dG^s1`jD zWrBMf{hI5z?Ps6d&cAMwxpu9tAQSLC;sV+l?CI!atlqGv_K~X}S&7D6#irA$G%zcr zGa^}SvXODrvrsWB#ZkB-c}-Y}>Q0!#L#9IQCX$ZI#7DnF9fJ8(R=8iR{NJvIR3GfdBS0fGXvSYugM@B@Fy~s_l`Jy)|ccqHxmVzApHz{x4N{y z#Xj0V$LH=@zsWY)$4Z)6--edG^VYGh&b$}$F3XeLt5=Uu0`p37@FaypB&t$KuAm9R zq*|yt7WOdr(m%g{dU1bs0-qy(nh~3JDc<<|K^(;cR4G!8UrKd|p;N zi5zZftW#Kk#vM}fdS+hLQ#;Dq?H?_`8P1nhqmR=j>Au${MMR)hh&5HCA z?cjx6pHV1ZFFx`ra1m|YMALE$u3RAxZp(6Eus@DJwzn!G7Cw2Mm%K&AN5Ia`DuuPd r`dvHM#yxB2nYDo;0!e2cs)*3P7gB8$K+RT%00000NkvXXu0mjfr&_ZI literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..40d0d1645cbf05e30bf092ace45403281da7f318 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`oTrOph{nXLlMZq=7znVWA2oV&$ZSjW?F|h7ziq5jS#e}ezd(V) z{M(JTeF@SBrcbxn{QE=WZYK^04VRD=846z*9&b9ovtVvpnl(eT%D#{N!SzC3^S3#* f<|u1MCr7h0-;i__`(soEw28sf)z4*}Q$iB}%FaDT literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..40d0d1645cbf05e30bf092ace45403281da7f318 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`oTrOph{nXLlMZq=7znVWA2oV&$ZSjW?F|h7ziq5jS#e}ezd(V) z{M(JTeF@SBrcbxn{QE=WZYK^04VRD=846z*9&b9ovtVvpnl(eT%D#{N!SzC3^S3#* f<|u1MCr7h0-;i__`(soEw28sf)z4*}Q$iB}%FaDT literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_48_inner_holo.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_48_inner_holo.png new file mode 100644 index 0000000000000000000000000000000000000000..c8358e9cefce502030416e05dc8faff139b886b2 GIT binary patch literal 2081 zcmV++2;TRJP)YIdx5%v}IY-E={))x>B}kD^;1aO=v<01PBB|;(|LQ1lm?k zLWq;Nn-CY=ae0(~!^>I`t6s zs-B%JpquWw-vVT&b%#DKYKZiAR|9AYVtSC>+D1~E4^t2*_YE}4C7t2scS_b&i9ji7 zBYSvMwdlT0Go+O!I1;=rq$n|BisnJx=53v0;@hqm(7l)*=4rJMo!clNrP~Z@m{E-} z^JZ{ZNHx@{flX?mQSo``X|C|5u79fpM_&?X60Kt|A5rbxJ7+XZpRQ<_6xsZ!_#wo! zj#h1_U5!M-Io2>ob>UEYg+LRijsxnVI$Sub8=TigMynU~iXTIjns`*ZXjCM8l?je< z^3e1OfW}cB&*(9#LY#4(p+|S(CFYo)RH;RK=~N=zD5YZ@e|b@)#etF>)Z-yez@UzD zxn@bF&zGN~8oIPk4dfy-rEX5Ww8$EZ0F70%U;9F1W%-Z($&Ga-Maup1vncKQ7_DKl zn9!@7d$FjFqs1PKM)U|Dr6$Db)oTnV%fNxx{Okxr+DM%Qs^$R=K0p5VBBLXP|Go*uWAqrP!s#9EjG3Y5H)_%&0w$xIP8)2<gS?toB)4w_5VP~5v52jeNf?a@l%z&Ft# z7nB8|dUgD~fFBhAa+9}!Fnz66uJJUZMq$&Z-=x+YQJfJpw%hO;S zbE}u#&MHNeP>Upl#AP)>l0hdeKfNO4(#tQm-Akeu&02@RbFR7XY>6_k1%f(YAT(#fsAW zCKBlg4QBOIpq?mn>zJh1X=9x9hp4F}kQ(@481j?!sz3o)0BA?xOCB;{@vwLHR_qA* zZA`n>5_V~?==zrnj46C`9p$WNjB&zGc+-W7;QUT(*KSn_p>ds2!NyfVppL*7{NFHR zx3J%}=U0sLd(^D`)P?PxcXaJb1;-WXet3d^dmIcA@AOk%p(p(THF8j!=km|#V)bYd zpicX$PljfTc@O)})|@FD=Z~mC2i2imPj;N6y7k2(V~h2N*p=p#-z6}HxcB*hYkSJV z`IFSdb9yY-P}dA6b@>ZL?=z9&3we?^d^OD4aqs1Mx13&f#Qiy{cDn?wohTPSPjL-WpW1m}O&Ju5YPHyotYlm=9`GcY zrwYvY8;-f&ZSM33oCpsge2-Ip%afm3V!sl6q6gM{kN3J3%|Xrhwg)`uVUIiGY!FzE zIO3Qa-0aQX;)a}NjB&uQ|K;9KmvHqg(MeCoc*sw<&DEj$2|GyBp7MmJgBi=!jyvfZ z$6Ymtf^mwAKHp@Hd-~&L-Nsi~>l_hPjymE9wjDU*%(E+7 za!uA`P2O+vKSpg~;?JJlUH||9C3HntbYx+4WjbSWWnpw>05UK!F)c7SEiyAyF*Z6g zGdeOeEigAaFfi_TCsF_a03~!qSaf7zbY(hiZ)9m^c>ppnF)=MLI4v?WR53O>Gc!6e zGc7PTIxsMwC7)_* literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_48_outer_holo.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_48_outer_holo.png new file mode 100644 index 0000000000000000000000000000000000000000..f62f74bb38e8818fd970b7ec1f7862e543cc9d07 GIT binary patch literal 1811 zcmV+u2kiKXP)Q(x@RlU0R z*6*F+o^#JDHf2*b#j2Gf_PMBSbuGRn) zDJUkGcinCw!4`)d@_D~EMJnC5dvGXBz z^GjW6Gg4BPB{MBwxqQWN<0fP#?6J=Sj@WNJ!AH@8Kl`>9L$xnJF(@mqT0WPnt1qF1 z=Fx+;deGw@bGK5OQ+L*P{Upq+6DX1yGQbK>T~%EkI?XGa@}$o>ppa%>^8?Sie*2l7 zfHK3%D>%7|N++0Avr7*8vd@}G^Jo0fcfyUHfnsLZ&jU?a6Rn7I58e-AIzUHA66jy!AvGyBgcAIA_8&ya%2-o5w@+x^Frq z7x5uqjDu?ciVPZ-34&-=b^T>U$i3owu8N|PCmm@W9a)>Z@0e@OLVt>;Q1iTBsK`Y- zJ#Dm0pva)1q@Sv}wFUZZ<(6Yki*muoJ=kjDtmVDYq#tH=k$<|@5vTpkf+%-~CzQJb zDj5=FGBxvks&SW*YJTnCqA2*7ySf013>jGQpITpe;Jn|eigLRhZQhTXHIx~a$pm$C z{nZbIsz13R7nL1tHd-@KF*$Um(og?cC1;!x<)VYeI|B_UB@HdgHw5UWlj@?}cDp+O zMal|-j9w2i9i`?Cb8^v;J)JZZ3@FG_LfsGv{MVdZZorO4w{8Y134%<%0TH$=m)%OW z_@u(SziK>nET6ihG`KOcU?%zJh~m2+ycN)r5;qQq+h%%Xy;f)Ejn0a3UnsuS^+vZqWP#0th z#x}@k!|oI0qU+rNRV>J4GUFR$v|a9z%jMoM-5IE6CMAy{ll?bZ%p5f-7cDwzt|L%b z^86*Y-fp1pM3X+OAj(~JqWJ*PYCpbZCY5MgZSAj)V(>vz$zUg(ZywPKsOqx1Or~s4 ztCPVxWShrQgx&N<^IZW2u9-7hOofKj5BzxpoW= zdO}GqH|+&2+j}j6LUh@cv}2FCzaLvtWZ?^TwHb8;v&L-C`+P^-e$fT!yBz5Da{oL7hj@h;h3%R$P7X_J;dmT2? z8&V8*_<~22M7c%3b3D}BjlNwczv7fZds1ebGU8;svesTmESU0X4=BlHYF_eOt8iaY zL0I~yq8N;M$m4dU73%)xM=srNe&@#dxWo1;CZw8+{^f0pouFbc zV#*`lZz%0)HGlQf<_c&{Ktx7;z}?CzodgvZopY&OUp7)Q;eaFVO?})iuy4L9j zyLs2K^qSz1EvYP7>Ws{|~_-QddT;IiL%she&}m+lY?b~t3u zik_CPT+O0+6?K`iA!CLOr{nnY$OW(ay)*42s|TRe$lC9I+YPJ$b-IG8H~q!myML>= zroa>ruDyrb zV`&jHgSNQCgmI$=lu=hRYuXKOo3_xM&-4jsmA;l<3@^Ph&(-?zXM#=Hludb0$^QZH zs3&Vcm*{c;001R)MObuXVRU6WV{&C-bY%cCFflPLFgPtTGgL7)Ix{mmGBYhOH##sd z?sz9s0000bbVXQnWMOn=I&E)cX=Zr$HaasiIx;gYFgH3dFrOu# z?f?J)8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?002ovPDHLkV1l}_ BPJaLZ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..eb28ff9a5516c15667fa8fafbc22d608d1f77a06 GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?o1QL?ArY-_Z*Jr|WFXM+FkX}IYI~tj_}8!bFJ^a4j((ibs-&WN zGIsXEx)Wtn`lnsEAmpSFI79ccn9RKAsn<`<tk;t}o>yjV{qp%WbL{dki&M)*dw`x~@O1TaS?83{1OTcY Bcf0@q literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d281adb553af892f758407b846bf31810b9d776b GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?Tb?eCArY-_Z*Jr|WFXM+FkX}IYP%rckLbO*zpbz{y7bYSIrPClD)2Hc3qcaC*%7oYhKR%+5DyWbJ~oU4#{OKNlluqE0VJm zR?Ud&kaA;Q)O4{aB-unUR3g{I@EB82%f_aZWF5r`AFqi`v@HN~5*v&Qo>cRA$gv99 zHaapFv&*%1#4~?bwda`9)~}vNKHF@K`t|cGZ}Xb{RR4x!PC{xWt~$(69DLj BcXj{( literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..b2985860907ac324b509b76731e8ef9e01bcef39 GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?E1oWnArY-_Z#r@{8;G<#%>2r*^uo7)-)HXL@_O1Ny%Iq#{YfeF z(mvLmIJH1t&`=}DOJmBWhqv04yB582t6X;JXNKdwfEg3JZl{PztUeIIdQ8h8YDr!LqoiBzejNy&kDcJs%rP689)vmGI{X_;^jtl6gm^<0^v)GdFRa+YOJx z7F>vKtz@b&Rr+MtRJ_Cdn)*bIu9V&{pI@`*?C`z(Yf|Vzp#K;=UHx3vIVCg!08ssU A5dZ)H literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4215396dd4e51fea9239323d313b72fde0ba86d6 GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?E1oWnArY-_Z#r@{8;G<#%>2r*^ujlV;{V25Ur(E)S0c!zKPhEi z+Q+&RrxwTy8fpZ2X-wJl@K&30*P>T$mCG*u%y7IHFk@oZ?G!PI)dwP2k7*f%?N0KT z=P~Pe`QZt37-AUDv?qm~sFi(Y>bsQr3FCw4S+92))lbOG-Y30G>`_~0 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..a280eabf59b5eb69fa2a84280402b63d5e1bb8f0 GIT binary patch literal 524 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9q_DjO#pI977^n-`=$MKI|ZI{A2#4tV=npb9cQAXy4X!_bwM}{Q4K( z1sl8bnxc=22fURRmTQmkS`l-5N%{4LzmAq3{WkJ?oSyR(lyW*m>cW(jDj1r7drC_% z+Ahf4U7%?EfVHA#U$%eE)HUhV{* zGqMRv58QeS1t+_UJh{!Nwtjop`q`x&KXzE!mvvsrOU)9V|3+xFYu0w7ttSN+pN66C zV4oMA@AG&3wK%+`$wcPZ<#Ux2T-c9-*heq_yZUm|{V%D1UlxhJm0zYfUETgVr;hpA zt-Fj|Jsx=O$lYh^6WL+vBibSA6WURD#!g`Ij9SHG25Jg!2FnzxlYN}N9h%V=a_mM! z$e|leQ;yweap>IrEpmd};fhV2Zrn5uN|m^)*v*dyQIi{G2ej@g`j zy#1roz10ezmNeBYwbLI^0W9{MT&2dcxOa)`zb@?O?Gu2 z*S413TzCHUdV}>`f)DaiKP_4HkL&Y-WAl>F%y}d1AGY65et#XKh5dqWo7Y|}14bu< Mr>mdKI;Vst0N8Ej(f|Me literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f8d619b4d47ab5b104d6b1042c27fb16a3beca47 GIT binary patch literal 523 zcmV+m0`&cfP)C3<00004b3#c}2nYxW zdK`GU$CA-E+tg1FUj3CV1Ez}l7r{NB_YWZ zgb+-Kh;2qAgunr)owSNT9jE|#(}iQ{0=K~F)j_f4%AIwfW*LI4SCjSena$3zhl@?`-N)f>fC&00iU>|7tSL}YGdG832Z z7Ry93w=$W@5~IozqskJa$`YfBUCf~8@-tLEe(Yg7ZJ&$d5^vAJVlkbz&)H#>=1rCU z=lI*@D9QucAy4<)W_$YF0~q6}sI5vC!>ie*fX@E1>5KTAKqegRE>ywO`Fw(I}^ N002ovPDHLkV1grX;W+>R literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..955a2f34061ae8ac853050da355f89409fa0a784 GIT binary patch literal 464 zcmV;>0WbcEP)C3<00004b3#c}2nYxW zd0`Pl=$b2!s#>@tS z$Y#JV#)+K6SU+tW#+_RkXYzpRi_e9eTN!5>F{(z4su81V#Hi{OLkTB`etUYuM1<4( zFh4)_STHCiBAh-(+2ze7j|0M$*V@)G5^^0JhFHh^fzV_7Tf?-4Si|T*tYCB@#xY$W zMloF>#xN!zMlhxzoiQdMoiL^$+87%UEsQNlYm7|@05m?}iO1-}bYl(D3Ue3c7gw}A zD?zp;CtICi-;5NDtN#ybjCs$)&yQmArGt<$4!&l7(HXO5p7J23`oDJvMC3<00004b3#c}2nYxW zdPRE!~6H3V|7LaeL+kwzxO}{DvWjdA^uWhB*Ox4MVbeVt$Spwgkx< z!VkuXjKgSuY)h6Hw=%|LL;AyKLdLC(F?ASO9Y$7%k=0>jHH%rr7Kwb5&>UvDaCo}j z=j+357qeVAJX{{~a_138(!I8ROa__X7ee%7enXtUzOE0mAw(ah0z?m{B1Ao=21G5U zCPW=Z0YnW(5u`pwA*3EgF{C<11Ed;86J&FYMhHOp8-||_vny?o%`ne52fWVraQiWC zKdv-wupMF9(yd;3%<<_PN8|TOh%C!a80|#$F{54SO;q)d{~Z)(nS?QFWpYf|szS`q zFpt2hCCEz5&mZk`@i_(t4MLWruXxh=CcXUn1{k8P{&E{)e*gdg07*qoM6N<$f@(ay AcmMzZ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..673e3bf10d60cc54b6dfef2fcda24575073adf61 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1i!3HFsuehcLq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMgJWBc+iXw=G=Ra=)z4*}Q$iB}l;b6k literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_selected_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_selected_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d57df98b501944b4ba63623766c396b5bccc29ee GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1i!3HFsuehcLq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg}h~fd(*my85}Sb4q9e0H>EG$N&HU literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..aadc6f87b21d7d5139f3bfe860f4c289f75d241f GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!3HD^Kbl$tDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s&XV^0^y5RRG22KRnVX>4qKXwM^^Uwi5RN2-aD!@msM(PItf+&Xuw+O+F;e0P1D%boFyt=akR{ E0I7Z;-v9sr literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4be4af5fab3a09cce65144c747f24c6ade600359 GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DPvC;#}JM4$v^)8w`Z37Am6po z+v)2g(?$k`c>N1yj{}(xupO|Bb9m#eWaid)`oBujjyMLj^RWk-B)8T8wKI6S`njxg HN@xNA1NtG- literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e72193f5921ec091dcbdb7a6da540c6ae62a0abf GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DLqdY#}JM4$v^)8w`Z37Am6po z+v)2g(?*5`F8a+MS1=|pKR7U*C#OeuU+2*R28QEj<(b@LKCA=kWbkzLb6Mw<&;$Tx C%ODE? literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_selected_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_selected_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..8f20b9d2673d84e22fe4f92da5c6fba5524bd7c9 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DN9cm#}JM4$v^)8w`Z37Am6po z+v)2g(?$k`;P+>Y&mX9;kTm#w#$Mr{KU16J0f(K87k2#dS899B%AjFfa`@;vsXm|~ N44$rjF6*2UngAGyC2#-$ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_selected_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_right_selected_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..04f657e1db10e9694c00a2d0240c4dd96a062c37 GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DKk$O#}JM4$q6$m+Zg$O@E^Uw z81lZJ?Gxk7s`Po4Y{w3tY?zt;Z*oT>n?b-q29KD3>Vk*AGBMnIke8aaIU*2f0)wZk KpUXO@geCxD+9O{8 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_selected_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_selected_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..99309ef6d3e32a2d3303400aa061e0508a70f758 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DN9cm#}JM4$v^)8w`Z37Am6po z+v)2g(?*7dS92?$NlFNF3%qKd&uD!9kGjy}NRLj&jF%7WCrYdnXQ&Wp*=?oVF$ZV} NgQu&X%Q~loCII6IBdP!Z literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_selected_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-hdpi/abs__textfield_search_selected_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..9bde7fbdce15a1c2873eb0779ffc0617fd9b15c4 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DRWO3#}JM4$q6$m+Zg$O@E^Uw z81lZJ?bE^f8J_14%!p_Ru>Zp|qw<;kM2WLbT|5rH?EgED6zpZtm|hnx*$^-bXas|& LtDnm{r-UW|n`=evwJLPDoBk{4*AEnmdKI;Vst0H2gA*Z=?k literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0706c8af658bde9602634950dfe3d5fa5886163f GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%zMd|QAs)xyUfsxfz<`JK;_Z5A z-Y@ApO*&r-OgQM+#9X>wkYiu(tId138dhyGKCm}H$eLN@qysZ=3D*)nlM7YC@0xyy hn}nCMmBhQI$CPR`ipOiMnG7_T!PC{xWt~$(698&aE5rZ* literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d814d02d31183b8f00f475a05c124004983d9eff GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9EC|%_%783w8jlt8^&t;ucLK6TeKPwmj literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..b139c8e49168e4404df0a46b30a4b30e90c1ccff GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9ECY>s_{MVWOZ(=mjBT1_sGr W&p6(H%v1uJ#^CAd=d#Wzp$P!PC@9VV literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..738cb38d072137cb68723c576a801e3f3471bd3e GIT binary patch literal 2849 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed75a767a87ac573cb7306686035f2100459fb5 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)n!3HFaZu8v$Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#4jVIz7XKNB(EC6kA5Ry@5Rc=@2?~6F)PwUxdYTwn zdMu8}YM6Xys1i$1bTr(^uv&TM3(=CrV!crU$Q6V-%Qg7n#gTe~DWM4fl0G)# literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..743d00b6cd7e446c7badca9dd11d1579404569cc GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyUQ!e~V8Fq8aW6aH z`M>?!MSK0VJ5DH+1)MRKpSquM-S5BdOIN+&sn~jE%jQNlsf-1UY_}X6mMgq#dKVMx ha^q%Y#@a>3az|3`-r6;1y%^A322WQ%mvv4FO#tkfF|q&v literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..17c1fb921f9b7b46aaeefe7afb8302874fb0abd1 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyURua|z<`JK;_Z5y z;?s*`91mY+Vs~LvSAIRQ|I~ek>wo_(4hk(}+Y^;`>!t%UugL`m=C=w5f(6PQ%h%~C hy?JA^CG4Uk|5eN5b2qlEYyz6g;OXk;vd$@?2>`YpFM0p~ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..ddfc8e3d5c4131f2460254f183938477fc5a0679 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rhed`}n05R21qr&#kfCPg`@kT=WR_nY-)l@u)2m z9YjR(TNrC5J8zlf@MOx-MX#^q?zd~tP;1Ok`WbQLQ#YGy{=Yfu7pEGW;JmVaai5Cr S@!LSF89ZJ6T-G@yGywoUXh2*5 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..007a4b239244212339b817f8de9474a4dc34fde0 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%zMd|QAs)xyURua|z<`JK;_L&H z*gyPBj&nSGnTg$nOT)YjBQU;+O3-o%)BNS9GKrK90(RDcPwA0 ir}XBH&6co>lKfV`a~Jh`>I4G~X7F_Nb6Mw<&;$VSc`p(G literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..ad6e1a4d9f3c81e20676f979a53cea2084ce903d GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyUQ!e~V8Fq8aqs`F z7bNtyi1zwxcbrft3piseKXpIjy5E1@m#%ulQ?d2Tmd%Z9QW*;x*={*DELV8f^e!gW h<;Km*jJ1o5{)rFFF7K literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0ad6c888b4c7e436e7d7c78432dbfdaecc95a7ac GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%Zk{fVAs)w*fBgS%&%9ECxB?U?=uVx Y$^4u51wHGE0Gi0)>FVdQ&MBb@0N@ZURR910 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..19b50abcb536602cf2cd36d5a19805464988bd20 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9ECmdKI;Vst03^XH%m4rY literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5461b9c00fd3fc513aa4465682e70e87cca36a6d GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQaYY4jv*T7lQS|h5*V8PD@dJb zGfWV2j%0YY@&Et-(u-Ft=sZxsVYp-gbGr;f^5z}?TUWk$0o2Ff>FVdQ&MBb@07WJt A3jhEB literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc6f804aea8ca344275ac6eb497b6bfe0f117f3 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQd*uajv*T7lQS|h5*V8PD@dJb xGfWV2j%0Xds4&4P&{4SYp+J&{BRiiZ!)425)ejdW>;mdy@O1TaS?83{1ORBM8sz{0 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..a70b53c59af769e3c98973ad9718670ce27259ff GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQYM}*jv*T7lYjjGZ_h07hy7xL zS%<;BUsuG{45zRSgeB^>bP0l+XkK D`1l&; literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..85d7aadd4dfb619883f68f1cc63e629698b5dab5 GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQbwLGjv*T7lQS|h5*V8PD@dJT z6Fe3@|6GeFPb#ATqtK84|Mweqan0i3X%}$jvMQLwz#trO`SaWQ^{znO44$rjF6*2U FngE5o9^U`} literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f7b01e012f895bfe2c4241e1d48771fc372b35cb GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQU;zbjv*T7lQS|h5*V8PD@dJT z6Fe3@|6GeFPb#ATqY%TTAPubyB?B2J9?cgAJee4pt{u!zH{AaisF%Uh)z4*}Q$iB} D0X-aq literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d8f1c8bd54f4f091e79389603095c99cf825cb6c GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%Zk{fVAs)w*Gcqy~4zxBtu(zuW zGMHg-@7EW5UBeRx4_{GYv)%pQnG{Mujhr&UNqv-pZ`Il{xB Xs2c0@Tz2whppguou6{1-oD!Md5lfPH{+~ zs&ZK!$GJ#`+OXn)bEl7O^s7vMLr%~_eO6@BP#xDsWzJIxbKZ~=QHwoEqiCN;6|k~9&?6VGu8wVeg}kjlqBUkXd|o%rApJ7Xx?SmelE6^*`N?mP%?P7H@yM z@176Te{31>^aeVqCP$2D`iM8b&G*loT1#z02OAN3)TGUD#xbYXQgqexFre>@9yw_< zoN>t9>xRrEIA?_IE1YrUo=P<2hNadJXB=4rbb%a&IXb5^sO2P4AoU2`8OJ_N3+RuU z?3bPMlGWJT{|mv5xDeck3qc!^Tkv+yM^@uWqQKxnw{tZ6G_7EN(=@mR#5tHjEptZL zT?o!N^e&F18P*7EfGlP>S;He0o_$19Sz!q7up>N&hdzT z+KgUQr1}UkLQL4KR;yolWSqh_YPX?lMz7!1&pz~~fd%z~_Z{#V_yT+aKE`}mgO%s( z*Zy2en({y`_&;C`{0061zkwyNiuqzpAev$qeWYoU3d{J#NzC8IACaX$H=;%xu?3!~ z#a`2j|4di>P9KpnLiZ0Fl^vDJdHW{hJgNDYHbk!VsHwq51hhtobGl;RmY>GHkg{)E zesWUhFRGl6)Eh$fMU__)%@X*lTj%8LuWk+fh;ux9b*`$4|A#h$uKO0E`Tzg`07*qo IM6N<$f=1Pyg8%>k literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__dialog_full_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__dialog_full_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f18050ea589eaa31233bc08e4f8a4e361747bc94 GIT binary patch literal 1003 zcmV%vbFc60S)hq5aquQtN zO>~Q-PMt}eDy?tfo9G5^U3x~HVu{=o-l^#5`3AXbFq#7CZ= zx~R)Z%-PngELWXE=jG+4wH{HY%RHtL$z+_dj#xsD@Y&isDVlJd1j7%A; z{S3ob2!NCVl}{yrl8B^V**9f-6IC==^T()w$-W%VAY54pg(^F>UjitZxrB-eCn8Lf zB*stQ-rl}17K`6RG#lbS(&{_eIc1V`#=6_}di{5~T>e4x!ZPZXM|a{QRmt`XV*pbC z)5T)(D?{j2cRHWXf1>hHw<=z1GC@s9Ro2lk0Wc$?r`}K3Qx5<^GzKt(+iwt@SwZ#Y z1K3Z>bSEt!roEr8rydA`NJoVD>nPSV+2(05UE>4T005_GAOuI89vS#iG4B18N9tN{ z^Z@tNBTj+gCOB47*w+ z+2Hb~>!f2H1$Hq!D=_Sb+i%D|qnZ-1^bbIwX<}v&QHjdz0&e>kOOQ$(hHgzP5DjJz z0f>y6M3En>w55Wi4nf3bKUf4p>o0~xvY>6}4YBjHqH^B)8ba{Lja`ks{5OurR;$m< ZjQ=n8%sUGgc=rGR002ovPDHLkV1nUn!$<%C literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..df2d3d158e201f4b5bc8f478bfe194c819c762d1 GIT binary patch literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>S z4={E+nQaFWEGuwK2hw1@3^B*n9tLu5dAc};Xq+#-xYx_sQH13|{`71Pj-*6Uoi`#n zE(U8IKgsQz<^Rb4R70ym$22iPZttV^?_#_6n&0#=x|;ZH&dfx!jETDzs(0U>)g_uQmUhGGNWo+VotE}_5b3Zj`hnf_E}Q2 zkoV^c&!VIWreR+T-g@7!2<2C~cxLXYh02~hOPyXw&7V2OC7#SEE>Kd5q8W@Hc8e16}SQ(iDxmE@S#`ha8qiD#@ zPsvQH#I3=p$s!-9K@wy`aDG}zd16s2gJVj5QmTSyZen_BP-2>S z4={E+nQaFWEGuwK2hw1@3^B*n9tLvudAc};Xq?Zzc+iX4P{i%w`)y*!lC}nMxxP5m z`ipDd|3l#c1q-`17wzs7jap-@cWTC&8}(D4%&X3GaM#!SkY4?Tswdc+PM~^5?gXjDEJr|A(9^w&s1cyzt=Kg=58+)D;SHpB%sRSHFHUToUy>RV`*x3 zp=*`d7Z@F1xvAFw#q#fW_g_%cHx(CZDFFIJwZt`|BqgyV)hf9t6-Y4{85kPs8kp-E z7={=cTNxTy8JPmPRt5&f_Zu#wXvob^$xN%nt--0uA|I$h5@bVgep*R+Vo@rCV@iHf fs)A>3VtQ&&YGO)d;mK4RpdtoOS3j3^P6 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a17b6a78920848c37a67246a76749b4cc1425a15 GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~Ijou`Xqh{y4_R~-EgIfxwlm><>K$vu5h!wc4! z9iP>XtrZVs65@3e-rKIN%Hh(x{ewWxt1j(s|L*kJ zSoUnickXv5=i7?TNH`^EJfpg4#&4;Y0qR0+drTg2JXGfUq3}Rr;{P9f_n*&gD7KkW z&D4IqLivGGRq&kmAH6(eA0`F~7S8rex88HAVS=03cY~80?cpzkFa4S5A6;t}xJ7Q# z9-saRVPfVT##U33AAO3A+Ypl|_94?@cK)tT4*8AF;-^j1iVm!a-M-<=iX&Itr@TnW zJpXO;4EOj9!Ar}#BHVL6_dHGGELXBQqN>Q8)gj~`k@s=>rw|ur?|x;upO5s^{asBY zKb@S=&SWDRsQzHyR;N3i0@8Cfnf~0l`P3PA4VeH(Ut{H!I{}l<<aB zB5gMTgH*M|HKHUXu_VC#5QQ<|d}62BjvZR2H60 RwE-$(@O1TaS?83{1OW6u*u?+< literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_cab_done_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_cab_done_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..b28b3b54f4c81d482f797f31936cbd4013c093b5 GIT binary patch literal 552 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_normal.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..86944a879b986d941e6567d78fbac16c87ae9244 GIT binary patch literal 1869 zcmbVNc~H}M6fTFTAW9JhxeNgj51OPWje@pKfI5QEBA|d$+W@sTscjVKdVuS?9w2h9 zu!^p(ipSu+I*za)qKMZh4tTpGiYF)@D~E`is<``y;~$%us6_Qf>3EP7d8-+ zSuC3rZA?5JA2A(OQ+kfdV#CSM8yGZ;HF-*gL8aCaG%$}y)sn&B%ahe0pw$F}ae@dq z!XP8kwBcqWp)^OvsLeXHSOZQ80VZdl41u1YRX~P*0ck=rg27L`C^NTgLm=?Ugw_Rv zpPh=2hyrAkkpKi7I8Y4>VL*s*5FTG75={iSFakp`7ecs!hzR9zQ5XikJRqZH)TE#a zEcA;OvkC^&Xxe~6PXctnG=pit3hET2u2VQ z9~N<8VGzQE&zE61CKg~a1QT!t{T$!IN?{zwL_!$n$z%wEg-T!nU&6;R9*)6ME??M> zm6Ik~MXHH@T`i;g87m0=E*6y;2^CElV<>7te+5LPQ8Z;rqYQvdDF7l=YAtD5TdwDG zv>0L3E+#agMoJHS$}g(@hCVJsqzKOFTO4KL4hj`=LnW957mEdaK`0OWg4O(=oI#8; zkfk{OQ!M>kOa)q|UrV1^d~F_rWID#kv<4`i7|nFtQaL7x$+*=PcRNxkacMnTzT(!p zfRg6DJ1Y_~Z$G;tw~$ix*L@nh0_gy+q{K6=O-)U1ZBL7fiw9T#wcP7iz?I7*wg8n!aY@L* z%F1466IZ9xDGw&8Ca%%8-9N%k=5}B-gNg) zDs^~|+ru7gAfdUoeO*+YE(gj=-VB=VaaeB5#xy?WU;B+3~rnji3!zw~u|NB5xDgMA*Ab}CoKR1b4{ zl>=_SIAEWB^HRqqsb8t5;#}&X_CmjxL@oZX6x`u-Nm{2|`y?pbN5T8(*$@T`ZH%+J z9q+wi#oajjm>l)vpmE_mr&lY%70+^a$7TKT;qFtqhuwA!$jh%>ho3F4%BgGKv%2K0 z$HF4;&SJ>7KIHm~u<^wO_8Z;3y_c~N@r~v)LwjwHt(kkY;`G=_K|x(kncTb+Ti2eM z7yH!X-5fzxm)r79(!ZaTJ+c?A_7b`^xjVa7S5;ayZg6q=sKBA)LhBfI?7p4HG-EdX zGM##G-t1BC0PE-nz1YH|+GW>beOJO<&x4C?Y3_ohAr4Hb&I{K{y07O> zYq)siMdY38b0^FH-T7Vnp?+Dwy~?6uy>H4FYTQ}9{^zjW>fFu1k;Wnu$QYKv+~3MD zkL9@kLKD%Thtmq5^yY3(U$KE}2<_4f7b{3i<6pkgb<{dv;FI&fmd#{QXNuR<0GE-t|?<-_xFWf6rQD zvp1?(m;K#mK7kAc23PhCb9_I|Uwpe=_~P7`{<9hKeqT15)CmrGep&{}lJt6uiX0l6LDtGM?vvS&HSN)*I> zeOGt*EnBDP@;N{6y`LG()$~n&=KfpyvX&R-FPte;1xy60C9V-ADTyViR>?)FK#IZ0 zz|c_Fz)aW3GQ`l_%D~9V#8}q=$S`=EA9fW*LvDUbW?Cg~4U>%CWdb!wf@}!RPb(=; nEJ|f?Ovz75Rq)JBOiv9;O-!jQJeg_(RK(!v>gTe~DWM4f-EB1! literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_search_api_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_clear_search_api_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..15b86cbb21eb3bfb82d36aa9ce750906297a9225 GIT binary patch literal 743 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{0wkH`a%F)OQ-Tee`#-|*CiUbcIg;ND=p zYvDSd^|6iLOdqf$Xmz|*HxtvIt|l!1HU7>O^~bA&&;Fj*b;Hx}3d6&UEnVN=_&rrS zyUca-tl4jMo@$nFEpTFXzIjD+{<)ibKgss#-rp9f6_EGh??g@(2S&3=!i$ftp1=NR ze5Ls1tv8DvCnWJd(z*Zhh{1dQ0Dw1}N=Vgur< zo}V(7G@F#*B=UQaz!7tS(%x&E*VO)~n0V|`)7|K^f!Elpcvl1$gq+H{_D)QEMqY%8 z_vf1aTF*LU_FtRc+)-?b!3?Ao)T}9E5o1c=IR*74~B%^nkKn;>08-nxG qO3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrH1%F?hQAxvXq8M>Z zk&z^%c%@bRQ#)+nOe){kHaX!!Ue%|-vcG@vo7s2MJqBDZfk5<_)|-ZFZPj9NlZ$EDG$w6h z^v#+%T(e!=j16si)bzU4HWV6_^stND&E;|5`nfYv$?gux?t!>a1t>hEvKg8)f3B--`qJ5Vc+(!(3AIVr zEf|cmkv%DM(IHdcJ}Sgr>#(5~Tn4TISAy%nrQvE?Laps69ZLLT!~WS0QV)l|q?Zr( z+%hOrq1e~am)EDre9b1+$FL^?hsoiT)~9EmS!B=eNVF1PP(kFFm`ljix)2F8;hG8d=#8;jP)h%8u`(ez=ZN9^bNjAY1@m$qMwqc*3 zT<9Z^7q-4S8p!6dM-010M=(>rk1eytHi>R-cR}tW4SUbF89%`nk>dMSnMgg-f@tvLl z8zJ1Aj<77hi)&@}=LO_3nTIUJfhLK?)MTgjijKG^e1tcvx@U?wd-4zBd{w~Rm8u&) z61IEoor<-v>QlY};sLy%=GMYsYZW#7TiibW&xJ?UJ`JsgWSk4`n=4tN;yWe=Mb9;n zrw!^kvCo<)%-&D;l)PgTvU~Z|j|VKn#)IlF_j=`rkH?YbC)&niUyM-$#5;BRtd~Vt zvDwmlW4up^P2AqKxmr=aNvNMq0%A$n_A&Ybf8s&n?eE2(zp1N=^sXKmlORRu-MwkG zqSrlb4;RY>`GT2~ewsriQ0>5-Cr@@n4LZ4_+db%Z)RR$pECx zV&kKm<~rTWsF|5CovUxbAuX%rMqUY#bK_3MXl`zRlnnCM)JOk#@Q|`yZle2b!xrs+ z?}@SMBoaxAn*F`n4c~I!tWN%NL;nce-(Ln9T2XV@wz0+fUe{x3EWBVphWolE&ZMpy zk=t+u)*ULX*vshr>?xS>+y1VFi$&0ZQQaET*YU40s&SgZh;!v@8ZAA*DJJ>D=a=0< zFKXQ=k&~NZZGoK2o`n~+R8w?*R>uuBc#s$EF{m0(={u8TU3kQEm9SfChYCn7J#=g4 z(PaFJU1FFZJS#?cN?VCdd62LmX1(Q&iCokv9@0&`0c7bz75vdTSAVg)Dte++U_U8a z)M|^@vmd{xiq;M1c-`XC1_k!;*hJ-2+0wh;$&M)lJC}axPr((&K~D-GVw^}ZK>;xo z8*&r{B7jDjnH@k`96(zW%`9zDXdCl`2T+hey^ru3{!bx1A}HkS<^L~SLob9t1%PwH KV``51)Bgpr>#?r@ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_go_search_api_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_go_search_api_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..8518498eb6c93e3d4f9f5c806362bf3117b17852 GIT binary patch literal 570 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{0wkH`a%F)OQf4-y`wRCHWT>4=v6Z~W)^Ex~}&Cks#3Ph?YL zYs=^PA1JbT)~OR;KkxqfX5VYCuTH8yF+BVMK5jv$P8>M!p?~7X|K_(-ZNE?1#j0+Y zX}rfdsOO!o8=KoP`};Z1zsHB36rFKS#YJJm49Wj>o1-q)hN%bb=nB|jWMKUFU(#;% zzNwwTK`8{^tVraaWCe_M$vxef5w0QpFdP-veDuD zxhegZ|L;vckoBsbjg4*D|NoLZ`&-4e?`K!s|My<3S%8^2?NH;i6Q(?qt2KRNl&_PX0wV*1 z5qGtn%`^R9z@Swvag8WRNi0dVN-jzTQVd20hK9NZX1Yd}A%^Bw21ZsU#<~VThQZ_f zu&XEx;QVw%w1wevX{81fiqT9$oZHH(4a215zM2{s3I28IOo7eJ#J d>KPlRN5&o6d@ywr|9haR44$rjF6*2UngC}HDAND{ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6bf21e307ed392bf00fe80b162a6ce9115e62c84 GIT binary patch literal 332 zcmV-S0ki&zP)h$s=>Sb2o({EW84x$2Sq@4Qvb1mj$j~;VIQBr2GX>%-APxay9!he7 z8W7h*gD?q**@0LXh%12j6cFzN;xHg)rA0Yl3bh0|IM)O5QD`2|BGz~0I$#-|1SL$5 zlJGbV2jtPKD8?58g7k0zp)`;V#9XwljI@z*K`Om-0V(CcdbDyt4~XM{*o)XuqGd@4 zDx{8=fp<=lEG6&%R0000-rS^s>8d@5ni2hppU0iV;YH8gwNa0%) z{Cz&}Jx|SbT`f+uL?986Pnf0|l@f5k0jz*^zeXXD13Pe$Xi*7R9^s5FmB7$P;6x!% z=kMH0V6IZ20v0@I38qpwTN6bU0_>(U;T<=GYX-1E8)QG}f-;!!681nE=wJ-aU=KPV z^-i_I3K%>@EawIsd5_!T)2R?x1}rE&N|%HcIQa;SqE5+gRv=Fy@M;YVKt`niqbhVk zpSlae%z=$G2Wp@TnqrmWnuKgf72^IDIDhdq{E7X5-;T%%62M`q*b}mOv3|8DyoG;R z;O#l^2#-VHDcnmy=|6xRPAT9SP9@+QP9YE&4z7Z?SGPkvc&h*a002ovPDHLkV1j;z BjTis` literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_search.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..4be72f108ba1a4f36da5c3a59b1ed08ddcf7cb8b GIT binary patch literal 2280 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_activated_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_activated_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf8e03623c94b68d31963ffe7e59c72c3dcc059 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`86o-U3d5>t~CW>mH@a{g&g;s7!l1y4Byva-KaJLVIiI)OpBYodjS ofJx&-C1HsL_x|*Yp0_#7zz}{&aC*>dO_0?Lp00i_>zopr00f~Zw*UYD literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_divider_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_divider_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..986ab0b9746301f2dd9401829da09e00995621b3 GIT binary patch literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~qMj~}Asp9}6B-)+^BAxRtXRm= az`@Yw&#rLZUbzUUfWgz%&t;ucLK6T(%Mo}0 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_divider_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_divider_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0279e17a123f8cbb3c7e3a9ce5c5af8e693b6977 GIT binary patch literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~!k#XUAsp9}6B-)+^LX%RmN2q0 Ycy4A9FVZ~13zTN?boFyt=akR{01+Y(GXMYp literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_focused_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_focused_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..7c0599e3a6fcce1d9b22e47bfdb63afb1d3d9c02 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSjZF4rt@IU_AhE`IYK8I wIB$ByaB<8!;4zVtCm{dd@wVRWcBu>u-xEd5&snyt0Gh?%>FVdQ&MBb@09FhvcK`qY literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_longpressed_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_longpressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf8e03623c94b68d31963ffe7e59c72c3dcc059 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`86o-U3d5>t~CW>mH@a{g&g;s7!l1y4Byva-KaJLVIiI)OpBYodjS ofJx&-C1HsL_x|*Yp0_#7zz}{&aC*>dO_0?Lp00i_>zopr00f~Zw*UYD literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6e77525d2dbbc1673145d60d775602c85264330d GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSlBa@C*nY4{!0_J9HA2p woHspUxHx7V@R-QS6OjM!cw6swyHo~-e~lvMp^1B@1I=RaboFyt=akR{0Ay(_r~m)} literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_pressed_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_pressed_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6e77525d2dbbc1673145d60d775602c85264330d GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSlBa@C*nY4{!0_J9HA2p woHspUxHx7V@R-QS6OjM!cw6swyHo~-e~lvMp^1B@1I=RaboFyt=akR{0Ay(_r~m)} literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..92da2f0dd3711a2ceb843768cafd6b91a2807b43 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVD!3HFkzrK_Oq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg#;uvX%d>fBtxy+SfFGJhTv9Z9>9n%%Tr7{oI+Q@DMao9hQt@O?p#8;eZd15IY| MboFyt=akR{068-?^#A|> literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..42cb6463e4c28c6aeffa315c4fc869867dbb6b7c GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVD!3HFkzrK_Oq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg@oJyIHz9Y|%SiynA|kd)58s-{92FmHki*;@KxND!%;H%=F4ZU(n;yg$GVRgBd(s L{an^LB{Ts54)-;@ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..460ec46eb0786706610e21ac9097de489cedfc33 GIT binary patch literal 651 zcmV;60(AX}P)!1&^00004b3#c}2nYxW zdZ_-Wf*5)VugS&t+23J}V*z%DOHb#W|`Z#l>;cJ*L_P;jGoKD8nX4Z`xH*Q>s zTvTl`b;%gqS1znaOc|u@tz3t7=|UK<9Hr>BJ|D1%4AOYzE>c>YASL1(e+Y^`_iG?7 z1UL~EK(|`0e*W#*UXt~C{TfUweyI5sSBLVgO?u)p&e9+4(C=i^T1GuQJ|j^LdEE0 zfZFjzm@Nd117_`XxKDqSoJXh_wG-}tW_yHE!!B|TSvyio<6k9eTgoG9O0aTdZJ81x zmbul8Z%fpkT#Wc{ND1L@No&VX#iPVF7hx`c0JdkE;3e2%ZBQYi%Oe#dj=&z+_I>|? zOJi$dCv)FoZJG3n&>Qp|;vSo*JOkf=A5uR{`;uV-QwsX>Ho!a31HXV*se5TxFFA=4 zo=3!%#5;D2+DO|6R;c8b^-B2j{s4XhZw!t1m&l3O!HmBwHn=!)kb6yF?kI1MVX*Vu z<6hz)DH{^YBPWDzO$|0isCW3@P>L98oO;C$E5=4jGEPjLS?XZ=13IvJLaC?O;nLn? z=e?6_T^b`&$N3sK+o1N3^-DyB&=+_N>geY)_rHdJwBJ%s{^4(_WBZ5MLQM53U4RfX laXn(LVYMe-Njr@(d;;;gyUim^Wn%yU002ovPDHLkV1m`SB-{W1 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e84adf2d41604323cdad8b15e7034b6137e02425 GIT binary patch literal 720 zcmV;>0x$iEP)!1&^00004b3#c}2nYxW zd09!jyup9SJyH%;E_KZI5Ed^B*iNJmRSj zBG=jNc2B+cMg+dzb=~X>SwfDye{PH^oqQ4$1^~*55|NVv2=ckIR8XoEqC|oOgc2g; zEPA&fNb-^8#Mr1#v(VQn5UdVR@QAWs>EP1 zTHM9Zaim5tPqqk+y4R~ii**RWgPIHWkr2Q-rv~$oD_;OFg!*vQOJ?oR%RhjSvm}}N zU}~@)A@q_TOphE%y@J$^Y;2GXG*T-_?U?-%UNYKi5n>WcgjmBq)+~pV5UB*Fc4!_E zr<_OV^tE=(@|l_%K9#lBPBbeU!!Q72CYl{ozqWE(s>}kg*Xy-fB`%jskbX;(+jyxw zA`k(lb8|^3?6_RfL_?Is~gyeh`O%xX?U(f4nJ zaCd?*qxs3xYk`99o-U3d5>wYsbmTgqz{8?`Dg4L(`abqnuZs;wTVv8ZBg|GX^f4xE z5ck=nld$UVv7H|oR+P30etdkz&;0SSW2^3}yn7y4rozh{Dy3k((DE(NNCr<=KbLh* G2~7afj5MhL literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_bg_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__progress_bg_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4bb22f0e10e621ef31f16100b3f682a09565c65d GIT binary patch literal 159 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 RY6Dcn;OXk;vd$@?2>^cl_{IPL literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..29aff4d43f71a025f464587ead52aff2ecae6a58 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^59s(?1)eUBAs(G?r*GssWFX)$e`(35Y8e@;SI4XCdOETn3puLX+U@Np z`{}{9$F@!!Tb4}GnD8m&^|D{1rP|_tuSV&+Z=MCoD&l+{? zpGeMToA<;$LF?@fW~rUl3#RU765DB+Fm*PQ+)k?pQ&%&Ye!A+gR)$OeeXHaR#_cxq xcQACD7BHRDw&oXmu9s(?g`O^sAs(G?r*GssWFX)$e`(35d_EZ~i&w|H<&_`ZD(+MedV5zj zu-#_I+lqbxCf!wDY`(!qq|2YPZ`s2sD|KqW({JG~4*WL+Cpx;A`7$XPF&b}JE9dda zdDh0P2cC5-%kKDDBus2)4y)97FmX3?+)izQiL;plcWMSG#q&-%rTF<%+zn>y2h*Mj yizj?!^E*(P`ureMOz-ZiFXWg1cX%y7!FpSm=AYI1UI{?QGI+ZBxvX9s(?*`6+rAs(G?r#o^TG7xZ`zf?Wo$i4qI|8=SuS_>z)W_YPj?%Q>u zIp@ANM{x}Zqe@#*i-Jc_;!9;KcT)!P=e8Z65pgErb%iKSkCNb@A?yTt$n@r z2c`IHF%KKu<@hR|E_CSLV|hUMOZy3b87rAYm)KaVUb9s(?*`6+rAs(G?r#o^TG7xZ`zf?Wo$i2t+|9e$2v=&Zo&G1s6+_&pQ zbIyHljz-QjH&*S{-J;(gu&3N>@$LMyenNedpai4+B)&;SOq0|eu$bkReVyxuhm-Z9>GFCF_99MaBsxVXw=u8GrS3j3^P6KmrqN>Fc^oQq;b>Mt0(a$ z!tgX@A7RK4{kGy^A3#w21maN-UfpV|U0)B)Mu)Zk(%$xiP)OBD#retJ&sicWsshEL!WHUI0Z}S=i2Rqw=-{<_oUlU4$I1(Vt^KG}@Sd2k4!kUV zp9d;G14UN$xn@Z2Tv!X1WCiPlZi?T5Wo`s>dMMw4?2=HB&MqLoAdzh3Gg0e200000 LNkvXXu0mjf#CNP@ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6536ee63329bb47bec2bf2384aa494923cc2773a GIT binary patch literal 424 zcmV;Z0ayNsP)Km%mHHKmbPH_0G1~QE(|Z z3L*$mIy*=P@!u2&!BHHFf;fuc0uio1*2@YRBct9{0AyU2}iGVkcWw7UUPW(q{Hz&m;6;CQrhm;h30w)z2(`W_Vv zws(S3@Pah`KM=_o2%_3&n+}O86bq(Ag>`_N^4m7drC>+{^&N;72|01L0Qm!AONf3s S@;8qF0000Km%VDkFce0=d)+vOWKIG} zhpvGvb*AhYN}o4m@H1o!d4o*tRBGZMkUCTWmkL{wB~SUlAntIEgw4Gc(!&*+NcHqe zdbonr;tjwaz@#r!B?pk5-j_#K1)p#z)*b-3QShBfQxGf+4==MNa*z{HXhG0C1P_4~ zh;-k(7eP#tUz1`!Wij$Dh)MD;xve&Fv5GXEp_kweUysY@i1cm8S?~wm($ky-rf?^L z4cuB_3%3%uz>Nj2a3et6#z@uGqTe`wK1>2-pyo{<@B~f=x)vOqS_S8F z{BbGcPm`Srko*>0TM51dS0?bbgq{a9*ucpHu=A!M^DM~~^Y@aViMI>L4{MrZFUa%^ Q4*&oF07*qoM6N<$f+pdR_W%F@ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6de0ba8841d25f20f12e14002ecc4c9ec6a7b2f8 GIT binary patch literal 370 zcmV-&0ge8NP)Kmp@CxKpa3{epU;uAYD{w zoy1-2XXsG+d5c4J(@pInLg`pK=_I6J(k2d`5V?BE{Yj@j2pl)OcgK;0qd#7akgCKEJ@PeExDlrpx^Tf8?8gJ#K-Da<_nm z+&*9_w+lGPs|OtA)dC)JfQDKAb-?t#>nbk~ygr<>n4NOeOiNA8R)UE3F)|0PZr-`P z{wS3Lh~%_Rw1t=h$DO2-+|>0Ilo0LghZEP}j*Edw;7F{TKbM3p1iOHI0}cLp61dt? QIsgCw07*qoM6N<$f;wQ9<^TWy literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c9972e74bb4fc7416960e238afd47b1ac363e316 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDd7^K@|x;h4Gh+(zC520Y9MizoD2>~^~(JZa^V pUoEkkaeSh9w)TUlKa6vZ+qJ0**((%Vy8umK@O1TaS?83{1OR&wE2RJc literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..587337caf74f9ba3d32ba1c7cc8fb8b0b5ba245b GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDeo^mK6y;h4Gh+(zC53JlB#xw8$}k`45e4cLk;e3y7!_%!uv(Z^d6 t0#9x~Qa^f(Id{#0H&;LIP<)f9-+fKc+F|3Yl|VxnJYD@<);T3K0RZ_tFJ}M% literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..155c4fc753ed43185b31df3bea2af1ea5b3e7482 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDeo@N{tu;h33haPQZY#>U2n_RP$O>mRT6my}r88lS< uMnfl1c4A|rBX^f%!~&s(1*$LFm>5oL2|PB@cz*+E5QC?ypUXO@geCw>u`ROz literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..081657ee7b828a74287d65d2f4644af9c7b55816 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQih%`jv*44lYjjGZ_jMS*7QH1 z$Cu9~IqOiSz?8?{Eo||(vKg$oJDqvb4v1Q5NJR27d@z6V;avVV1E6LGPgg&ebxsLQ E0ED?8Qvd(} literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3f312b465189caa47a7f8e4bc53c3222521e0bb1 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQrey_jv*44lYjjGZ_jMS*7QH1 y$CppZQKez^S5>Et`mrVp3OWu(*tYT>W@HfhtG!C@Uj!>q8-u5-pUXO@geCyVL>!s` literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..b086fae8738227fc0b4f05171ded25ec1503e49d GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQU;zbjv*44lYjjGZ_jMS*7QH1 z$Cu9~IqOiSz{ak|8`Hl@9XRLoNT6Brf-|eO+cr*y`8p4HWnZ4T3DnEr>FVdQ&MBb@ E0JhyB4*&oF literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..73c336a77a9c908532b5b39098c22a878e0e87bf GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQktGFjv*44lYjjGZ_jMS*7QH1 w$CppZQANR3w^={dWI;j4L5+C_+aEG8Z2O~g(C$e@C{PoFr>mdKI;Vst0EP1$iU0rr literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_selected_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_selected_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..726e0ff427cd175c9c3607e25352bd696a3152c1 GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQbwLGjv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONwVb}j=LshAN!kv;Qt~79nzL7Xt$zT{YC1>l7eH(zf89ZJ6T-G@y GGywpjU?4sK literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_selected_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_right_selected_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..726e0ff427cd175c9c3607e25352bd696a3152c1 GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQbwLGjv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONwVb}j=LshAN!kv;Qt~79nzL7Xt$zT{YC1>l7eH(zf89ZJ6T-G@y GGywpjU?4sK literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_selected_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_selected_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..1767c169eef03f3370b0f8e40f531dd481a9b82d GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQYM}*jv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONw%V+tnLd~`l!OqNzXB@V%srV-z^vGhE?K{(iZ(fQrP(OpGtDnm{ Hr-UW|vZo$& literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_selected_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-mdpi/abs__textfield_search_selected_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..1767c169eef03f3370b0f8e40f531dd481a9b82d GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQYM}*jv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONw%V+tnLd~`l!OqNzXB@V%srV-z^vGhE?K{(iZ(fQrP(OpGtDnm{ Hr-UW|vZo$& literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-v11/abs__progress_medium_holo.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-v11/abs__progress_medium_holo.xml new file mode 100644 index 0000000000..6bcbdb83f1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-v11/abs__progress_medium_holo.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..575334699663b221b5a2b3251572a7c7a23ddb4a GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nET98VX=kc@k8Z|>$jV8FrZ@U7ta z-*T0WQ@><>I%v71J%hiqt0P@2{q!E)%~9Ermd_VC*s;IdoBnhS>rHk6>|lcSgpVF9 tjEp}SQ%vGx1w)$%c)I$ztaD0e0sua~Gttc^?peW`&R>iA3bc>G)78&qol`;+04`QPF8}}l literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..8155fe840532e1d0fc25450729892ea73c4e007a GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETTu&Frkc@k8Z|>$jV8FrZ@J;?q zbcL8uwC8*^`8m#29p5Ib=%`p$wC&7oqt#odO)b{rdQv>$UUk^Hs0pFVdQ&MBb@0G6aYR{#J2 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..fa4d76af93de31de153c6a7d41c05496bb14d2c0 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETcuyC{kc@k8Z*AmdP~c#3C@cDZ z^MXtGfey<_%m2nWx~HUtq@RtOD!V+x#J|ag^QD{sZZM%<(R`m!o+Hzd-iC%RO>bP0l+XkKAqp+G literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..9a70a5d1e3ad43f632287aff78d86289259099db GIT binary patch literal 2878 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 Xx&sG-cNbs*00000NkvXXu0mjfHD**$ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6622cbad34409b2e09f69e305455482ee107baa6 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK-lVFc4sN{QB_B z&fog}EEk$2&*T)$|Ch61%h`96?xa8O-xitu^~t0=vn)PNZ(|U lO#br3!H&B!tiEU`L+e4N?emv^?*rP(;OXk;vd$@?2>`X4Gjad` literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c4272978338a232aa445ed5190abab61afcedb16 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK^^+Fc4rl_yt@$W?82D^ReIqPjo#d{bLmpkiN+x lnf&F6gB^EeSbfn>hW*nwPPt#_849$O!PC{xWt~$(697sdG9dr} literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d0df29d8b3fef9f71cda9b7a0975c68dcfb05685 GIT binary patch literal 290 zcmV+-0p0$IP)(^RAa&-b-qmfdL= zKY^DZ_=R_1v^+>Y{!mW=MF!v|2#Q>Q>z_&4i6T94j-Y4q`P>I~g?cE`S~^QhBCU5$ z-8a`dJ38hrt)qwm8XJx0+%VAuW=z7Jg@`1pBAUrf#Ef=wZl|UqH7RO)u1OwK(@xK~ zuV&5*5lN0GQV~igR!o15*n1TfDTP6ilQ72>QBJOyK^2jQYHlAzlrUMuFCtAA$s$=K oi)4{qME3aCu~lSF#Q4a(0o}otDK%H_Q2+n{07*qoM6N<$f*T@rc>n+a literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..a0d9c1b957ea4a6ce62abd120668610d0cb2bd96 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK^^+Fc4rlxca~( z?t=fRa*SINS}wBuewp3mefy2x$=b4i8MC*B`RkorJG1!P69>HDUX#kpcm>9d6MZKb ky7}`x**qcrtNL{AY0h>p*ZiBQ0JN3C)78&qol`;+0O3wK)&Kwi literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d36f99fecf223779432fb843b823c04d739f05cb GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK-lVFc4sN{Ca;{ zvU;8e%Y`P%GdTtG|K%*$a`xS%JL%8+w?$@ueKP6JEX#C%J{El7iLS?_f2=|R(l=Qo klfOK1u;Z=_t1sHgP`H~Vw5GX>6KE@gr>mdKI;Vst03NU~l>h($ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5ad475dc3f478734be31bc5763ff494e5f120914 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETR8JSjkc@k8Z!P3yFyvu&IDfHo z*MFzV3!h#&I<8{wJG6*7%`^0A*`zgvpO3}4Jy+2bzzZhGPxw0F1DlG16;n~mnRAu= eo1*Vq{$#i=98+;OAz%&ALIzJ)KbLh*2~7aXVK40f literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6ade5eeb37d8388813cee512f8adaad0f6c15397 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETcuyC{kc@k8FE8XhU?9M9Fk3-& z>Hkf73eN%?4n{M7dy#!$d2ZSCCv)eTUt5@6!ODmi{A7$QW>Hb7V|gN6#Q)yLqkTHN Y-hRf#&+ODnfL1Yhy85}Sb4q9e0PNo==Kufz literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..719b9234df6fefc32c628a212141681df3414d85 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETB2O2`kc@k8Z(Za)puoZEAojv! z?q20mzFS+?F-&~oGw)ovvN+_p>pJvXn6S<7W@Fox#)9&t;ucLK6T;ku_WZ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6da264db26b5debc433e570e454f7ad596d3609c GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETbWaz@kc@k8Z*Aml2;gwNxP9_w z>q*543$-17oYd6QwPclDxvFIP6Y06uZ3-`2R5T~}Ha6e^YubHkRDB$o9=Xj@xc>Lb i$;LIUf5PjFDj6>?G+3v-_OK(+N(N6?KbLh*2~7a3Fg*4E literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..7ef2db75e273c3a4fa34a867d43714d47b67dfd9 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DHBf@#}JFt$r%|L2@FmD6{OlE zCs-P=E^ay;FECBu-~a#X*$!!Fy;QT1l2!H>nDyu1;UEQuS2t(=%(&d{0o2dn>FVdQ I&MBb@0Ph$gIRF3v literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..2283b4c01f31c24c241101989a028a28e662ff2d GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DPvC;#}JFt$r%|L2@FmD6{OlE zCs-P=E^ay;FECA@!GWvmzw+t@{SPuqdTbmsKKbP0l+XkKVJ9JJ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3c909b51306d684dc9fc4deb674ab1e1feb7004e GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#xSIG!$!Ar_~TGcqy~7@GboNVOeo z`FL&lz5>PtO@Rj=>T@VLG&w|ZbqQ*{RI`whRrVK{_2=K=E+vL!&S{*=@1z8QW-xfV L`njxgN@xNAaNr>U literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..131d1030c9d5b447ef62fc8e336d9d3950ff7519 GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DJxGG#}JFt$r%|L2@FmD6{Ok@ zwtT#{-1s4r1MA|Z!|?(x4J`lv|6k8`NJHzTnuV0CvcJHrKmQJQDKT8Re5&^Sxg#LM O7(8A5T-G@yGywoD=q9NE literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3e7dcdfdbaf66d51a90633e6f601bfe71b0c5069 GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#xSIG!$!Ar_~TGcqy~7@GboNVOeo z`FL%)@k1sD*2PVS;{{wASQ@v8h$x3#@+~m2a+{}M^7C)Is4GMKie-X3Pa7xz&0z3! L^>bP0l+XkKapWP} literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0bd09806f5c85ad3a33ec80c2a526e9dba34d1f3 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETTu&Frkc@k8uN>rTFyLXm;P>R{ z?#-o|?nQl9Ua&YVWQl+9{Kh9CkJo#*NAA>4+xPwD`<&mEu1}vZI664|W68WNxRjX* q7uY2C$wZnF2qKv(-xu6mlE@I5@4DcHNa}B(#SEUVelF{r5}E+w(lnv~ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..43ed26d4784aa508b93551bdb0359b959bd2c91b GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nET3{Mxwkc@k8uUzCjV8Fq8;LR1* z*j37dP53cYgnN@8iE~W|ez(m3TTj;06C0 vR9@;$usQD^o~Q2-Eg&#Ke!|DE+S9qyz8u@<_Da1C=l}*!S3j3^P6YLYC-!V(AVEFG+v!>way|q9)89ZJ6T-G@yGywpFG&bP? literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f4970ad1c3278235157ac72f71fc98f159fdc439 GIT binary patch literal 2159 zcmV-#2$1)QP)7pj*K04R=GS>IExgb+dqA%qY@2qDDdSi?}MdX75WMJ|ri_~yampZf~b zyDwJPzURp0aERFLx!K0Z6`{S(+b^7Rq0fZm(kDLm@P!|`&m~8kF)y`OQ+*6SLgj(n*c6WFZ`T<6tC6A%w8 z+L+Kg_>sWYRhaz=AtQLA^@LuUvKr4zS(=h&ATdHMd1uOv+V9M9YYe+zz%fKlM3B!~ zyq*EP{ZyC9dltDoQc<8ZrM^eE_Hte#g^dKR2>{;+o?xX#_XJ<6fcSW3 z(2+n3e1qrFpfvl1x~?#Fy4|E$M6lRgKuT?d8dD>b&VB465lv_ms575+OWy%#u@k+N zI%?Q+K~hGrT_7#|a=gF%@ZrOc@87@w`1bAFU(2$bW3Gd+|4`xmgT=9~$+>Rd`_AEe z?tAPdzh~^4zVA1WkB@)c-QE59<;$19v5OvFA}vv41E1cCHa5&@4N;9-`R?7jpWeKA z^Yg>QL%m+FvDt*4cRX_bt0?zBkB(K>DX%%#=N+5R(_-8y- zVb>j!?$Wbc5y%%}IfCs9*+@_USOKV3tJQDczI|KW-rgqvI6{s^UDwxjUH<~$ckEhw z$wzfwA%@V6dv=Zxn=8;sa(#b)ziOIh-@k{Dz1VCvD9chBW?(0HZ$3-*gQG?|lNRhy zsce!AuP~V46@dEg?(QVrAwo2L-=l3?V9=qSyONQk&Kv_~&Lf1nMm8E$0BV|mEX9~d zNP}Lf5}1xu21h4T$+9&-HQuut%PRmY8i6duXoOerBY}OxLGlJ5BU$zc%^yh8OvsW{ z7(^}+!OmYLNsSuWi7|-^5)oDyq5>gHA{u-eOKk`#f#=$OmM4_(@m{kC%_W5DAmmhR z=d>`52C;YCwuB;r{%j}Ebe_P7K+b^`h8A8*tydWpwYtuV2y(IKDEl%UBLZ0(i3V1m zfUn~Tp;05RlF3Ax+6Y;a8pF(Tjoo`iqE#Ca+!sAl5kbmO&cKL3&H*nkK%{gluy`-t zg(lV{G7z#PI)C*NX293=me{C~cPz9KvLxQ9W=NZ^Ugspsp|?>vp+=TQM}wGdXLXG{ zVi`Ci0$G}v=(F^hV}w+)Oe2t`iJ2g)`#yKX$5zN3ft&-L4rl3d-=WWF22RL{IarUJ z10V#?jlh->hk8-+(B={{f_KC0$_Y6UbF}H| z)iXk95=}<}9Szz&zBnPrq{TEU=*R&0y55rN8c7*TmhI~1gq#|$ON79_OO5CMyD7gV z9}@irgLxzpwBV#1S)NvH5*4HjnIZdKqfiE}-PZx=`o6zC@DCwmFGlT6G>P~~(uABG zK}Q3f7d(yIx@nqEUDtg*;O`-1HeJ_!ZJOp2fHih{)cJyq3PN^{5b9^?iHmLcxw*Od zt7)3gecv~S{b_{c(f57RG|lImo14Ed?FxBAs6Zqt*x!B;W5{pK*JF7#9(y&G-;L+K zAIl#wtZ4Xp+<&dElXaOZRbPeOuW5VVgIpFOP7$z(T3Yv~vHW)|AI5VJTZ64^6BEBSg#y zGM}I)%~}j17KiFDEnOcuUt#E@>0HCEcF3*~0j6Ce`xZm1O5Ih`IeuTN+ty1RWW4eh`~TOU@&BM)3MkQgMM@bdYm8B8c#1 z#@ViWE78D40!D<(#Tx`hXJ-KSDrqoae31hLi8 z$z>DjeP}^jBk1AK*j$2rhW(rzJ{2JYJMmiAitr^tE-^SXloO=ZTOgN*_a2ZHvyBd7 z1l@JghOv{s(P7lwc?A9CfSo}^z#H{B))n$biD&`>gkS9e;$0Z5~J8tXRDNuF002ovPDHLkV1mNB_TK;i literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..172fc3b5e3caf3357e706be2a1f0d91f357c8e5f GIT binary patch literal 2302 zcmV2ok^m97efLZMJ76bgmHN3TVPgynL1iZF^o zv0AMLkI|bD5@Z+S7;_RWD$X2Q#-Gi>; z=tN2`078B~PH0>efZ`B@1i||(&~g>qMGRTwTrQXXbnj39hPAQB*)bIg_=HbA_WGzO zR;yL=j9HSDjSEl*;KYv!A@o|O_=;IUA}l9+ObGitX|Dzg#M7mV*iktr2nZlVbl%^^ zH53Ym36TIhGR!|u7{3PC~!L=Y2z z32ZT8B;zY)i(nCqF!62X25hwu6@!!-aVKznAwf{$S4ay%(<6lhDJ|l}=KVE%xD;tO zjxokGV%Vil6ww-?fi&aiwtz1TI;KLw!36;9iSC?$w}w5ZTIo^H5hBZ^Apum+pFjWp*|TRqUSD7TX^iIhX;RaeQQ zE(9uq^MWzvYwRam(2Co38gn;jAmP?U& z&MGvUhjxmcRMYbSg3kR zZt4g}LPgLEq&hYm(J$si0u;4;IwvxY6?fp6l#|X8fH;pmq-q5ISi1H|(Ge;Lg>w@fkyi)P5d7;2~0$MDQ@!DE$`cg61AQt41xJiqTo9Dlsio7bTA}sD9BZvH#!%wZ zmJ%ND@1^DnZ%X(Ld?$$A6k0J~NE59ixD&!XX{j@~=b>7mwKZvxCyp*B)cAo?C*Y0% z?1kZeY?X^e-9W)XxdpU^5OahW`IAUpYa}@W?W5#&t4q8l2swcYLBS!VH7P;dBP@_? zQAk2?GdMjs_n0oBI`TV#(4X2ifxe2hDg*@upKxQ&K(mtAk|`HJPz)_1HaAZ&&GHf7 zsz6IO?f{EsSe^=LZJ-DtRGZRNi3)(P24xANDG)6Gj(#dNGOP_9D0K*+?F8HR`Nj#&1(CYoj<+oYNw{1t4Y0L^ri-RBp`1VD6hPVuR0IkNiMUb`EeV02O|F6c zauGd$;Lv5&C{!~b&}Udb7lOKhLPE$D=wt2>b>Q`^nt&r(EH@_=La)06a5Fwnfw+Sp z&{C)%=8X_pC077s0o1}imRwSiS1dcYq8ac~BtElCsZ+`Ul=zAmLOFfPAwvBY@Kn$$ zk{zOiq+$R>LAX{rQ>;#)$VHAb@IJ99w*HlMq6mNtA~I*7`@~Y7+@e^8prDZQ`Pk}@ zSYXq1DD{)3Sw!SFBRAo~AvKngUU3Lg#cu0$<^+@bU0;P_H1st~XDv}F6a(QX9$Rbi YKbh+rFQXz7g8%>k07*qoM6N<$g2q=E^8f$< literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..8ded62fb7b6a27a86f7b532c9a2b5a4ae999d34c GIT binary patch literal 741 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JOTTd6q5Rc^#N8xy%NgI}`eR{7o3SVw~oLF?DlhO#(rS&-V`^Q!s%)gPgzJD$(6 zlPX(2b^RHIj&o60rR$>g!|G>TRxtl*e|^4a{T&6ax|r;1#_KA};b_owfAXfrk8RFR$o&QDy{Vn>#x#sulW#~7Jq)- z)TH!~FS$Xsf0AE4joN$h`JQ|K8Rwjx@86b-rgDVb@NxHUL6S>yvXNP=t#&QB{TPb^Ah ka7@WhN>%X8O-xS>N=;0uEIgTN160J|>FVdQ&MBb@0GkggF#rGn literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..517e9f72d0c8d28a22360ad5d73476c25fd4db33 GIT binary patch literal 661 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JOTu&Fr5Rcj%_$5Ae=jmr`i z3DvOQxBn=~BCIDR#iS^(^w0Zu6&JUPm!vIx7~`u}yzledo5s8M7#uS86ZssvI8sdD z&xg3?2M7HpA7}46mr}+fqP5gidGgVwQ1_}WN$aob&9(OVStj}6Xj_!ShugM~J~IZM zU$@KD($sJ1b4JGMs?Xp43SH*aH+p$-+40a@k*+<>G~DD-|-{tS&vG^x*%GGq=j0Y+3zJN#Vil?OA~@ zukBM`R53;FYi;h*X6Nv`Uq9z3iuI~5j`7&H`BAcUqjcZh^7x-d8^2$_pe40Fq;EPa z%hqE7x*0h;3a++#0KFc4?e_Zv*^k$mEo1DpzWsL9`(v*67M^+IpR-MVa>nHwC6*2c zw&pTkoOQ_aoMO7bofkh1@}JI}ZKA~9;BBq7`S!))DS4@K0yY}FSDK>kZ?)HK*JGG& z7n!~MQ}4z!!HZux9M^8s)pB{g?A$cwGrvCg`RlIwI(LVEXW4OK`|IMz?e(5Emfz@% z$^^!kYKdz^NlIc#s#S7PDv)9@GB7mMH89sTFbpv?wlXxZGBO2ntqcr|?>AgV(U6;; zl9^VCTZ2=RMLtl2B*=!~{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{sKt&9mu6{1- HoD!MOjfK$EgnR$;T z=N`Kp(hSrM@CU%evd=bf=-4w^bQmnuhmUH-jd<6WZ; zHl4_>Rk2U@t}L_t|AiwlQ891B3C|YS1B^O3M@oxo5*z)LB91b?+QOQX_r0yH)YX2= zvK_aW4}ZVF|MIp0)1X?{@CS{e_APBtKk;H~nV$PVB{N8HV+L1tOj6 z``KDz%d4l`HAyHPxAByb%b6xG^S8m<-YfXS7v>b+zlZNGcwheZcvv-P0dQ7=MviH9v^t)=yc559VF`j43j z_pMt2oAX|`goy_Fm~UMa9d%t_^^2qU)cXl;U0e%IRZSM> z>7Ksk_VioOmKv*1mN|c~ELg&~mMikt+LpAdYoES)QG3#uo404uV`0ytJ&!XS^rKz< zU6j9{ob*(;{k73gyQmwdmG2d+82l2_J(5-Z=Epp_^THpe+eb5HIvzUo?fW(va5{7P zd0GD0trC|9zjsRjleub%YeY#(Vo9o1a#1RfVlXl=G}JY)&^0g*F*LI>FtRc>2C}UT z3_|{Y+l-q7HAsSN2+mI{DNig)WpGT%PfAtr%uP&B Z4N6T+sVqF1Y6Dcn;OXk;vd$@?2>?&0tquSH literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..bb19810bc2062509e4e4968099a359ad73818728 GIT binary patch literal 915 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I0wfs{c7_5;rX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfwTh{zxw0jNgl<&3j(^ zeD(x}!be9sh1LD$__>xwFX-mty1-MRJ?GVgBPRYo&#phmts!D?ltV3&FI%+a$=z1Z zV;YHl1iMSDgJ+|>#46F---v^ z=n46F|IdfFb=)S0I4Coo@!g}n4Nex)S*)#RZPN@k9D49tzo1o|L;8h-cSg(aGrNAg7qQ^lmAJNnY2BwD zmg$yB$_Kc(9`bFT@$ln4rdg7D8~IZ-f3I60`0mq%qw5167@Xn!BqR{_Lfuy~aYE2x zQ4_Q6{SU<2c z;lT8&TH+c}l9E`GYL#4+3Zxi}3=9o*4J>pG%tH*#tPG5-jE#Y8D+7a&|KB#FXvob^ z$xN$6(O_z2Y7RsY4Yp<(!9Wd?ARB`7(@M${i&7aJQ}UBi6+Ckj(^G>|6H_V+Po~-c P6)||a`njxgN@xNAiwS~- literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_clear_disabled.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_clear_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..e35c5f05efdaecd358f87fbaae543f8e5d5d0331 GIT binary patch literal 2531 zcmZ`(XH=8f7X2UrgEU7FLQ_zh)KH|OfFK}4%YY;l3BgE$bfgPHm>57oiVlR{r3na1 z5s*k31wv6NLqHIXlu$zN<;7X=&-?MtTKn#O&)WO^xNF@LZ)0W3eOmZ5007+PX2x(P z8~g$U%sc^9vpoQSAh_$-ZE)`H01!%bN1<}R&3~u$N|MPoHg<5@c^XvcH=z=8RBlXS z3@PSUNvJe8kyXUW#9vzZn(}j&b1+rdgO(`5gilr zURLUj7BfA=2?AXY4>LF90D;`OK%iJNc<{fP<(CdNOIBm{nI1lCb59ed2NW9^Wr(r8 z8-61mUr+zyDcHH@-Fn|q#SnumGVnRPq;@GRR-7e$Zl z63G7SSIaZT#y2h-AmUaH<0K3MaJE8vvO-WWlpo3k6@{`w&kE6n1Yn|=&`#Nb`3^*H z6MpS{8uX7dU%;iDlnzP?g_AU0i>SL_JBc1~_r|n+xZ9(VxGWN(b>PDzm86uUoE@Jn z*d*HA;CC-T`CH0&Qm=fMZoGAduW&op37SPLMhst#clZ-dh=S}Sl*KKb;}$%+s9`>7 zc9>vHD9)y-ls~}X7Wh;#b@aMM+CI&Nb|UL#uVDB2kMPRYTO|e~##=9_hFeOBHkMNT zypE?{%PbVr9Tzz0ZJ)29Yss~vvVZ?GYCQF9e6wVnZ6im(LO}*Gf}Epvjk8mmsZP33 zUAk7ewtTZ}Q*X=VCi#f62zodvbYi#Zfc-#fcka~iDJw2V;Z}JXdcM!E6w+)~Sr#{+ zkU@GC@%_AHtrT6FAf;JcW!^>_NO4Ock*;VSpp_zWBcn{-mv)47Q>Bn4mAzAT^A3O6 zEmyczZB=ABp48gbl$Y*#RXRJl9elD{s4iUj(pC|fcoZT-{XJ8Ek1@Q9BYI#dOL<$7 zRvnXHHu?n>TqNt7f_fS;q&~(=E@V)6VjnefQBl)t;!a&y->o$7i4er{Wcx(W;CQ6l z!39x@_U4A!fy&wsc`L^}oe=50rJ9X2B~MqKaH%zV`(mIEb@FY*i{sq&BR<}Z^N;n% zPZTx?ANyi!Hl};qTUHAe(iY|%Tm>KSo?KpC9L^hkm~?Ui0=NNQ^?wdS)R{j++}#Xr z2>{_z01zDu0DC7)UI2g~7y!^w0HBir0D``$uH847URJb)sWEUud`f9&-Z=cskbwZe z$@dE^KxQ`dS2Nhp(1Xba|AM};ivj?)A#-CxJM7dl!pVyt!+(6dNV)Gs{Te)0XjWe6 zZQd##cOza!>Y39JRI0Ng)JZmIAUi`cv9!JSx_;AgLZ7EyYooR zTahf;!@{qv_L6J@KOW&-XNryEyJqR4@~arDq&at2kCY_HPqBd_3m^ z6W44o80 zd#3>_So4<%m=b18pV8hGV8l?a2$^=US5)Dl{e@}<9;@L&YK#;-?60l;d2G-=BmE1+ z`lsBUk&k8LCE%K#YRE)aC?NJcrp(30Rqm*+0lw3y(t${?e}7b==Vmy7JV8?1$8?i} zC970B(cFv{gl@Ji^K8p%fvkdHkTDGLWx1Xlh6IemS(AUeaHt9YN_-99X>k}R#GnSjD z6mp~4qV>Y+>quK>hC=;ek((`aN^32cE4xQx4;>uTcnNj1>Nm69!$CMBr*mYkhGIcn z-#L)CZ2thkxC9gh<_C1(S@X}JVgq~`s2B3lHjFH)MhINO?CjM7aM0;6-J+I}^>D?H zTSja|BR{|7h_)R4*qmzcOG2LI^3^MFi-vs~SlCEZt;kc%QjMsV8JuoNXQ!~8^Yqp%T{J~z9iRV@_1)_fL@#~gP%vH zxOCgH9WK05fMJ7bW|TeXQmU=jKd*xky@ z%E<}ebd?jW7w>2Hy$ae8d&)D^SeO1H^hfN{YSzyfH5slUJ;Ggx!ghqO!;S$_9`Jr5 z@lBz7Y~!YuK<-%Su?g!&r66yZQ;W}h0Qlp=x3SMXo(auQ>YvneIbRr#Ke|HZdp8Cd zq}ijL_TO6dxJ3rNevR9HE!J?aTpsL{=D(o155rNCq>)Og7*xSDZ*SXp0goxryOQK4HXpc!Ex?()L;Z?73vmql`ZFY7olc_Qvw6+AKsBI-+Kk=H#6^OJnb7=HrmdnVB zpTYRkxm<jpD>fgSzn<}E~!UN}tlGV3AoQU#eK}|lW9R2Jw z3$u#IF3F!wW>*T9mJ~<9Z!6{vRyo1Pj)|XV$JaRf!vz4Vl*S`nM3Mz;baDGr>~Z$U z2@R`3dzU8S8KRv}A@03+{KK|Bmkp(ObP?g^@K*E*hIV7FzSoZSN#U&swSokxVtZN6 zyB=Y6Vf#|26IK@dAy(gGYB2peVjegBbev1&L*SYGJfV%ipCoi4vc{H^ILvML{V9E- zJH=CK9cy$k&juE^e3{rLcqky98BEtD8s6#d^vMrN|BY;X1$Xwx6Z|IR=DH&ZYdVLp zHLB+d*7-BBAwjx!x6$J`Fl|ZZ9J0x&>rm>VO0~czTK?KoFQ@-**7mNvh>0>9PHu~r zx#Xqpn;`Dral4PvaSy;S2~dTps3^iT6jinDR5W#9sygawiZG^t{qVgt@;?D@-#fUw WVgEmns=9(>1^{ytE8}V-6#hTCp0D=+ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_clear_search_api_disabled_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_clear_search_api_disabled_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd7aeb2a63980f5c7459b96ae175b875f27add3 GIT binary patch literal 1315 zcmeAS@N?(olHy`uVBq!ia0vp^+91rq0wlddc6tLTrX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez1K-K5QyCaov^`xMLp+YZo#ve{ohs5cKmXZmZ>G$w-JO@O z_$Dncy|l#DX=;KaYmSzf&V&g+I5)gx(wb5qs1h)7!mfsR25uDCBNMaEYi!b%Lx%#0Z>6%}_Ke;bM=$-hufo^&&725YD$vGBuUKV?<1 zW5r*8XXtLO5$#WZeo|;mb85TEyq_Keb3$U;>HYFK{YX}hy1N)ld|`iZ8c+f zaW}0jS<%V*aZgCBwd%4 z`mTTDHix9d^392b?Js?F`)aOklAwYhQ$?F@yb$ytH>J_Jb{Z~vrG;$w0s zy7gpFZTnjBVEMK z?u*UK{&)=cU7rs=ddas!yNA5%MN;fAeO3GpiZ3y(^OR`LtKE&RYG` z%T6M0Q((r64h>88-;=&fKXORn&)Y9<7j0ADM4op#Evb9DEVE3OxuAOMwTp8T79Bpj z^46Bw7ia(6t$e=h^6Gq+^)tU-Y>!_fu&_#YcJ0QCjvJ3m`|4emd(8LrvxuLIduy^w zKRn;Ob&-9_RrP6hYo5j|+EK9n+eN__H(s3nbj~C7+}RUuX{m{weGosZ*S#`Yezasg(E; z?-{fhY+_DS&eu;5`_fikR9#fupz-tEU2!F+6F=1F&8oh6DP7e>i}j<0lm5=$VtqvCS7PaJ&waLQ0xVeA<2r9FV_>h2sIGsVSbJsf1ID=TJ5=|I z&X8~@c`+{`NhyHi(Rj}}j=t-itc?USbMMp?m=EB?(?e-29Zxv`X9>CKeyCDB6UQN6rr@v)_sLiS3~Qp ztEzq2)O|!<>xiRNElR1gi&m6P`)xn$hne5Zy#N2rd-GvpEU{+CMPx+)0Kjn+5^l}o zg&!d#$jfNkdNdFGu4pqj;P63GZxgQ*_CY#Oc|`sUQ?}=CKZgE3#v~qpdI6&Bx^w_Q zunGk?wncWWW;l7-UI#@tQM0)~HL81;)HPu;pVQ0pgJQPrfpMpp=aU0}M<~a{2nw%n zU`-fLR8Od%K$J#9U{=UTI40i8@}fD@+Oa6N|E1RI6sbQ)pL!RfOePt0E*?-w>vc`F zFLoR~H8O{D0Fhbf&d=`-+1DWWi~EgA3{w%CBurf@x&z#)AS%CTjBJ;NXfEz(-q*!r&D zRZs9Vt%N#~h`fZ2dF&WAUxzdNEE zLcQ7z)<&U)d{TxG*7ZfZU%dui_e8AOG#Zu1*(e!@&OEmtgjVAmsh>Px!}hna+U*4u z-(P@*kBOd~_&ckM8!+$m47a*D-IZ(wJ}aDF{e;O>YW!u636JA2%GNI#9Kc(nk+Ttf zZ5oR_VO!WXDMZ#m`6;XjkCv`_D6eahzuUOoqFaafSiYTac<;TmC>LuaHD30rCoEXh zD5R1Oih#JsO2+Mq%9NFu7{5RCprvtcFS~~}?Jc*n#%9=R+B~=%4@*03!EPJP0MrnJ8N%7FfRW&1jKLlO`E6 z2Nzeo&ri0;XG#nsf-QzGDH@1K!SO+oQz;nwgfHIg%HhTbyKTOO$NB{~co(lFCB3>E zA&~-M`}RVuy48f;Y-C?8l|c;|{QHGA&~=s7pAt2h>u zaS=yuntEie>)yAC_-npL!3zTFzOgLKZ}$=3sW+~_Ul7!!J>-L1jXDCh?L;zNtpzrIp_ZRL}JEMXYA5@jiafE19#aIkmj zpOVnI=5TB*VZwzSHn(G2*x&nZOKW`I9?Av!cNOvbi#$Fwg7v#&)Ar=Xmc9st_ZL_3 z{@58B!k$KOp%D%6encJsnot-_4XUH2sc#F@HGpawXltoKc?EQiVmJC91DQf_cccHm zAysqDoo4|5*kD6(qXoG55dp>oiYrkGMRp+(t%)uKx-Xk($P)oj2rRtP1Q-4<4m6z) literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_go.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_go.png new file mode 100644 index 0000000000000000000000000000000000000000..1e2dcfa02057f16f9f89e31fada93991c4eb9ab6 GIT binary patch literal 1983 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a92fb1d4af622cfad770d7c494121719a7896e61 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=d7dtgAr-gYUQ-leFyLX@@b&p` z%gbN)&SLHDYV<0q^J4_6fq?|&@*V6j4#NRakTDF}Z~@#RP$drMna{J{ZM0wU(H|t@ M>FVdQ&MBb@0L8N*<^TWy literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..930ca8d95e8bee5a1240fba645d9dab919abd734 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=^`0({Ar-gYUf;;epuoZ6aJO@& z%&D0-IKvGL&8p&qV;O7KuliPO1yl(K>(rHwor_8Hg9|Y9Gj8!^hz0Vk4~QZ}ABcvv nF)(akj$uTI?LshtEWgbR4Rf6*RPme*0Ev6L`njxgN@xNAEX^ml literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..45a0f1da0d01b7c0ba53830285c67d629bd0774a GIT binary patch literal 699 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU~2MoaSW-r^>)^McjrWjeSoS8SCOEBs|%|?VJ7D=T9Yz_dLJ8 zJ9zK=&-=vhubx}{vF6<8-!m`2Et8%6G=f2_fi-~)r;kY>>MAgRkm@i7CT&PKJ^T(I*&Av>d6O5U0r~;hkX|;LrY6t%e!5sze0;lgN zzhmA1v9d1mdTWRDgJXqP4j5dhQr@DSSRpJN-*(9Bjp4$N@%tt%vt{r<#9TCmVT&q5 zPY_dpf5x8W&TrHi1EzgwuzL61gP~v}`*h7_ev9YX^%66WzmeOz)Rwd1sPzfWyZX+; ziqW^(w(Z~haJj|{8OsISSA~|G@%CQ8Y_d#7=yl$KAFm&t%#H|W$kcQ2;yBguIO76W zkG?He)AQ@KipLqRU6Nb%FPk$;xS@jW=|$x{C80dl?QT)`*~FQi^@N=fie6YGbN2D| z=`W4NG-chmgqp9bsxquQQuyVroI59@gwb7QnV5NMi~&p85J-Uv+l!N+#T%5W;<7yr4}f9Ow$JGA?da_{7}kE@t}@ET5LG{B2CIDTQC8`Twj U_qmZcFi|piy85}Sb4q9e0Mf@O?f?J) literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..528e554abe239137182dd9069d1fa4ba02a109a1 GIT binary patch literal 935 zcmV;Y16cftP)=+L@6RIMT%_@p^A^X5UDRjLANf13Pq%);A`Pd+=!;23pXx; zAif`nPef)@LW&ftmV!!=U?`shr5Kn0)zPywg_Q~)Xf6@UsrA5Be7{a=6EByPs``206cpncnr4<@!q@mA~gUzaA3%HTX+%kDFHYT5Qf!vm`Me|1djAs_x*GR z&!z%kGhWI$<|3X<1;9qUl5@-=4yFR&S{y_@$C%@oE<1op+>aXzjC~!)$_ii$_F+%K z@y9V;#ya3q+!Mu4ce-D|$M^yJarJ;X=I|E&DieT9a7UE58@rw_;mfG%mg3n4+>X7G zDINV8W$>{wd4UPs8tHyn<_K%Vx4t-F{HB0#CbHyT8aIH=*w&T4zhI%?@Yvw4$UHw9 zfiH|AwZ;Wt3m(R<9MXfe~y?7+&yyx)=z7N}~%m5B!YmPaWaH#7@Q+5E; zIqP##(=Vn1;7AlEd2}e2K@tF-TcIq?su`V~Rw@AYX?JP!=ya5wR`qE`V>4fQR+^F$GWKC7sT4IxUFgD9>&BxJs0#D$E0dq8B&$(De03B_O{zBGgT!>|}k{a55 z!O~xj?u?9>EHL(EoJ!?lWDg$AX}pf&%~Sx?@v3~6qvvqAx*Saezy`dwo-+WR!8JMF zpTip|0k{c|kLwhu)oQ!f;y+34?@=W6(zkfKXdO_i)poDN4CtH&58$o=8{em4rdmY+ zbb?>20J>f0o#8w;#fEn(4AdV*y+C*HYaPJI-C#EObp@bT@IwJeLH&YX7XStYpFDt- zf=?R2Fu^AaVA$Z31du2AoO(cqH+@Lz(5e*i5O+3-*HCUO7(002ov JPDHLkV1h8vxv&5L literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_search.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..998f91be9c4dff50a3ac354a3810a2afe39fe32b GIT binary patch literal 3784 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 Z$DPpsU&xgE;c;3340Mc9_1aGO{{Rgi%2xmY literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_search_api_holo_light.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__ic_search_api_holo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..a4cdf1c7927896d70e6b9f6af2eaa64b1bb41707 GIT binary patch literal 3037 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 S!l#~*4goMWSah`&G3sAAl9aOm literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_activated_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_activated_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..eda10e6123e1e1383c4617228ec0c96680d60dc7 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn1!PZ!4!jfu$#Gb-B{xqtMx1s*(O%+nLV7IxRdaaX6Iu&3070|zpW ye6d-ZyJWwc+pgOl@x443T>9p%`1p8cx&%YrImy|zOvgZGF?hQAxvX30u5yFboFyt=akR{ E00Z(eO#lD@ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_longpressed_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_longpressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..eda10e6123e1e1383c4617228ec0c96680d60dc7 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn1!PZ!4!jfu$#Gb-B{xqtMx1s*(O%+nLV7IxRdaaX6Iu&3070|zpW ye6d-ZyJWwc+pgOl@x443T>9p%`1p8cx&%YrImy|zOvgZGF?hQAxvX literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e4b33935a3aa4f1af3fa9e9e199b5c47d43f4b74 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn2vPZ!4!jfu$y_kK-b literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..88726b69160589c8545759440e8d4e69dc984c67 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^azGr$!3HF6SgS1tQk(@Ik;M!Q+?^oIXnykaTA*No zr;B4qM&sKXhJ1$tcw7#es=J@sd2yMiyW@jyg@u(=2qh%>1r1WJE1Ls*cJ{|veUO|(2?8OR-p?Vt(<)KXNk*dJ1<_`!jRpab6RMK;Rk47fDU#NEX#7yk4(~&Fr}L7DZp)K} zK)DDZgb+dqA%qY@2q7)3S*px^wsY!a9l?~jW2$HoDfOAoDc4?$q=mJH$Q@HesW|pH zEqI5t5pt#=^`ykNb$bDA+g_!6r>E#0Ebxb)V~E)@66{HSu%o+0#^7QK=<56_<*0g z4?VWXMFRkJB8s~XX6q}?LEeWW=Ef--P!X+fp` zQ#hbt=1@CWv@?Vrj0n$wG-wfB>s2&!$QdDJ0ulZgw-cuRiR{Y>^Hj3K6cvDZyr8vA z8lxp5*y$r9!v6G_XAF7`2PhmT)XW;J_(x39;8bKfgMu`e! zU+jWXwIOOF0-q>8C*JQsY~7_bBCuA z|Ap1-2&vJi9g(t&*dI@qVtrbEm_q)8uxlUymW^N&DQrSTF2REQdw9B(B*Fk-L?96w zfdFVX0=tCgq*<4>5rKwy4p!?>V+1b~mqyqhPm^M8N}pNlWK7Aa(;L|rtB1{dT%;u; z=)dm(?jeLfE6zhUB!2hW01y9MdY)1v=ujhBx3b+Xm&>Pd9KV)clx)K|j$bdA%O^}( zPFj=H`w_B~E-2}`eIdjBd_I2}hT(GvVW{|jkQIawhG7^!pU>wnc#H_%SRreOrJP6k z#f!~#`~_1^!^gPqw^)9R`+vop3DslHn(o!PiI0dTt@|45Za=)m1`%IwEW{fV$LVaF zE9RVsAMaWMjZlg;f(R_4iy{7r`=s=`3SdP<&^M)TPHqgUw5?z25;3$902*NlyMU*S zpa+j$RH$BIEX`7~H`b|A%pl=Pj|o!QHv-L&MvImjnCmfv9y@5Gq|A_|G$L4MNvqdg zg%(@J38}FG4N!(%uhEggMhM*%9HY#I^l zO-Wr$p$z~$ref=30GgqO)XJdORd}!BEq>NeB8p9{v^kJo2|NxCQwf^HCpGf6X;Wp4 zg!hgmb$FtdtQ>ASMriqL^@|$FBEhNWjw@zMktp~+Gzo9nO1w>OhBUKE#}ER(1L)vD UI+1b(O8@`>07*qoM6N<$f~tseq5uE@ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..93066c8403ddaac9b19571152ef499620bcc0e02 GIT binary patch literal 1551 zcmV+q2JrcbP)ZMyJc+a5x+ehm5NR9U3;9%`Hyz-(tJnPJWK72_ZxFO$7HJ!wl=MA(TM` z5z;&LLlB#EA&f^$3`&>pe6X)LdJ&`vfROKm-xd+jMbSqLMZ|438|}{L$EEgM9M^%w zHa{i`W4qmEM~t#0eOdu-0W1NOh@<%YUknyuBI#0I?3#!O*zRI&T@|+kOaOda%IhNv zM;99T5trXGZJ+ZJPec%b)$c$hhFbzf1btKUoQ@WxJHBtqt%Djjh@==IkkXLZmr_R= zETUs(|D2YHL30h7B}jQ1@s(0WN*y++$>%9Px0_7;Q^61da}ymGVa5oGC6I`(Se|An zXj@SBzbdSFK)Um(Fw#d8Mr2~>phE(63xW_TA*G~C`G7107k~`S4FDISDe;mJcscGO zI_^QW2+SjBmZ1U=9v>gytZ(L+77q^(-%!w_2qCD0PZix`L1IaO$h(b>d0@F@G3Eaa zi55W^GL}q#AgNiNjxa=>FZdR(r+ zxE>NCSff^sd0^fBMHn)m#E-cU=7+{dF-K!9f{S1|kOWYSoDj6e26s~&lfViRc^MJj z^>Y9iF9eSfmVwbcxJ7UPa3MH8F;)otZ%)TN7|p{_AvpQV#UO5SLMWM?>!O$+C0vaD z8(N!X1GsBg3ar^sKmkXku0dO*!9}nfXnYiL)Hg=pYKs73(^zvc9aG}t;{#B5>C;Y2 z2$?l`wfXukgc)%>9s%7AsDyH^rRNDOAHyeHMgYzG`@1jfJOi4h!RzZQK)65|cOA0& z28%R3H(uBEzOL&YU%_z=>~=fscDp^gsmfTk*1@j+TejVzGC zpG{n`bp4r^(iKT*Io^&x%OHc_WZd_EkhCG`k)*sFZ|A&V23>!#)HToxrIRJ-1q1Q~ z3qHxB_z~+bgihSWK3otqlC9O%9BoMC(eAot5j0oOB3|pwbjUE4*ONZd@_Kxq z*B8(0XhE_FfV`ZZwcn~gXn8&5;sQ&h03_lPHzc@QD2L`A0DB!p$qE$r97Hn6cmgfM z$;^GEI@&qEx+o;VEJ0ZAK#dKOL6F|xU|IwgE6|`&x_D{{k^myy5)6fQcS{yR>LIlD zb0eL(UISu`k;Dp-=L_3_9uII4xG36?ZZ5uUxd1Up2yq&z=dNHjN&oIh<{D_CLJUbUG4w?002ovPDHLkV1n`$ Bwt@fv literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..345f5d3067c1b5a2b13f7234238468e8083e75e8 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*8<0#p>+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTMQc)B=-SoFS~;>gutz{8S$H2ll||1$b2>+ab^8r zChoU9-sVBr1cr+EHAcpdxgPN?*fw!WN@w!F_di=AUe22-xp-2_jNr43yl#?i1$i|o QK(iS+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTPFdAc};SoFS~;>gutz{8S$^!?BO&wHlFT~V_1=)TZ8!I{mdT_A)Z zztl5%UbEjFE&+!7%~#Kq{9)d)y{;#I@4EEH*bSem)2!T7Pp)1*OL*gdvC7^*b6)~Y OX7F_Nb6Mw<&;$Uil{z^9 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c3f1ec248835c16ee8a8f9d253769ea4196468 GIT binary patch literal 1309 zcmV+&1>*XNP)>2T29Hys?P&Vm zZA9*OOSNlf`Pu!y*8AUEO|D+e=9Pi3BR)agfw#}SukU>S5_JQH{fFX7qt#y26-7>F z^lg#%AL~){ay($Vl%dNK|ns=8F95J5u4IuT)_iO}FO5AO!x2YA-ev{((MiCMb95Z27y1N{d~<$0ZOiAzT-4$^Y~d8=D&GctVLiOE-HZCX=>916 zaB}eD93BUF6!cN|FY@&i`W7!}IIL?H*U-;b(9ZeC>T4fo-D~%;%Al$SM;o1{CK^c@ zLsL?U%;F5uW`mKV6p@jG8Wm~81rvcAg~E0r38^#=q@={j6{7*N{-mRal zZyi757l1u@+(UUVUpKQfbx4*^AEZ`NBGTk&djR!;W=;+8vR!2ZvkZUiF_Uw;@^@UHY_tFNo|bZ|HqK}~Z_0kB z>1@!nFOf~^{KOi&lvG5Os4i`3m5LaZ>S{(}C2cS_3u25qx+GSC0x^F*mC<6C%zjX} z`(@Gi@=yT|C0D;bu>bAn+W30Hh5ZfH4VVpRc=$wP71`a_ciV~TTQkNXRQHQat7toU zZx*3Z?Q~QYQO|ZUR_Tl#qXtzIiPWWo(#}&aV(i6KuEST$lYVRUVscgaEz?@VCh+@z zYdAdahv=OS&fP(?9$16?`l0%F3gfnP`B71?hw4@2e4pjZouU=>X|R*`N-YD-DJj}uU$#5 zV>X}RzD~bXHhFf?KK=4JTCWrMiS*`U`G2n9l*Y@cp7B$uQwuKJNIF$*XNP)>2T29Hys?P&Vm zZA9*OOSNlf`Pu!y*8AUEO|D+e=9Pi3BR)agfw#}SukU>S5_JQH{fFX7qt#y26-7>F z^lg#%AL~){ay($Vl%dNK|ns=8F95J5u4IuT)_iO}FO5AO!x2YA-ev{((MiCMb95Z27y1N{d~<$0ZOiAzT-4$^Y~d8=D&GctVLiOE-HZCX=>916 zaB}eD93BUF6!cN|FY@&i`W7!}IIL?H*U-;b(9ZeC>T4fo-D~%;%Al$SM;o1{CK^c@ zLsL?U%;F5uW`mKV6p@jG8Wm~81rvcAg~E0r38^#=q@={j6{7*N{-mRal zZyi757l1u@+(UUVUpKQfbx4*^AEZ`NBGTk&djR!;W=;+8vR!2ZvkZUiF_Uw;@^@UHY_tFNo|bZ|HqK}~Z_0kB z>1@!nFOf~^{KOi&lvG5Os4i`3m5LaZ>S{(}C2cS_3u25qx+GSC0x^F*mC<6C%zjX} z`(@Gi@=yT|C0D;bu>bAn+W30Hh5ZfH4VVpRc=$wP71`a_ciV~TTQkNXRQHQat7toU zZx*3Z?Q~QYQO|ZUR_Tl#qXtzIiPWWo(#}&aV(i6KuEST$lYVRUVscgaEz?@VCh+@z zYdAdahv=OS&fP(?9$16?`l0%F3gfnP`B71?hw4@2e4pjZouU=>X|R*`N-YD-DJj}uU$#5 zV>X}RzD~bXHhFf?KK=4JTCWrMiS*`U`G2n9l*Y@cp7B$uQwuKJNIF$+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTN5dAc};So9|U`2XLYnVI=;y-5$#f-D2o4GsT&Tr`prfMCHsr=)`p zy9zZlQWAk&gL|Kjh|gcN+0MxMkn!S`=@A+#%ic(Om>d23|9^ht#EF9It^fc3f1ZP3 Y!dJ=4-o~HPfwnMsy85}Sb4q9e06h#o+yDRo literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..205b66e2cdef686c5ed6369b14e64b38d0182984 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*8<0#p>+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTN5dAc};So9|U`2XLYnVI=;y-5$#f-D2o4GsT&Tr`prfMCHsr=)`p zy9zZlQWAk&gL|Kjh|gcN+0MxMkn!S`=@A+#%ic(Om>d23|9^ht#EF9It^fc3f1ZP3 Y!dJ=4-o~HPfwnMsy85}Sb4q9e06h#o+yDRo literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_48_inner_holo.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_48_inner_holo.png new file mode 100644 index 0000000000000000000000000000000000000000..19517c4b0aee1010c7041a76089fdfdbfa495e80 GIT binary patch literal 2769 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d8929fcd1864e92c78f24d34bb07ac0304bf5ebe GIT binary patch literal 395 zcmV;60d)R}P)%)khMb;v@5Yo)-?A$vWI3J{&4Tqm)VM&;#i3-!rXQ;}}A|kSK_xLoQ9!D=| zrQuRX_jo!D&!*woG(4MzXVdU(8lG)+!_Dl;%pOYTRyEwrUVwMtwRCnh!_9059DxJy zTsprAUsT~zdJlX8e>K+(FMd_}2<&RF8#?@^bn(8vHtbfpl-_eLJ!>=!D!!z&OE12( zv`a1CqqIva-mA1rDc-ZR3oqWgvUXO(tc zif5K~i;HKMc8iLSDD9eyk1Fk&iksP%L8V=5@ekmQ^NVfO%k2z5z^Qbob@&(X-FR)u p3HS~A?&0(Ut%!)oJooy?_kZokYAURbJh}h?002ovPDHLkV1n7-uz&yn literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..9174c4e4bc984a89e1ed643bc66b1569466ef52b GIT binary patch literal 394 zcmV;50d@X~P)pS_@$ zhD#gW|+S$zvH?tjZ06u}I z+WCj@MGelS_rM46*K*DD;uob4z^?VWsl%^ISMTdf({7b>={={?i$=qw;%iE~^x|tv zyVT+%O1re;qe{D!;v-AD@ZzIOyU^khrCnI@sM0Q^cw}ieym)kJH?(+0X*aBRR%th+ zcxGw0x_EYJx2pJz(yqJstkSNlxS72&skG}Y{tg(Y7u%+n+Xa4rW9?Ay@Gs!I^V*st o@Ei2q)9D9V5fPDPZuO7v|4Ms3SH1lZVgLXD07*qoM6N<$f(F>P&Hw-a literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3015d307088f12d52a9e99ff4575fd2153127e5b GIT binary patch literal 381 zcmV-@0fPRCP)hG*08Y#N?T!?S64w!;lKvy+*1?>p3RGdlx#190x$dzj&7b^-9QUftoB@I?dG z(l;!l|3;oEFaA*ajtwD8hd-6>9*;+5M`bO2!%}+FXrQS0p3;u)|QJUO}XO$+G;+dssck%4fw5xbU zX__uxRhp)XSC*#P;_m>iSbo@k`^^CW{9xcU{p|2h0AG{O_A~&$L7!btFK9(XM7DX= bKfeD1Etg?&Fp}qT00000NkvXXu0mjfW#pxI literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..126637d1194f1d6609787774fb140818eaa4ba1f GIT binary patch literal 381 zcmV-@0fPRCP)hG*08Y#N?T!?S64w!;lKvy+*1?>p3RGdlx#190x$dzj&7b^-9QUftoB@I?dG z(l;!l|3;oEFaA*ajtwD8hd-6>9*;+5M`bO2!%}+FXrQS0p3;u)|QJUO}XO$+G;+dssck%4fw5xbU zX__uxRhp)XSC*#P;_m>iSbo@k`^^CW{9xcU{p|2h0AG{O_A~&$L7!btFK9(XM7DX= bKfeD1iaRu(IeFS@00000NkvXXu0mjfR7Ip< literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d45c7a864d9b36fc5d06ef7650bd22c228e3533e GIT binary patch literal 680 zcmV;Z0$2TsP)JMg@Fn128fNR{httc z2n-9ae~A~-WYQOAyjJ3`v+tFS>H?h>cjZI44!YCDJ4vU-UH-NFC!H?dNqTY9^x~%J z#ZA+To2C~xO)qX5=ft;__PrJUYC9#q>!rbyQFMFHPb=3hoe|&n)9~p|baWUbMthlMtLL6k^E5&wx9H zfkWKo4DxGy27JSv%4KLW#~I|sPnXY+fCHfNj(}ks%-+uyBgtHbMG(R)| O00009q_DOpcx|jv*P1Z)f>u3p>g<+)ulGcHZsoOUd0`v$ideb3Xs*rv6J! zg}R0?Ejbavstni13%M+(h~#=Y?=G{+sY|c-R?LyC;M~J_EGz53I-4BR z+cU4@A4T%4{LQ{7{nooe_R?;9Ufq56+wp;!Z_W|LdHU^V zuiix!E)rt*mg%eid+||lw)K3kxzR2XQeoHKTo0e>Tz_Z7KF;I+KDl^G6{a%9AKj}v z@Aq1v55LRoZXbD)<16^lF!*Li$^7}+)mu{zFEMCaSs}k;w&aatvA+!FKCV6>P_Fen z(L?roLe!sxPkWei7+T9&rtD<0W7^%ZdcE}hdZyQpKhHVIBAEwFVGN$GelF{r5}E)^ Cjyh@p literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..2cb34d7f60401a563454c03e266cc5181d9de996 GIT binary patch literal 609 zcmV-n0-pVeP)%5ec8;(Nh#y0Zthco9&fD+Scz(J_kqCSd>@N)Jrb#iJx@ z@geV)|0U|;Q8J4AW)%0$DDIn4+&81RZ$@$73{E^#CTa6Odr;zqGLyGk)zfLB)26Y5 z5#LU9dOW?JALQjc$4r{WH?GVFg))<)qMW_Ts@W~*Hgkd(m(u%LwVNxGwVfAK{BG$~ zHD4Zg33jP$CptYU%GrKa?RJ%hK*cvHEqE`!X=%Z0aT}!tZ^dnu7Q7Uk{&1!u)wl@^>7cUfAnUfgwQ!D?|Ir3GuneU%oh6!%$L*todw(!xf?LzEVJ7Y|ih z=v92GOd6`R(5v{nqI~u|T|T)5eQi`_Q>fI*QllCl)AthpQf>YCTIE0c%xyxW%x|6C zG>z*e{-?!>T@(EFL|;a6&!||%qb(l4cp2298zt1@mjOk(atXEgIq-{NzY%9xIi5qk vb6%{!-vcjz*7vDBaRYn@J|M2KzWDwRiVUw(_ikNA00000NkvXXu0mjfOP&sp literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..82f752fdc28390f1dae188e66886f9fee783b4f7 GIT binary patch literal 602 zcmV-g0;TXoV&|>P?2N3a|H=XkIpb%g2C{mUcD8z%K5!WW71`A3B@}P?c zNzmeTUM-&`=;A@rh-=e`Ytx8p(}-)+h-=e`Yg0e*Nfwct-zMuNo?gfN+FNCOm6(Rs zNBrh8;rK_F^Mfu~8k>e2?@WdCI_7lHVR+IZj_>A~;=j0*zBpPVOJB@8&9C^w(v!^i zcs#`4qjGbZa60I4akN%e8hjOBptPW0e8JL!ZgC5x1-;^yN((y0EtVGC7q?tma9i9# zX~A7_N2LWf#T}Lw>=$=jTCiJOp|oJHxKe4sPI1N3!s5l1OACt?_fT4>Uffe@p<40r zRpP6(P_6jSy?2bx-x9}n#O>6o(Q^BiC^BxWR1^RB?JvEr|0>Nj5k)!eSD9&8HSzXK z2sbij-vth4?P;pL%~0mos(Tg<|DAn;kcS obzts&Y9%t@53qx{hWg?AJqc6disFjI`v3p{07*qoM6N<$f`4nJ zaCd?*qxs3xYk`8Mo-U3d5>t~6?){q5*x2~c-pCBZ5@_=ERFyG literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_selected_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_selected_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e4229f26b2771d884934b80d0056b8dd66d10edd GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol;0U|59*B=E^EX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`8+o-U3d5>t~6?){q5*x2~c-l(n1@K5>ymj5$1a2Oc?!34d7Ck`Aq skg(^gW|wXH-lZoEvTk@AJm}J3sQWAGentL}KF}BjPgg&ebxsLQ0KFYBT>t<8 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e862cb12154541c150fb2d9bb98872bcff506317 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol;0U|59*B=E^EX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`8Mo-U3d5>t~6?){q5*x2~c-pCBZ5m8aUV+M1MLNsm8aUV+8udAXlQhooEaFu)>JVsC;_i|1;&qn1z`CMwWxmD@8>XG@5j{z4 Z4Ch(42+t_Fa};PGgQu&X%Q~loCICWDCD8x? literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_default_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_default_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..98f4871bb52aa7c60414b62dc102a63025d14b86 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq+C2*978nDC;#~W-=0~Khvol7 z1H)I2CW)>m8aUVm(v1b%el;0fY!m7fYzsPhAkg_?o6!P}0Ord_0t$qVOiDg+P{Wat YL8LkPQkkjERiJqcp00i_>zopr0H|OnC;$Ke literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_default_holo_light.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_default_holo_light.9.png new file mode 100644 index 0000000000000000000000000000000000000000..733373ed38d92906a3f639124b60d39cfe3ea469 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq})7R978nDC;#~W-=0~Khvol7 z1H)I2CW)>m8aUVm(v20J8xM$gbsA4Oq2MIp#mnr@>uNTIF}6W!#;>-fvxg@opE#)D b$jGop@Lc3+&hjll6B#^R{an^LB{Ts5lN~2O literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_dark.9.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0c6bb036dbff7c452df0032fac9daaaf3ed36cff GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq})AS978nDC;#~W-=0~Khvol7 z1H)I2CW)>m8aUVm(v9t$CDZ2p!k(eA~|x?WSsfj bIFlKwHfSC=yJ^W9ppguou6{1-oD!Mm8aUVm(v9t$CDZ2p!k(eA~|x?WSsfj bIFlKwHfSC=yJ^W9ppguou6{1-oD!Mm8aUV)4xTaopEyItdE!^$Tn)$h3#7aBEDrH5l{lPKbU~WStl#0CqS)dY aj0`i|)DAxoJGT#LAcLo?pUXO@geCyp{V3}I literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_dark.xml new file mode 100644 index 0000000000..85c2c02129 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_dark.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_light.xml new file mode 100644 index 0000000000..85c2c02129 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__activated_background_holo_light.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_dark.xml new file mode 100644 index 0000000000..cab896283c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_dark.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_light.xml new file mode 100644 index 0000000000..42ba8a0df0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__btn_cab_done_holo_light.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear.xml new file mode 100644 index 0000000000..a16f4b22e8 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear_holo_light.xml new file mode 100644 index 0000000000..256de80fb3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_clear_holo_light.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml new file mode 100644 index 0000000000..2588a492db --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml new file mode 100644 index 0000000000..e2078c9679 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_dark.xml new file mode 100644 index 0000000000..d99b7a426b --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_dark.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_light.xml new file mode 100644 index 0000000000..da5fb2e86e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__item_background_holo_light.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_dark.xml new file mode 100644 index 0000000000..b2ce4f0f77 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_dark.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_light.xml new file mode 100644 index 0000000000..d7e31b1d1f --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_background_transition_holo_light.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_dark.xml new file mode 100644 index 0000000000..08b8b12f37 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_dark.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_light.xml new file mode 100644 index 0000000000..ada490bf9f --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__list_selector_holo_light.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_dark.xml new file mode 100644 index 0000000000..bd19140abf --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_dark.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_light.xml new file mode 100644 index 0000000000..321f07c8b2 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_horizontal_holo_light.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_medium_holo.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_medium_holo.xml new file mode 100644 index 0000000000..6d4814f862 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__progress_medium_holo.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_dark.xml new file mode 100644 index 0000000000..26284187a7 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_dark.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_light.xml new file mode 100644 index 0000000000..0d00c58788 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__search_dropdown_light.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_dark.xml new file mode 100644 index 0000000000..4af5e22a90 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_dark.xml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_light.xml new file mode 100644 index 0000000000..b785084782 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__spinner_ab_holo_light.xml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__tab_indicator_ab_holo.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__tab_indicator_ab_holo.xml new file mode 100644 index 0000000000..d34e208117 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__tab_indicator_ab_holo.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_dark.xml new file mode 100644 index 0000000000..b6d58c040a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_dark.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_light.xml new file mode 100644 index 0000000000..3d6acf8085 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_holo_light.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_dark.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_dark.xml new file mode 100644 index 0000000000..05ff4eda55 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_dark.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_light.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_light.xml new file mode 100644 index 0000000000..f6d61e57ab --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/drawable/abs__textfield_searchview_right_holo_light.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-large/abs__action_mode_close_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-large/abs__action_mode_close_item.xml new file mode 100644 index 0000000000..8811dad8d6 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-large/abs__action_mode_close_item.xml @@ -0,0 +1,40 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_dropdown_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_dropdown_item.xml new file mode 100644 index 0000000000..6c183c0596 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_dropdown_item.xml @@ -0,0 +1,26 @@ + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_item.xml new file mode 100644 index 0000000000..61dc02527f --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-v14/sherlock_spinner_item.xml @@ -0,0 +1,26 @@ + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar.xml new file mode 100644 index 0000000000..040df44abb --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar_overlay.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar_overlay.xml new file mode 100644 index 0000000000..c64ef141b3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout-xlarge/abs__screen_action_bar_overlay.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_home.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_home.xml new file mode 100644 index 0000000000..5c1e9ec4b3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_home.xml @@ -0,0 +1,38 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab.xml new file mode 100644 index 0000000000..f46f7a044b --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab_bar_view.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab_bar_view.xml new file mode 100644 index 0000000000..0d51220c90 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_tab_bar_view.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_title_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_title_item.xml new file mode 100644 index 0000000000..dd69acadaa --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_bar_title_item.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_item_layout.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_item_layout.xml new file mode 100644 index 0000000000..13149fd630 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_item_layout.xml @@ -0,0 +1,56 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_layout.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_layout.xml new file mode 100644 index 0000000000..a6f8e53f8a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_menu_layout.xml @@ -0,0 +1,23 @@ + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_bar.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_bar.xml new file mode 100644 index 0000000000..7168dc77fd --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_bar.xml @@ -0,0 +1,24 @@ + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_close_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_close_item.xml new file mode 100644 index 0000000000..875ec3e1b0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__action_mode_close_item.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view.xml new file mode 100644 index 0000000000..6a0ac9ece0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view_list_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view_list_item.xml new file mode 100644 index 0000000000..b430032a14 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__activity_chooser_view_list_item.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__dialog_title_holo.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__dialog_title_holo.xml new file mode 100644 index 0000000000..ab2b0ee6ce --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__dialog_title_holo.xml @@ -0,0 +1,46 @@ + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_checkbox.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_checkbox.xml new file mode 100644 index 0000000000..39aca3a8dd --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_checkbox.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_icon.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_icon.xml new file mode 100644 index 0000000000..55ab28a24d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_icon.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_layout.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_layout.xml new file mode 100644 index 0000000000..147f36fe85 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_layout.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_radio.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_radio.xml new file mode 100644 index 0000000000..ff54bbecd1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__list_menu_item_radio.xml @@ -0,0 +1,24 @@ + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__popup_menu_item_layout.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__popup_menu_item_layout.xml new file mode 100644 index 0000000000..d42425ad32 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__popup_menu_item_layout.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar.xml new file mode 100644 index 0000000000..1fb82fe9a4 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar_overlay.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar_overlay.xml new file mode 100644 index 0000000000..0961ef561a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_action_bar_overlay.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple.xml new file mode 100644 index 0000000000..33e2dea0de --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple.xml @@ -0,0 +1,38 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple_overlay_action_mode.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple_overlay_action_mode.xml new file mode 100644 index 0000000000..f8b9fb1859 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__screen_simple_overlay_action_mode.xml @@ -0,0 +1,38 @@ + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_dropdown_item_icons_2line.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_dropdown_item_icons_2line.xml new file mode 100644 index 0000000000..e1d3dc49cb --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_dropdown_item_icons_2line.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_view.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_view.xml new file mode 100644 index 0000000000..6ba319121c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__search_view.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__simple_dropdown_hint.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__simple_dropdown_hint.xml new file mode 100644 index 0000000000..8fc0eb12cb --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/abs__simple_dropdown_hint.xml @@ -0,0 +1,29 @@ + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_dropdown_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_dropdown_item.xml new file mode 100644 index 0000000000..a6c6252d26 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_dropdown_item.xml @@ -0,0 +1,26 @@ + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_item.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_item.xml new file mode 100644 index 0000000000..bea7401781 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/layout/sherlock_spinner_item.xml @@ -0,0 +1,26 @@ + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-land/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-land/abs__dimens.xml new file mode 100644 index 0000000000..502cc16a30 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-land/abs__dimens.xml @@ -0,0 +1,33 @@ + + + + + 40dip + + 4dip + + 16dp + + 12dp + + -2dp + + 4dip + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-hdpi-1024x600/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-hdpi-1024x600/abs__dimens.xml new file mode 100644 index 0000000000..3312cfa7fd --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-hdpi-1024x600/abs__dimens.xml @@ -0,0 +1,33 @@ + + + + + 48dip + + 8dip + + 18dp + + 14dp + + -3dp + + 5dip + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-hdpi-1024x600/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-hdpi-1024x600/abs__dimens.xml new file mode 100644 index 0000000000..502cc16a30 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-hdpi-1024x600/abs__dimens.xml @@ -0,0 +1,33 @@ + + + + + 40dip + + 4dip + + 16dp + + 12dp + + -2dp + + 4dip + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-mdpi-1024x600/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-mdpi-1024x600/abs__dimens.xml new file mode 100644 index 0000000000..3312cfa7fd --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-land-mdpi-1024x600/abs__dimens.xml @@ -0,0 +1,33 @@ + + + + + 48dip + + 8dip + + 18dp + + 14dp + + -3dp + + 5dip + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-mdpi-1024x600/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-mdpi-1024x600/abs__dimens.xml new file mode 100644 index 0000000000..35910333b2 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large-mdpi-1024x600/abs__dimens.xml @@ -0,0 +1,36 @@ + + + + + 56dip + + 4dip + + 18dp + + 14dp + + -3dp + + 9dip + + + 64dip + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large/abs__dimens.xml new file mode 100644 index 0000000000..63b12f7f3b --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-large/abs__dimens.xml @@ -0,0 +1,29 @@ + + + + + 55% + + 80% + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__bools.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__bools.xml new file mode 100644 index 0000000000..7a48e1542e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__bools.xml @@ -0,0 +1,19 @@ + + + + + false + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__dimens.xml new file mode 100644 index 0000000000..f678538173 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-sw600dp/abs__dimens.xml @@ -0,0 +1,38 @@ + + + + + 56dip + + 4dip + + 18dp + + 14dp + + -3dp + + 9dip + + 5 + + + 64dip + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v11/abs__themes.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v11/abs__themes.xml new file mode 100644 index 0000000000..03473572c2 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v11/abs__themes.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__styles.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__styles.xml new file mode 100644 index 0000000000..88a60dd92d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__styles.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__themes.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__themes.xml new file mode 100644 index 0000000000..5fac1ab584 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-v14/abs__themes.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w360dp/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w360dp/abs__dimens.xml new file mode 100644 index 0000000000..6f49d7e47b --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w360dp/abs__dimens.xml @@ -0,0 +1,22 @@ + + + + 3 + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__bools.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__bools.xml new file mode 100644 index 0000000000..3eaf4aee9d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__bools.xml @@ -0,0 +1,22 @@ + + + + true + false + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__config.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__config.xml new file mode 100644 index 0000000000..88357b0a76 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w480dp/abs__config.xml @@ -0,0 +1,29 @@ + + + + + + + + true + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w500dp/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w500dp/abs__dimens.xml new file mode 100644 index 0000000000..2fd4deea2d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w500dp/abs__dimens.xml @@ -0,0 +1,22 @@ + + + + 4 + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w600dp/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w600dp/abs__dimens.xml new file mode 100644 index 0000000000..b085952d32 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-w600dp/abs__dimens.xml @@ -0,0 +1,22 @@ + + + + 5 + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-xlarge/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-xlarge/abs__dimens.xml new file mode 100644 index 0000000000..bfc535de16 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values-xlarge/abs__dimens.xml @@ -0,0 +1,45 @@ + + + + + 56dip + + 4dip + + 18dp + + 14dp + + -3dp + + 9dip + + + 64dip + + + 45% + + 72% + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__attrs.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__attrs.xml new file mode 100644 index 0000000000..32631ca8d3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__attrs.xml @@ -0,0 +1,432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__bools.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__bools.xml new file mode 100644 index 0000000000..0b432448d9 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__bools.xml @@ -0,0 +1,22 @@ + + + + + false + true + true + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__colors.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__colors.xml new file mode 100644 index 0000000000..625c632ff7 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__colors.xml @@ -0,0 +1,27 @@ + + + + + #ff000000 + #fff3f3f3 + @color/abs__background_holo_light + @color/abs__background_holo_dark + #ff4c4c4c + #ffb2b2b2 + @color/abs__bright_foreground_holo_light + @color/abs__bright_foreground_holo_dark + #ff33b5e5 + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__config.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__config.xml new file mode 100644 index 0000000000..4c7b5d4598 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__config.xml @@ -0,0 +1,43 @@ + + + + + + + + 320dp + + + false + + + true + + + false + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__dimens.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__dimens.xml new file mode 100644 index 0000000000..831289e073 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__dimens.xml @@ -0,0 +1,67 @@ + + + + + 48dip + + 8dip + + 18dp + + 14dp + + -3dp + + 5dip + + 2 + + + 56dip + + + 64dip + + + 65% + + 95% + + + + 8dip + + + 8dip + + + 32dip + + + + 160dip + + + 320dip + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__ids.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__ids.xml new file mode 100644 index 0000000000..f9f56045b3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__ids.xml @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__strings.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__strings.xml new file mode 100644 index 0000000000..06a2a2af4e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__strings.xml @@ -0,0 +1,53 @@ + + + + + Navigate home + + Navigate up + + More options + + + Done + + + See all... + + Select activity + + Share with... + + Choose an application + + Share with + + Share with %s + + + Search + + Search query + + Clear query + + Submit query + + Voice search + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__styles.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__styles.xml new file mode 100644 index 0000000000..45a18c1833 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__styles.xml @@ -0,0 +1,412 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__themes.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__themes.xml new file mode 100644 index 0000000000..634fa798b0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/res/values/abs__themes.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/android/support/v4/app/Watson.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/android/support/v4/app/Watson.java new file mode 100644 index 0000000000..d93de4c6a1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/android/support/v4/app/Watson.java @@ -0,0 +1,144 @@ +package android.support.v4.app; + +import android.util.Log; +import android.view.View; +import android.view.Window; +import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; +import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; +import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +import java.util.ArrayList; + +/** I'm in ur package. Stealing ur variables. */ +public abstract class Watson extends FragmentActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener { + private static final boolean DEBUG = false; + private static final String TAG = "Watson"; + + /** Fragment interface for menu creation callback. */ + public interface OnCreateOptionsMenuListener { + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater); + } + /** Fragment interface for menu preparation callback. */ + public interface OnPrepareOptionsMenuListener { + public void onPrepareOptionsMenu(Menu menu); + } + /** Fragment interface for menu item selection callback. */ + public interface OnOptionsItemSelectedListener { + public boolean onOptionsItemSelected(MenuItem item); + } + + private ArrayList mCreatedMenus; + + + /////////////////////////////////////////////////////////////////////////// + // Sherlock menu handling + /////////////////////////////////////////////////////////////////////////// + + @Override + public boolean onCreatePanelMenu(int featureId, Menu menu) { + if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] featureId: " + featureId + ", menu: " + menu); + + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + boolean result = onCreateOptionsMenu(menu); + if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] activity create result: " + result); + + MenuInflater inflater = getSupportMenuInflater(); + boolean show = false; + ArrayList newMenus = null; + if (mFragments.mAdded != null) { + for (int i = 0; i < mFragments.mAdded.size(); i++) { + Fragment f = mFragments.mAdded.get(i); + if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnCreateOptionsMenuListener) { + show = true; + ((OnCreateOptionsMenuListener)f).onCreateOptionsMenu(menu, inflater); + if (newMenus == null) { + newMenus = new ArrayList(); + } + newMenus.add(f); + } + } + } + + if (mCreatedMenus != null) { + for (int i = 0; i < mCreatedMenus.size(); i++) { + Fragment f = mCreatedMenus.get(i); + if (newMenus == null || !newMenus.contains(f)) { + f.onDestroyOptionsMenu(); + } + } + } + + mCreatedMenus = newMenus; + + if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] fragments create result: " + show); + result |= show; + + if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] returning " + result); + return result; + } + return false; + } + + @Override + public boolean onPreparePanel(int featureId, View view, Menu menu) { + if (DEBUG) Log.d(TAG, "[onPreparePanel] featureId: " + featureId + ", view: " + view + " menu: " + menu); + + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + boolean result = onPrepareOptionsMenu(menu); + if (DEBUG) Log.d(TAG, "[onPreparePanel] activity prepare result: " + result); + + boolean show = false; + if (mFragments.mAdded != null) { + for (int i = 0; i < mFragments.mAdded.size(); i++) { + Fragment f = mFragments.mAdded.get(i); + if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnPrepareOptionsMenuListener) { + show = true; + ((OnPrepareOptionsMenuListener)f).onPrepareOptionsMenu(menu); + } + } + } + + if (DEBUG) Log.d(TAG, "[onPreparePanel] fragments prepare result: " + show); + result |= show; + + result &= menu.hasVisibleItems(); + if (DEBUG) Log.d(TAG, "[onPreparePanel] returning " + result); + return result; + } + return false; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + if (DEBUG) Log.d(TAG, "[onMenuItemSelected] featureId: " + featureId + ", item: " + item); + + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + if (onOptionsItemSelected(item)) { + return true; + } + + if (mFragments.mAdded != null) { + for (int i = 0; i < mFragments.mAdded.size(); i++) { + Fragment f = mFragments.mAdded.get(i); + if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnOptionsItemSelectedListener) { + if (((OnOptionsItemSelectedListener)f).onOptionsItemSelected(item)) { + return true; + } + } + } + } + } + return false; + } + + public abstract boolean onCreateOptionsMenu(Menu menu); + + public abstract boolean onPrepareOptionsMenu(Menu menu); + + public abstract boolean onOptionsItemSelected(MenuItem item); + + public abstract MenuInflater getSupportMenuInflater(); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/ActionBarSherlock.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/ActionBarSherlock.java new file mode 100644 index 0000000000..a2767c2537 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/ActionBarSherlock.java @@ -0,0 +1,794 @@ +package com.actionbarsherlock; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Iterator; +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.internal.ActionBarSherlockCompat; +import com.actionbarsherlock.internal.ActionBarSherlockNative; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +/** + *

Helper for implementing the action bar design pattern across all versions + * of Android.

+ * + *

This class will manage interaction with a custom action bar based on the + * Android 4.0 source code. The exposed API mirrors that of its native + * counterpart and you should refer to its documentation for instruction.

+ * + * @author Jake Wharton + */ +public abstract class ActionBarSherlock { + protected static final String TAG = "ActionBarSherlock"; + protected static final boolean DEBUG = false; + + private static final Class[] CONSTRUCTOR_ARGS = new Class[] { Activity.class, int.class }; + private static final HashMap> IMPLEMENTATIONS = + new HashMap>(); + + static { + //Register our two built-in implementations + registerImplementation(ActionBarSherlockCompat.class); + registerImplementation(ActionBarSherlockNative.class); + } + + + /** + *

Denotes an implementation of ActionBarSherlock which provides an + * action bar-enhanced experience.

+ */ + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.RUNTIME) + public @interface Implementation { + static final int DEFAULT_API = -1; + static final int DEFAULT_DPI = -1; + + int api() default DEFAULT_API; + int dpi() default DEFAULT_DPI; + } + + + /** Activity interface for menu creation callback. */ + public interface OnCreatePanelMenuListener { + public boolean onCreatePanelMenu(int featureId, Menu menu); + } + /** Activity interface for menu creation callback. */ + public interface OnCreateOptionsMenuListener { + public boolean onCreateOptionsMenu(Menu menu); + } + /** Activity interface for menu item selection callback. */ + public interface OnMenuItemSelectedListener { + public boolean onMenuItemSelected(int featureId, MenuItem item); + } + /** Activity interface for menu item selection callback. */ + public interface OnOptionsItemSelectedListener { + public boolean onOptionsItemSelected(MenuItem item); + } + /** Activity interface for menu preparation callback. */ + public interface OnPreparePanelListener { + public boolean onPreparePanel(int featureId, View view, Menu menu); + } + /** Activity interface for menu preparation callback. */ + public interface OnPrepareOptionsMenuListener { + public boolean onPrepareOptionsMenu(Menu menu); + } + /** Activity interface for action mode finished callback. */ + public interface OnActionModeFinishedListener { + public void onActionModeFinished(ActionMode mode); + } + /** Activity interface for action mode started callback. */ + public interface OnActionModeStartedListener { + public void onActionModeStarted(ActionMode mode); + } + + + /** + * If set, the logic in these classes will assume that an {@link Activity} + * is dispatching all of the required events to the class. This flag should + * only be used internally or if you are creating your own base activity + * modeled after one of the included types (e.g., {@code SherlockActivity}). + */ + public static final int FLAG_DELEGATE = 1; + + + /** + * Register an ActionBarSherlock implementation. + * + * @param implementationClass Target implementation class which extends + * {@link com.actionbarsherlock.ActionBarSherlock}. This class must also be annotated with + * {@link com.actionbarsherlock.ActionBarSherlock.Implementation}. + */ + public static void registerImplementation(Class implementationClass) { + if (!implementationClass.isAnnotationPresent(Implementation.class)) { + throw new IllegalArgumentException("Class " + implementationClass.getSimpleName() + " is not annotated with @Implementation"); + } else if (IMPLEMENTATIONS.containsValue(implementationClass)) { + if (DEBUG) Log.w(TAG, "Class " + implementationClass.getSimpleName() + " already registered"); + return; + } + + Implementation impl = implementationClass.getAnnotation(Implementation.class); + if (DEBUG) Log.i(TAG, "Registering " + implementationClass.getSimpleName() + " with qualifier " + impl); + IMPLEMENTATIONS.put(impl, implementationClass); + } + + /** + * Unregister an ActionBarSherlock implementation. This should be + * considered very volatile and you should only use it if you know what + * you are doing. You have been warned. + * + * @param implementationClass Target implementation class. + * @return Boolean indicating whether the class was removed. + */ + public static boolean unregisterImplementation(Class implementationClass) { + return IMPLEMENTATIONS.values().remove(implementationClass); + } + + /** + * Wrap an activity with an action bar abstraction which will enable the + * use of a custom implementation on platforms where a native version does + * not exist. + * + * @param activity Activity to wrap. + * @return Instance to interact with the action bar. + */ + public static ActionBarSherlock wrap(Activity activity) { + return wrap(activity, 0); + } + + /** + * Wrap an activity with an action bar abstraction which will enable the + * use of a custom implementation on platforms where a native version does + * not exist. + * + * @param activity Owning activity. + * @param flags Option flags to control behavior. + * @return Instance to interact with the action bar. + */ + public static ActionBarSherlock wrap(Activity activity, int flags) { + //Create a local implementation map we can modify + HashMap> impls = + new HashMap>(IMPLEMENTATIONS); + boolean hasQualfier; + + /* DPI FILTERING */ + hasQualfier = false; + for (Implementation key : impls.keySet()) { + //Only honor TVDPI as a specific qualifier + if (key.dpi() == DisplayMetrics.DENSITY_TV) { + hasQualfier = true; + break; + } + } + if (hasQualfier) { + final boolean isTvDpi = activity.getResources().getDisplayMetrics().densityDpi == DisplayMetrics.DENSITY_TV; + for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { + int keyDpi = keys.next().dpi(); + if ((isTvDpi && keyDpi != DisplayMetrics.DENSITY_TV) + || (!isTvDpi && keyDpi == DisplayMetrics.DENSITY_TV)) { + keys.remove(); + } + } + } + + /* API FILTERING */ + hasQualfier = false; + for (Implementation key : impls.keySet()) { + if (key.api() != Implementation.DEFAULT_API) { + hasQualfier = true; + break; + } + } + if (hasQualfier) { + final int runtimeApi = Build.VERSION.SDK_INT; + int bestApi = 0; + for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { + int keyApi = keys.next().api(); + if (keyApi > runtimeApi) { + keys.remove(); + } else if (keyApi > bestApi) { + bestApi = keyApi; + } + } + for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { + if (keys.next().api() != bestApi) { + keys.remove(); + } + } + } + + if (impls.size() > 1) { + throw new IllegalStateException("More than one implementation matches configuration."); + } + if (impls.isEmpty()) { + throw new IllegalStateException("No implementations match configuration."); + } + Class impl = impls.values().iterator().next(); + if (DEBUG) Log.i(TAG, "Using implementation: " + impl.getSimpleName()); + + try { + Constructor ctor = impl.getConstructor(CONSTRUCTOR_ARGS); + return ctor.newInstance(activity, flags); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + + /** Activity which is displaying the action bar. Also used for context. */ + protected final Activity mActivity; + /** Whether delegating actions for the activity or managing ourselves. */ + protected final boolean mIsDelegate; + + /** Reference to our custom menu inflater which supports action items. */ + protected MenuInflater mMenuInflater; + + + + protected ActionBarSherlock(Activity activity, int flags) { + if (DEBUG) Log.d(TAG, "[] activity: " + activity + ", flags: " + flags); + + mActivity = activity; + mIsDelegate = (flags & FLAG_DELEGATE) != 0; + } + + + /** + * Get the current action bar instance. + * + * @return Action bar instance. + */ + public abstract ActionBar getActionBar(); + + + /////////////////////////////////////////////////////////////////////////// + // Lifecycle and interaction callbacks when delegating + /////////////////////////////////////////////////////////////////////////// + + /** + * Notify action bar of a configuration change event. Should be dispatched + * after the call to the superclass implementation. + * + *
+     * @Override
+     * public void onConfigurationChanged(Configuration newConfig) {
+     *     super.onConfigurationChanged(newConfig);
+     *     mSherlock.dispatchConfigurationChanged(newConfig);
+     * }
+     * 
+ * + * @param newConfig The new device configuration. + */ + public void dispatchConfigurationChanged(Configuration newConfig) {} + + /** + * Notify the action bar that the activity has finished its resuming. This + * should be dispatched after the call to the superclass implementation. + * + *
+     * @Override
+     * protected void onPostResume() {
+     *     super.onPostResume();
+     *     mSherlock.dispatchPostResume();
+     * }
+     * 
+ */ + public void dispatchPostResume() {} + + /** + * Notify the action bar that the activity is pausing. This should be + * dispatched before the call to the superclass implementation. + * + *
+     * @Override
+     * protected void onPause() {
+     *     mSherlock.dispatchPause();
+     *     super.onPause();
+     * }
+     * 
+ */ + public void dispatchPause() {} + + /** + * Notify the action bar that the activity is stopping. This should be + * called before the superclass implementation. + * + *

+ * @Override + * protected void onStop() { + * mSherlock.dispatchStop(); + * super.onStop(); + * } + *

+ */ + public void dispatchStop() {} + + /** + * Indicate that the menu should be recreated by calling + * {@link com.actionbarsherlock.ActionBarSherlock.OnCreateOptionsMenuListener#onCreateOptionsMenu(com.actionbarsherlock.view.Menu)}. + */ + public abstract void dispatchInvalidateOptionsMenu(); + + /** + * Notify the action bar that it should display its overflow menu if it is + * appropriate for the device. The implementation should conditionally + * call the superclass method only if this method returns {@code false}. + * + *

+ * @Override + * public void openOptionsMenu() { + * if (!mSherlock.dispatchOpenOptionsMenu()) { + * super.openOptionsMenu(); + * } + * } + *

+ * + * @return {@code true} if the opening of the menu was handled internally. + */ + public boolean dispatchOpenOptionsMenu() { + return false; + } + + /** + * Notify the action bar that it should close its overflow menu if it is + * appropriate for the device. This implementation should conditionally + * call the superclass method only if this method returns {@code false}. + * + *
+     * @Override
+     * public void closeOptionsMenu() {
+     *     if (!mSherlock.dispatchCloseOptionsMenu()) {
+     *         super.closeOptionsMenu();
+     *     }
+     * }
+     * 
+ * + * @return {@code true} if the closing of the menu was handled internally. + */ + public boolean dispatchCloseOptionsMenu() { + return false; + } + + /** + * Notify the class that the activity has finished its creation. This + * should be called after the superclass implementation. + * + *
+     * @Override
+     * protected void onPostCreate(Bundle savedInstanceState) {
+     *     mSherlock.dispatchPostCreate(savedInstanceState);
+     *     super.onPostCreate(savedInstanceState);
+     * }
+     * 
+ * + * @param savedInstanceState If the activity is being re-initialized after + * previously being shut down then this Bundle + * contains the data it most recently supplied in + * {@link Activity#}onSaveInstanceState(Bundle)}. + * Note: Otherwise it is null. + */ + public void dispatchPostCreate(Bundle savedInstanceState) {} + + /** + * Notify the action bar that the title has changed and the action bar + * should be updated to reflect the change. This should be called before + * the superclass implementation. + * + *
+     *  @Override
+     *  protected void onTitleChanged(CharSequence title, int color) {
+     *      mSherlock.dispatchTitleChanged(title, color);
+     *      super.onTitleChanged(title, color);
+     *  }
+     * 
+ * + * @param title New activity title. + * @param color New activity color. + */ + public void dispatchTitleChanged(CharSequence title, int color) {} + + /** + * Notify the action bar the user has created a key event. This is used to + * toggle the display of the overflow action item with the menu key and to + * close the action mode or expanded action item with the back key. + * + *
+     * @Override
+     * public boolean dispatchKeyEvent(KeyEvent event) {
+     *     if (mSherlock.dispatchKeyEvent(event)) {
+     *         return true;
+     *     }
+     *     return super.dispatchKeyEvent(event);
+     * }
+     * 
+ * + * @param event Description of the key event. + * @return {@code true} if the event was handled. + */ + public boolean dispatchKeyEvent(KeyEvent event) { + return false; + } + + /** + * Notify the action bar that the Activity has triggered a menu creation + * which should happen on the conclusion of {@link Activity#onCreate}. This + * will be used to gain a reference to the native menu for native and + * overflow binding as well as to indicate when compatibility create should + * occur for the first time. + * + * @param menu Activity native menu. + * @return {@code true} since we always want to say that we have a native + */ + public abstract boolean dispatchCreateOptionsMenu(android.view.Menu menu); + + /** + * Notify the action bar that the Activity has triggered a menu preparation + * which usually means that the user has requested the overflow menu via a + * hardware menu key. You should return the result of this method call and + * not call the superclass implementation. + * + *

+ * @Override + * public final boolean onPrepareOptionsMenu(android.view.Menu menu) { + * return mSherlock.dispatchPrepareOptionsMenu(menu); + * } + *

+ * + * @param menu Activity native menu. + * @return {@code true} if menu display should proceed. + */ + public abstract boolean dispatchPrepareOptionsMenu(android.view.Menu menu); + + /** + * Notify the action bar that a native options menu item has been selected. + * The implementation should return the result of this method call. + * + *

+ * @Override + * public final boolean onOptionsItemSelected(android.view.MenuItem item) { + * return mSherlock.dispatchOptionsItemSelected(item); + * } + *

+ * + * @param item Options menu item. + * @return @{code true} if the selection was handled. + */ + public abstract boolean dispatchOptionsItemSelected(android.view.MenuItem item); + + /** + * Notify the action bar that the overflow menu has been opened. The + * implementation should conditionally return {@code true} if this method + * returns {@code true}, otherwise return the result of the superclass + * method. + * + *

+ * @Override + * public final boolean onMenuOpened(int featureId, android.view.Menu menu) { + * if (mSherlock.dispatchMenuOpened(featureId, menu)) { + * return true; + * } + * return super.onMenuOpened(featureId, menu); + * } + *

+ * + * @param featureId Window feature which triggered the event. + * @param menu Activity native menu. + * @return {@code true} if the event was handled by this method. + */ + public boolean dispatchMenuOpened(int featureId, android.view.Menu menu) { + return false; + } + + /** + * Notify the action bar that the overflow menu has been closed. This + * method should be called before the superclass implementation. + * + *

+ * @Override + * public void onPanelClosed(int featureId, android.view.Menu menu) { + * mSherlock.dispatchPanelClosed(featureId, menu); + * super.onPanelClosed(featureId, menu); + * } + *

+ * + * @param featureId + * @param menu + */ + public void dispatchPanelClosed(int featureId, android.view.Menu menu) {} + + /** + * Notify the action bar that the activity has been destroyed. This method + * should be called before the superclass implementation. + * + *

+ * @Override + * public void onDestroy() { + * mSherlock.dispatchDestroy(); + * super.onDestroy(); + * } + *

+ */ + public void dispatchDestroy() {} + + public void dispatchSaveInstanceState(Bundle outState) {} + + public void dispatchRestoreInstanceState(Bundle savedInstanceState) {} + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + + /** + * Internal method to trigger the menu creation process. + * + * @return {@code true} if menu creation should proceed. + */ + protected final boolean callbackCreateOptionsMenu(Menu menu) { + if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] menu: " + menu); + + boolean result = true; + if (mActivity instanceof OnCreatePanelMenuListener) { + OnCreatePanelMenuListener listener = (OnCreatePanelMenuListener)mActivity; + result = listener.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu); + } else if (mActivity instanceof OnCreateOptionsMenuListener) { + OnCreateOptionsMenuListener listener = (OnCreateOptionsMenuListener)mActivity; + result = listener.onCreateOptionsMenu(menu); + } + + if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] returning " + result); + return result; + } + + /** + * Internal method to trigger the menu preparation process. + * + * @return {@code true} if menu preparation should proceed. + */ + protected final boolean callbackPrepareOptionsMenu(Menu menu) { + if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] menu: " + menu); + + boolean result = true; + if (mActivity instanceof OnPreparePanelListener) { + OnPreparePanelListener listener = (OnPreparePanelListener)mActivity; + result = listener.onPreparePanel(Window.FEATURE_OPTIONS_PANEL, null, menu); + } else if (mActivity instanceof OnPrepareOptionsMenuListener) { + OnPrepareOptionsMenuListener listener = (OnPrepareOptionsMenuListener)mActivity; + result = listener.onPrepareOptionsMenu(menu); + } + + if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] returning " + result); + return result; + } + + /** + * Internal method for dispatching options menu selection to the owning + * activity callback. + * + * @param item Selected options menu item. + * @return {@code true} if the item selection was handled in the callback. + */ + protected final boolean callbackOptionsItemSelected(MenuItem item) { + if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] item: " + item.getTitleCondensed()); + + boolean result = false; + if (mActivity instanceof OnMenuItemSelectedListener) { + OnMenuItemSelectedListener listener = (OnMenuItemSelectedListener)mActivity; + result = listener.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item); + } else if (mActivity instanceof OnOptionsItemSelectedListener) { + OnOptionsItemSelectedListener listener = (OnOptionsItemSelectedListener)mActivity; + result = listener.onOptionsItemSelected(item); + } + + if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] returning " + result); + return result; + } + + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + + /** + * Query for the availability of a certain feature. + * + * @param featureId The feature ID to check. + * @return {@code true} if feature is enabled, {@code false} otherwise. + */ + public abstract boolean hasFeature(int featureId); + + /** + * Enable extended screen features. This must be called before + * {@code setContentView()}. May be called as many times as desired as long + * as it is before {@code setContentView()}. If not called, no extended + * features will be available. You can not turn off a feature once it is + * requested. + * + * @param featureId The desired features, defined as constants by Window. + * @return Returns true if the requested feature is supported and now + * enabled. + */ + public abstract boolean requestFeature(int featureId); + + /** + * Set extra options that will influence the UI for this window. + * + * @param uiOptions Flags specifying extra options for this window. + */ + public abstract void setUiOptions(int uiOptions); + + /** + * Set extra options that will influence the UI for this window. Only the + * bits filtered by mask will be modified. + * + * @param uiOptions Flags specifying extra options for this window. + * @param mask Flags specifying which options should be modified. Others + * will remain unchanged. + */ + public abstract void setUiOptions(int uiOptions, int mask); + + /** + * Set the content of the activity inside the action bar. + * + * @param layoutResId Layout resource ID. + */ + public abstract void setContentView(int layoutResId); + + /** + * Set the content of the activity inside the action bar. + * + * @param view The desired content to display. + */ + public void setContentView(View view) { + if (DEBUG) Log.d(TAG, "[setContentView] view: " + view); + + setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); + } + + /** + * Set the content of the activity inside the action bar. + * + * @param view The desired content to display. + * @param params Layout parameters to apply to the view. + */ + public abstract void setContentView(View view, ViewGroup.LayoutParams params); + + /** + * Variation on {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} + * to add an additional content view to the screen. Added after any + * existing ones on the screen -- existing views are NOT removed. + * + * @param view The desired content to display. + * @param params Layout parameters for the view. + */ + public abstract void addContentView(View view, ViewGroup.LayoutParams params); + + /** + * Change the title associated with this activity. + */ + public abstract void setTitle(CharSequence title); + + /** + * Change the title associated with this activity. + */ + public void setTitle(int resId) { + if (DEBUG) Log.d(TAG, "[setTitle] resId: " + resId); + + setTitle(mActivity.getString(resId)); + } + + /** + * Sets the visibility of the progress bar in the title. + *

+ * In order for the progress bar to be shown, the feature must be requested + * via {@link #requestWindowFeature(int)}. + * + * @param visible Whether to show the progress bars in the title. + */ + public abstract void setProgressBarVisibility(boolean visible); + + /** + * Sets the visibility of the indeterminate progress bar in the title. + *

+ * In order for the progress bar to be shown, the feature must be requested + * via {@link #requestWindowFeature(int)}. + * + * @param visible Whether to show the progress bars in the title. + */ + public abstract void setProgressBarIndeterminateVisibility(boolean visible); + + /** + * Sets whether the horizontal progress bar in the title should be indeterminate (the circular + * is always indeterminate). + *

+ * In order for the progress bar to be shown, the feature must be requested + * via {@link #requestWindowFeature(int)}. + * + * @param indeterminate Whether the horizontal progress bar should be indeterminate. + */ + public abstract void setProgressBarIndeterminate(boolean indeterminate); + + /** + * Sets the progress for the progress bars in the title. + *

+ * In order for the progress bar to be shown, the feature must be requested + * via {@link #requestWindowFeature(int)}. + * + * @param progress The progress for the progress bar. Valid ranges are from + * 0 to 10000 (both inclusive). If 10000 is given, the progress + * bar will be completely filled and will fade out. + */ + public abstract void setProgress(int progress); + + /** + * Sets the secondary progress for the progress bar in the title. This + * progress is drawn between the primary progress (set via + * {@link #setProgress(int)} and the background. It can be ideal for media + * scenarios such as showing the buffering progress while the default + * progress shows the play progress. + *

+ * In order for the progress bar to be shown, the feature must be requested + * via {@link #requestWindowFeature(int)}. + * + * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from + * 0 to 10000 (both inclusive). + */ + public abstract void setSecondaryProgress(int secondaryProgress); + + /** + * Get a menu inflater instance which supports the newer menu attributes. + * + * @return Menu inflater instance. + */ + public MenuInflater getMenuInflater() { + if (DEBUG) Log.d(TAG, "[getMenuInflater]"); + + // Make sure that action views can get an appropriate theme. + if (mMenuInflater == null) { + if (getActionBar() != null) { + mMenuInflater = new MenuInflater(getThemedContext(), mActivity); + } else { + mMenuInflater = new MenuInflater(mActivity); + } + } + return mMenuInflater; + } + + protected abstract Context getThemedContext(); + + /** + * Start an action mode. + * + * @param callback Callback that will manage lifecycle events for this + * context mode. + * @return The ContextMode that was started, or null if it was canceled. + * @see ActionMode + */ + public abstract ActionMode startActionMode(ActionMode.Callback callback); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/ActionBar.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/ActionBar.java new file mode 100644 index 0000000000..24266bcb5c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/ActionBar.java @@ -0,0 +1,956 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.app; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.support.v4.app.FragmentTransaction; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewDebug; +import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; +import android.widget.SpinnerAdapter; + +/** + * A window feature at the top of the activity that may display the activity title, navigation + * modes, and other interactive items. + *

Beginning with Android 3.0 (API level 11), the action bar appears at the top of an + * activity's window when the activity uses the system's {@link + * android.R.style#Theme_Holo Holo} theme (or one of its descendant themes), which is the default. + * You may otherwise add the action bar by calling {@link + * android.view.Window#requestFeature requestFeature(FEATURE_ACTION_BAR)} or by declaring it in a + * custom theme with the {@link android.R.styleable#Theme_windowActionBar windowActionBar} property. + *

By default, the action bar shows the application icon on + * the left, followed by the activity title. If your activity has an options menu, you can make + * select items accessible directly from the action bar as "action items". You can also + * modify various characteristics of the action bar or remove it completely.

+ *

From your activity, you can retrieve an instance of {@link com.actionbarsherlock.app.ActionBar} by calling {@link + * android.app.Activity#getActionBar getActionBar()}.

+ *

In some cases, the action bar may be overlayed by another bar that enables contextual actions, + * using an {@link android.view.ActionMode}. For example, when the user selects one or more items in + * your activity, you can enable an action mode that offers actions specific to the selected + * items, with a UI that temporarily replaces the action bar. Although the UI may occupy the + * same space, the {@link android.view.ActionMode} APIs are distinct and independent from those for + * {@link com.actionbarsherlock.app.ActionBar}. + *

+ *

Developer Guides

+ *

For information about how to use the action bar, including how to add action items, navigation + * modes and more, read the Action + * Bar developer guide.

+ *
+ */ +public abstract class ActionBar { + /** + * Standard navigation mode. Consists of either a logo or icon + * and title text with an optional subtitle. Clicking any of these elements + * will dispatch onOptionsItemSelected to the host Activity with + * a MenuItem with item ID android.R.id.home. + */ + public static final int NAVIGATION_MODE_STANDARD = android.app.ActionBar.NAVIGATION_MODE_STANDARD; + + /** + * List navigation mode. Instead of static title text this mode + * presents a list menu for navigation within the activity. + * e.g. this might be presented to the user as a dropdown list. + */ + public static final int NAVIGATION_MODE_LIST = android.app.ActionBar.NAVIGATION_MODE_LIST; + + /** + * Tab navigation mode. Instead of static title text this mode + * presents a series of tabs for navigation within the activity. + */ + public static final int NAVIGATION_MODE_TABS = android.app.ActionBar.NAVIGATION_MODE_TABS; + + /** + * Use logo instead of icon if available. This flag will cause appropriate + * navigation modes to use a wider logo in place of the standard icon. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_USE_LOGO = android.app.ActionBar.DISPLAY_USE_LOGO; + + /** + * Show 'home' elements in this action bar, leaving more space for other + * navigation elements. This includes logo and icon. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_SHOW_HOME = android.app.ActionBar.DISPLAY_SHOW_HOME; + + /** + * Display the 'home' element such that it appears as an 'up' affordance. + * e.g. show an arrow to the left indicating the action that will be taken. + * + * Set this flag if selecting the 'home' button in the action bar to return + * up by a single level in your UI rather than back to the top level or front page. + * + *

Setting this option will implicitly enable interaction with the home/up + * button. See {@link #setHomeButtonEnabled(boolean)}. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_HOME_AS_UP = android.app.ActionBar.DISPLAY_HOME_AS_UP; + + /** + * Show the activity title and subtitle, if present. + * + * @see #setTitle(CharSequence) + * @see #setTitle(int) + * @see #setSubtitle(CharSequence) + * @see #setSubtitle(int) + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_SHOW_TITLE = android.app.ActionBar.DISPLAY_SHOW_TITLE; + + /** + * Show the custom view if one has been set. + * @see #setCustomView(View) + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public static final int DISPLAY_SHOW_CUSTOM = android.app.ActionBar.DISPLAY_SHOW_CUSTOM; + + /** + * Set the action bar into custom navigation mode, supplying a view + * for custom navigation. + * + * Custom navigation views appear between the application icon and + * any action buttons and may use any space available there. Common + * use cases for custom navigation views might include an auto-suggesting + * address bar for a browser or other navigation mechanisms that do not + * translate well to provided navigation modes. + * + * @param view Custom navigation view to place in the ActionBar. + */ + public abstract void setCustomView(View view); + + /** + * Set the action bar into custom navigation mode, supplying a view + * for custom navigation. + * + *

Custom navigation views appear between the application icon and + * any action buttons and may use any space available there. Common + * use cases for custom navigation views might include an auto-suggesting + * address bar for a browser or other navigation mechanisms that do not + * translate well to provided navigation modes.

+ * + *

The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for + * the custom view to be displayed.

+ * + * @param view Custom navigation view to place in the ActionBar. + * @param layoutParams How this custom view should layout in the bar. + * + * @see #setDisplayOptions(int, int) + */ + public abstract void setCustomView(View view, LayoutParams layoutParams); + + /** + * Set the action bar into custom navigation mode, supplying a view + * for custom navigation. + * + *

Custom navigation views appear between the application icon and + * any action buttons and may use any space available there. Common + * use cases for custom navigation views might include an auto-suggesting + * address bar for a browser or other navigation mechanisms that do not + * translate well to provided navigation modes.

+ * + *

The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for + * the custom view to be displayed.

+ * + * @param resId Resource ID of a layout to inflate into the ActionBar. + * + * @see #setDisplayOptions(int, int) + */ + public abstract void setCustomView(int resId); + + /** + * Set the icon to display in the 'home' section of the action bar. + * The action bar will use an icon specified by its style or the + * activity icon by default. + * + * Whether the home section shows an icon or logo is controlled + * by the display option {@link #DISPLAY_USE_LOGO}. + * + * @param resId Resource ID of a drawable to show as an icon. + * + * @see #setDisplayUseLogoEnabled(boolean) + * @see #setDisplayShowHomeEnabled(boolean) + */ + public abstract void setIcon(int resId); + + /** + * Set the icon to display in the 'home' section of the action bar. + * The action bar will use an icon specified by its style or the + * activity icon by default. + * + * Whether the home section shows an icon or logo is controlled + * by the display option {@link #DISPLAY_USE_LOGO}. + * + * @param icon Drawable to show as an icon. + * + * @see #setDisplayUseLogoEnabled(boolean) + * @see #setDisplayShowHomeEnabled(boolean) + */ + public abstract void setIcon(Drawable icon); + + /** + * Set the logo to display in the 'home' section of the action bar. + * The action bar will use a logo specified by its style or the + * activity logo by default. + * + * Whether the home section shows an icon or logo is controlled + * by the display option {@link #DISPLAY_USE_LOGO}. + * + * @param resId Resource ID of a drawable to show as a logo. + * + * @see #setDisplayUseLogoEnabled(boolean) + * @see #setDisplayShowHomeEnabled(boolean) + */ + public abstract void setLogo(int resId); + + /** + * Set the logo to display in the 'home' section of the action bar. + * The action bar will use a logo specified by its style or the + * activity logo by default. + * + * Whether the home section shows an icon or logo is controlled + * by the display option {@link #DISPLAY_USE_LOGO}. + * + * @param logo Drawable to show as a logo. + * + * @see #setDisplayUseLogoEnabled(boolean) + * @see #setDisplayShowHomeEnabled(boolean) + */ + public abstract void setLogo(Drawable logo); + + /** + * Set the adapter and navigation callback for list navigation mode. + * + * The supplied adapter will provide views for the expanded list as well as + * the currently selected item. (These may be displayed differently.) + * + * The supplied OnNavigationListener will alert the application when the user + * changes the current list selection. + * + * @param adapter An adapter that will provide views both to display + * the current navigation selection and populate views + * within the dropdown navigation menu. + * @param callback An OnNavigationListener that will receive events when the user + * selects a navigation item. + */ + public abstract void setListNavigationCallbacks(SpinnerAdapter adapter, + OnNavigationListener callback); + + /** + * Set the selected navigation item in list or tabbed navigation modes. + * + * @param position Position of the item to select. + */ + public abstract void setSelectedNavigationItem(int position); + + /** + * Get the position of the selected navigation item in list or tabbed navigation modes. + * + * @return Position of the selected item. + */ + public abstract int getSelectedNavigationIndex(); + + /** + * Get the number of navigation items present in the current navigation mode. + * + * @return Number of navigation items. + */ + public abstract int getNavigationItemCount(); + + /** + * Set the action bar's title. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. + * + * @param title Title to set + * + * @see #setTitle(int) + * @see #setDisplayOptions(int, int) + */ + public abstract void setTitle(CharSequence title); + + /** + * Set the action bar's title. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. + * + * @param resId Resource ID of title string to set + * + * @see #setTitle(CharSequence) + * @see #setDisplayOptions(int, int) + */ + public abstract void setTitle(int resId); + + /** + * Set the action bar's subtitle. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. Set to null to disable the + * subtitle entirely. + * + * @param subtitle Subtitle to set + * + * @see #setSubtitle(int) + * @see #setDisplayOptions(int, int) + */ + public abstract void setSubtitle(CharSequence subtitle); + + /** + * Set the action bar's subtitle. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. + * + * @param resId Resource ID of subtitle string to set + * + * @see #setSubtitle(CharSequence) + * @see #setDisplayOptions(int, int) + */ + public abstract void setSubtitle(int resId); + + /** + * Set display options. This changes all display option bits at once. To change + * a limited subset of display options, see {@link #setDisplayOptions(int, int)}. + * + * @param options A combination of the bits defined by the DISPLAY_ constants + * defined in ActionBar. + */ + public abstract void setDisplayOptions(int options); + + /** + * Set selected display options. Only the options specified by mask will be changed. + * To change all display option bits at once, see {@link #setDisplayOptions(int)}. + * + *

Example: setDisplayOptions(0, DISPLAY_SHOW_HOME) will disable the + * {@link #DISPLAY_SHOW_HOME} option. + * setDisplayOptions(DISPLAY_SHOW_HOME, DISPLAY_SHOW_HOME | DISPLAY_USE_LOGO) + * will enable {@link #DISPLAY_SHOW_HOME} and disable {@link #DISPLAY_USE_LOGO}. + * + * @param options A combination of the bits defined by the DISPLAY_ constants + * defined in ActionBar. + * @param mask A bit mask declaring which display options should be changed. + */ + public abstract void setDisplayOptions(int options, int mask); + + /** + * Set whether to display the activity logo rather than the activity icon. + * A logo is often a wider, more detailed image. + * + *

To set several display options at once, see the setDisplayOptions methods. + * + * @param useLogo true to use the activity logo, false to use the activity icon. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public abstract void setDisplayUseLogoEnabled(boolean useLogo); + + /** + * Set whether to include the application home affordance in the action bar. + * Home is presented as either an activity icon or logo. + * + *

To set several display options at once, see the setDisplayOptions methods. + * + * @param showHome true to show home, false otherwise. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public abstract void setDisplayShowHomeEnabled(boolean showHome); + + /** + * Set whether home should be displayed as an "up" affordance. + * Set this to true if selecting "home" returns up by a single level in your UI + * rather than back to the top level or front page. + * + *

To set several display options at once, see the setDisplayOptions methods. + * + * @param showHomeAsUp true to show the user that selecting home will return one + * level up rather than to the top level of the app. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public abstract void setDisplayHomeAsUpEnabled(boolean showHomeAsUp); + + /** + * Set whether an activity title/subtitle should be displayed. + * + *

To set several display options at once, see the setDisplayOptions methods. + * + * @param showTitle true to display a title/subtitle if present. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public abstract void setDisplayShowTitleEnabled(boolean showTitle); + + /** + * Set whether a custom view should be displayed, if set. + * + *

To set several display options at once, see the setDisplayOptions methods. + * + * @param showCustom true if the currently set custom view should be displayed, false otherwise. + * + * @see #setDisplayOptions(int) + * @see #setDisplayOptions(int, int) + */ + public abstract void setDisplayShowCustomEnabled(boolean showCustom); + + /** + * Set the ActionBar's background. This will be used for the primary + * action bar. + * + * @param d Background drawable + * @see #setStackedBackgroundDrawable(Drawable) + * @see #setSplitBackgroundDrawable(Drawable) + */ + public abstract void setBackgroundDrawable(Drawable d); + + /** + * Set the ActionBar's stacked background. This will appear + * in the second row/stacked bar on some devices and configurations. + * + * @param d Background drawable for the stacked row + */ + public void setStackedBackgroundDrawable(Drawable d) { } + + /** + * Set the ActionBar's split background. This will appear in + * the split action bar containing menu-provided action buttons + * on some devices and configurations. + *

You can enable split action bar with {@link android.R.attr#uiOptions} + * + * @param d Background drawable for the split bar + */ + public void setSplitBackgroundDrawable(Drawable d) { } + + /** + * @return The current custom view. + */ + public abstract View getCustomView(); + + /** + * Returns the current ActionBar title in standard mode. + * Returns null if {@link #getNavigationMode()} would not return + * {@link #NAVIGATION_MODE_STANDARD}. + * + * @return The current ActionBar title or null. + */ + public abstract CharSequence getTitle(); + + /** + * Returns the current ActionBar subtitle in standard mode. + * Returns null if {@link #getNavigationMode()} would not return + * {@link #NAVIGATION_MODE_STANDARD}. + * + * @return The current ActionBar subtitle or null. + */ + public abstract CharSequence getSubtitle(); + + /** + * Returns the current navigation mode. The result will be one of: + *

    + *
  • {@link #NAVIGATION_MODE_STANDARD}
  • + *
  • {@link #NAVIGATION_MODE_LIST}
  • + *
  • {@link #NAVIGATION_MODE_TABS}
  • + *
+ * + * @return The current navigation mode. + */ + public abstract int getNavigationMode(); + + /** + * Set the current navigation mode. + * + * @param mode The new mode to set. + * @see #NAVIGATION_MODE_STANDARD + * @see #NAVIGATION_MODE_LIST + * @see #NAVIGATION_MODE_TABS + */ + public abstract void setNavigationMode(int mode); + + /** + * @return The current set of display options. + */ + public abstract int getDisplayOptions(); + + /** + * Create and return a new {@link com.actionbarsherlock.app.ActionBar.Tab}. + * This tab will not be included in the action bar until it is added. + * + *

Very often tabs will be used to switch between {@link Fragment} + * objects. Here is a typical implementation of such tabs:

+ * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java + * complete} + * + * @return A new Tab + * + * @see #addTab(com.actionbarsherlock.app.ActionBar.Tab) + */ + public abstract Tab newTab(); + + /** + * Add a tab for use in tabbed navigation mode. The tab will be added at the end of the list. + * If this is the first tab to be added it will become the selected tab. + * + * @param tab Tab to add + */ + public abstract void addTab(Tab tab); + + /** + * Add a tab for use in tabbed navigation mode. The tab will be added at the end of the list. + * + * @param tab Tab to add + * @param setSelected True if the added tab should become the selected tab. + */ + public abstract void addTab(Tab tab, boolean setSelected); + + /** + * Add a tab for use in tabbed navigation mode. The tab will be inserted at + * position. If this is the first tab to be added it will become + * the selected tab. + * + * @param tab The tab to add + * @param position The new position of the tab + */ + public abstract void addTab(Tab tab, int position); + + /** + * Add a tab for use in tabbed navigation mode. The tab will be insterted at + * position. + * + * @param tab The tab to add + * @param position The new position of the tab + * @param setSelected True if the added tab should become the selected tab. + */ + public abstract void addTab(Tab tab, int position, boolean setSelected); + + /** + * Remove a tab from the action bar. If the removed tab was selected it will be deselected + * and another tab will be selected if present. + * + * @param tab The tab to remove + */ + public abstract void removeTab(Tab tab); + + /** + * Remove a tab from the action bar. If the removed tab was selected it will be deselected + * and another tab will be selected if present. + * + * @param position Position of the tab to remove + */ + public abstract void removeTabAt(int position); + + /** + * Remove all tabs from the action bar and deselect the current tab. + */ + public abstract void removeAllTabs(); + + /** + * Select the specified tab. If it is not a child of this action bar it will be added. + * + *

Note: If you want to select by index, use {@link #setSelectedNavigationItem(int)}.

+ * + * @param tab Tab to select + */ + public abstract void selectTab(Tab tab); + + /** + * Returns the currently selected tab if in tabbed navigation mode and there is at least + * one tab present. + * + * @return The currently selected tab or null + */ + public abstract Tab getSelectedTab(); + + /** + * Returns the tab at the specified index. + * + * @param index Index value in the range 0-get + * @return + */ + public abstract Tab getTabAt(int index); + + /** + * Returns the number of tabs currently registered with the action bar. + * @return Tab count + */ + public abstract int getTabCount(); + + /** + * Retrieve the current height of the ActionBar. + * + * @return The ActionBar's height + */ + public abstract int getHeight(); + + /** + * Show the ActionBar if it is not currently showing. + * If the window hosting the ActionBar does not have the feature + * {@link Window#FEATURE_ACTION_BAR_OVERLAY} it will resize application + * content to fit the new space available. + */ + public abstract void show(); + + /** + * Hide the ActionBar if it is currently showing. + * If the window hosting the ActionBar does not have the feature + * {@link Window#FEATURE_ACTION_BAR_OVERLAY} it will resize application + * content to fit the new space available. + */ + public abstract void hide(); + + /** + * @return true if the ActionBar is showing, false otherwise. + */ + public abstract boolean isShowing(); + + /** + * Add a listener that will respond to menu visibility change events. + * + * @param listener The new listener to add + */ + public abstract void addOnMenuVisibilityListener(OnMenuVisibilityListener listener); + + /** + * Remove a menu visibility listener. This listener will no longer receive menu + * visibility change events. + * + * @param listener A listener to remove that was previously added + */ + public abstract void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener); + + /** + * Enable or disable the "home" button in the corner of the action bar. (Note that this + * is the application home/up affordance on the action bar, not the systemwide home + * button.) + * + *

This defaults to true for packages targeting < API 14. For packages targeting + * API 14 or greater, the application should call this method to enable interaction + * with the home/up affordance. + * + *

Setting the {@link #DISPLAY_HOME_AS_UP} display option will automatically enable + * the home button. + * + * @param enabled true to enable the home button, false to disable the home button. + */ + public void setHomeButtonEnabled(boolean enabled) { } + + /** + * Returns a {@link Context} with an appropriate theme for creating views that + * will appear in the action bar. If you are inflating or instantiating custom views + * that will appear in an action bar, you should use the Context returned by this method. + * (This includes adapters used for list navigation mode.) + * This will ensure that views contrast properly against the action bar. + * + * @return A themed Context for creating views + */ + public Context getThemedContext() { return null; } + + /** + * Listener interface for ActionBar navigation events. + */ + public interface OnNavigationListener { + /** + * This method is called whenever a navigation item in your action bar + * is selected. + * + * @param itemPosition Position of the item clicked. + * @param itemId ID of the item clicked. + * @return True if the event was handled, false otherwise. + */ + public boolean onNavigationItemSelected(int itemPosition, long itemId); + } + + /** + * Listener for receiving events when action bar menus are shown or hidden. + */ + public interface OnMenuVisibilityListener { + /** + * Called when an action bar menu is shown or hidden. Applications may want to use + * this to tune auto-hiding behavior for the action bar or pause/resume video playback, + * gameplay, or other activity within the main content area. + * + * @param isVisible True if an action bar menu is now visible, false if no action bar + * menus are visible. + */ + public void onMenuVisibilityChanged(boolean isVisible); + } + + /** + * A tab in the action bar. + * + *

Tabs manage the hiding and showing of {@link Fragment}s. + */ + public static abstract class Tab { + /** + * An invalid position for a tab. + * + * @see #getPosition() + */ + public static final int INVALID_POSITION = -1; + + /** + * Return the current position of this tab in the action bar. + * + * @return Current position, or {@link #INVALID_POSITION} if this tab is not currently in + * the action bar. + */ + public abstract int getPosition(); + + /** + * Return the icon associated with this tab. + * + * @return The tab's icon + */ + public abstract Drawable getIcon(); + + /** + * Return the text of this tab. + * + * @return The tab's text + */ + public abstract CharSequence getText(); + + /** + * Set the icon displayed on this tab. + * + * @param icon The drawable to use as an icon + * @return The current instance for call chaining + */ + public abstract Tab setIcon(Drawable icon); + + /** + * Set the icon displayed on this tab. + * + * @param resId Resource ID referring to the drawable to use as an icon + * @return The current instance for call chaining + */ + public abstract Tab setIcon(int resId); + + /** + * Set the text displayed on this tab. Text may be truncated if there is not + * room to display the entire string. + * + * @param text The text to display + * @return The current instance for call chaining + */ + public abstract Tab setText(CharSequence text); + + /** + * Set the text displayed on this tab. Text may be truncated if there is not + * room to display the entire string. + * + * @param resId A resource ID referring to the text that should be displayed + * @return The current instance for call chaining + */ + public abstract Tab setText(int resId); + + /** + * Set a custom view to be used for this tab. This overrides values set by + * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}. + * + * @param view Custom view to be used as a tab. + * @return The current instance for call chaining + */ + public abstract Tab setCustomView(View view); + + /** + * Set a custom view to be used for this tab. This overrides values set by + * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}. + * + * @param layoutResId A layout resource to inflate and use as a custom tab view + * @return The current instance for call chaining + */ + public abstract Tab setCustomView(int layoutResId); + + /** + * Retrieve a previously set custom view for this tab. + * + * @return The custom view set by {@link #setCustomView(View)}. + */ + public abstract View getCustomView(); + + /** + * Give this Tab an arbitrary object to hold for later use. + * + * @param obj Object to store + * @return The current instance for call chaining + */ + public abstract Tab setTag(Object obj); + + /** + * @return This Tab's tag object. + */ + public abstract Object getTag(); + + /** + * Set the {@link com.actionbarsherlock.app.ActionBar.TabListener} that will handle switching to and from this tab. + * All tabs must have a TabListener set before being added to the ActionBar. + * + * @param listener Listener to handle tab selection events + * @return The current instance for call chaining + */ + public abstract Tab setTabListener(TabListener listener); + + /** + * Select this tab. Only valid if the tab has been added to the action bar. + */ + public abstract void select(); + + /** + * Set a description of this tab's content for use in accessibility support. + * If no content description is provided the title will be used. + * + * @param resId A resource ID referring to the description text + * @return The current instance for call chaining + * @see #setContentDescription(CharSequence) + * @see #getContentDescription() + */ + public abstract Tab setContentDescription(int resId); + + /** + * Set a description of this tab's content for use in accessibility support. + * If no content description is provided the title will be used. + * + * @param contentDesc Description of this tab's content + * @return The current instance for call chaining + * @see #setContentDescription(int) + * @see #getContentDescription() + */ + public abstract Tab setContentDescription(CharSequence contentDesc); + + /** + * Gets a brief description of this tab's content for use in accessibility support. + * + * @return Description of this tab's content + * @see #setContentDescription(CharSequence) + * @see #setContentDescription(int) + */ + public abstract CharSequence getContentDescription(); + } + + /** + * Callback interface invoked when a tab is focused, unfocused, added, or removed. + */ + public interface TabListener { + /** + * Called when a tab enters the selected state. + * + * @param tab The tab that was selected + * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute + * during a tab switch. The previous tab's unselect and this tab's select will be + * executed in a single transaction. This FragmentTransaction does not support + * being added to the back stack. + */ + public void onTabSelected(Tab tab, FragmentTransaction ft); + + /** + * Called when a tab exits the selected state. + * + * @param tab The tab that was unselected + * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute + * during a tab switch. This tab's unselect and the newly selected tab's select + * will be executed in a single transaction. This FragmentTransaction does not + * support being added to the back stack. + */ + public void onTabUnselected(Tab tab, FragmentTransaction ft); + + /** + * Called when a tab that is already selected is chosen again by the user. + * Some applications may use this action to return to the top level of a category. + * + * @param tab The tab that was reselected. + * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute + * once this method returns. This FragmentTransaction does not support + * being added to the back stack. + */ + public void onTabReselected(Tab tab, FragmentTransaction ft); + } + + /** + * Per-child layout information associated with action bar custom views. + * + * @attr ref android.R.styleable#ActionBar_LayoutParams_layout_gravity + */ + public static class LayoutParams extends MarginLayoutParams { + private static final int[] ATTRS = new int[] { + android.R.attr.layout_gravity + }; + + /** + * Gravity for the view associated with these LayoutParams. + * + * @see android.view.Gravity + */ + @ViewDebug.ExportedProperty(mapping = { + @ViewDebug.IntToString(from = -1, to = "NONE"), + @ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"), + @ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"), + @ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"), + @ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"), + @ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"), + @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"), + @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"), + @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"), + @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL, to = "FILL_HORIZONTAL"), + @ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"), + @ViewDebug.IntToString(from = Gravity.FILL, to = "FILL") + }) + public int gravity = -1; + + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + + TypedArray a = c.obtainStyledAttributes(attrs, ATTRS); + gravity = a.getInt(0, -1); + a.recycle(); + } + + public LayoutParams(int width, int height) { + super(width, height); + this.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT; + } + + public LayoutParams(int width, int height, int gravity) { + super(width, height); + this.gravity = gravity; + } + + public LayoutParams(int gravity) { + this(WRAP_CONTENT, FILL_PARENT, gravity); + } + + public LayoutParams(LayoutParams source) { + super(source); + + this.gravity = source.gravity; + } + + public LayoutParams(ViewGroup.LayoutParams source) { + super(source); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockActivity.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockActivity.java new file mode 100644 index 0000000000..aa30254df6 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockActivity.java @@ -0,0 +1,270 @@ +package com.actionbarsherlock.app; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.view.Window; +import android.view.ViewGroup.LayoutParams; +import com.actionbarsherlock.ActionBarSherlock; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; +import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; +import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; +import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +public abstract class SherlockActivity extends Activity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { + private ActionBarSherlock mSherlock; + + protected final ActionBarSherlock getSherlock() { + if (mSherlock == null) { + mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); + } + return mSherlock; + } + + + /////////////////////////////////////////////////////////////////////////// + // Action bar and mode + /////////////////////////////////////////////////////////////////////////// + + public ActionBar getSupportActionBar() { + return getSherlock().getActionBar(); + } + + public ActionMode startActionMode(ActionMode.Callback callback) { + return getSherlock().startActionMode(callback); + } + + @Override + public void onActionModeStarted(ActionMode mode) {} + + @Override + public void onActionModeFinished(ActionMode mode) {} + + + /////////////////////////////////////////////////////////////////////////// + // General lifecycle/callback dispatching + /////////////////////////////////////////////////////////////////////////// + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + getSherlock().dispatchConfigurationChanged(newConfig); + } + + @Override + protected void onPostResume() { + super.onPostResume(); + getSherlock().dispatchPostResume(); + } + + @Override + protected void onPause() { + getSherlock().dispatchPause(); + super.onPause(); + } + + @Override + protected void onStop() { + getSherlock().dispatchStop(); + super.onStop(); + } + + @Override + protected void onDestroy() { + getSherlock().dispatchDestroy(); + super.onDestroy(); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + getSherlock().dispatchPostCreate(savedInstanceState); + super.onPostCreate(savedInstanceState); + } + + @Override + protected void onTitleChanged(CharSequence title, int color) { + getSherlock().dispatchTitleChanged(title, color); + super.onTitleChanged(title, color); + } + + @Override + public final boolean onMenuOpened(int featureId, android.view.Menu menu) { + if (getSherlock().dispatchMenuOpened(featureId, menu)) { + return true; + } + return super.onMenuOpened(featureId, menu); + } + + @Override + public void onPanelClosed(int featureId, android.view.Menu menu) { + getSherlock().dispatchPanelClosed(featureId, menu); + super.onPanelClosed(featureId, menu); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (getSherlock().dispatchKeyEvent(event)) { + return true; + } + return super.dispatchKeyEvent(event); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + getSherlock().dispatchSaveInstanceState(outState); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + getSherlock().dispatchRestoreInstanceState(savedInstanceState); + } + + /////////////////////////////////////////////////////////////////////////// + // Native menu handling + /////////////////////////////////////////////////////////////////////////// + + public MenuInflater getSupportMenuInflater() { + return getSherlock().getMenuInflater(); + } + + public void invalidateOptionsMenu() { + getSherlock().dispatchInvalidateOptionsMenu(); + } + + public void supportInvalidateOptionsMenu() { + invalidateOptionsMenu(); + } + + @Override + public final boolean onCreateOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchCreateOptionsMenu(menu); + } + + @Override + public final boolean onPrepareOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchPrepareOptionsMenu(menu); + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return getSherlock().dispatchOptionsItemSelected(item); + } + + @Override + public void openOptionsMenu() { + if (!getSherlock().dispatchOpenOptionsMenu()) { + super.openOptionsMenu(); + } + } + + @Override + public void closeOptionsMenu() { + if (!getSherlock().dispatchCloseOptionsMenu()) { + super.closeOptionsMenu(); + } + } + + + /////////////////////////////////////////////////////////////////////////// + // Sherlock menu handling + /////////////////////////////////////////////////////////////////////////// + + @Override + public boolean onCreatePanelMenu(int featureId, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onCreateOptionsMenu(menu); + } + return false; + } + + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onPreparePanel(int featureId, View view, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onPrepareOptionsMenu(menu); + } + return false; + } + + public boolean onPrepareOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onOptionsItemSelected(item); + } + return false; + } + + public boolean onOptionsItemSelected(MenuItem item) { + return false; + } + + + /////////////////////////////////////////////////////////////////////////// + // Content + /////////////////////////////////////////////////////////////////////////// + + @Override + public void addContentView(View view, LayoutParams params) { + getSherlock().addContentView(view, params); + } + + @Override + public void setContentView(int layoutResId) { + getSherlock().setContentView(layoutResId); + } + + @Override + public void setContentView(View view, LayoutParams params) { + getSherlock().setContentView(view, params); + } + + @Override + public void setContentView(View view) { + getSherlock().setContentView(view); + } + + public void requestWindowFeature(long featureId) { + getSherlock().requestFeature((int)featureId); + } + + + /////////////////////////////////////////////////////////////////////////// + // Progress Indication + /////////////////////////////////////////////////////////////////////////// + + public void setSupportProgress(int progress) { + getSherlock().setProgress(progress); + } + + public void setSupportProgressBarIndeterminate(boolean indeterminate) { + getSherlock().setProgressBarIndeterminate(indeterminate); + } + + public void setSupportProgressBarIndeterminateVisibility(boolean visible) { + getSherlock().setProgressBarIndeterminateVisibility(visible); + } + + public void setSupportProgressBarVisibility(boolean visible) { + getSherlock().setProgressBarVisibility(visible); + } + + public void setSupportSecondaryProgress(int secondaryProgress) { + getSherlock().setSecondaryProgress(secondaryProgress); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockDialogFragment.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockDialogFragment.java new file mode 100644 index 0000000000..a7c856bf02 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockDialogFragment.java @@ -0,0 +1,68 @@ +package com.actionbarsherlock.app; + +import android.app.Activity; +import android.support.v4.app.DialogFragment; +import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; +import com.actionbarsherlock.internal.view.menu.MenuWrapper; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; + +public class SherlockDialogFragment extends DialogFragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { + private SherlockFragmentActivity mActivity; + + public SherlockFragmentActivity getSherlockActivity() { + return mActivity; + } + + @Override + public void onAttach(Activity activity) { + if (!(activity instanceof SherlockFragmentActivity)) { + throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); + } + mActivity = (SherlockFragmentActivity)activity; + + super.onAttach(activity); + } + + @Override + public void onDetach() { + mActivity = null; + super.onDetach(); + } + + @Override + public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { + onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + //Nothing to see here. + } + + @Override + public final void onPrepareOptionsMenu(android.view.Menu menu) { + onPrepareOptionsMenu(new MenuWrapper(menu)); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + //Nothing to see here. + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return onOptionsItemSelected(new MenuItemWrapper(item)); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + //Nothing to see here. + return false; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java new file mode 100644 index 0000000000..de7dd40469 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java @@ -0,0 +1,259 @@ +package com.actionbarsherlock.app; + +import android.app.ExpandableListActivity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.view.Window; +import com.actionbarsherlock.ActionBarSherlock; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; +import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; +import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; +import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +public abstract class SherlockExpandableListActivity extends ExpandableListActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { + private ActionBarSherlock mSherlock; + + protected final ActionBarSherlock getSherlock() { + if (mSherlock == null) { + mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); + } + return mSherlock; + } + + + /////////////////////////////////////////////////////////////////////////// + // Action bar and mode + /////////////////////////////////////////////////////////////////////////// + + public ActionBar getSupportActionBar() { + return getSherlock().getActionBar(); + } + + public ActionMode startActionMode(ActionMode.Callback callback) { + return getSherlock().startActionMode(callback); + } + + @Override + public void onActionModeStarted(ActionMode mode) {} + + @Override + public void onActionModeFinished(ActionMode mode) {} + + + /////////////////////////////////////////////////////////////////////////// + // General lifecycle/callback dispatching + /////////////////////////////////////////////////////////////////////////// + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + getSherlock().dispatchConfigurationChanged(newConfig); + } + + @Override + protected void onPostResume() { + super.onPostResume(); + getSherlock().dispatchPostResume(); + } + + @Override + protected void onPause() { + getSherlock().dispatchPause(); + super.onPause(); + } + + @Override + protected void onStop() { + getSherlock().dispatchStop(); + super.onStop(); + } + + @Override + protected void onDestroy() { + getSherlock().dispatchDestroy(); + super.onDestroy(); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + getSherlock().dispatchPostCreate(savedInstanceState); + super.onPostCreate(savedInstanceState); + } + + @Override + protected void onTitleChanged(CharSequence title, int color) { + getSherlock().dispatchTitleChanged(title, color); + super.onTitleChanged(title, color); + } + + @Override + public final boolean onMenuOpened(int featureId, android.view.Menu menu) { + if (getSherlock().dispatchMenuOpened(featureId, menu)) { + return true; + } + return super.onMenuOpened(featureId, menu); + } + + @Override + public void onPanelClosed(int featureId, android.view.Menu menu) { + getSherlock().dispatchPanelClosed(featureId, menu); + super.onPanelClosed(featureId, menu); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (getSherlock().dispatchKeyEvent(event)) { + return true; + } + return super.dispatchKeyEvent(event); + } + + + /////////////////////////////////////////////////////////////////////////// + // Native menu handling + /////////////////////////////////////////////////////////////////////////// + + public MenuInflater getSupportMenuInflater() { + return getSherlock().getMenuInflater(); + } + + public void invalidateOptionsMenu() { + getSherlock().dispatchInvalidateOptionsMenu(); + } + + public void supportInvalidateOptionsMenu() { + invalidateOptionsMenu(); + } + + @Override + public final boolean onCreateOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchCreateOptionsMenu(menu); + } + + @Override + public final boolean onPrepareOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchPrepareOptionsMenu(menu); + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return getSherlock().dispatchOptionsItemSelected(item); + } + + @Override + public void openOptionsMenu() { + if (!getSherlock().dispatchOpenOptionsMenu()) { + super.openOptionsMenu(); + } + } + + @Override + public void closeOptionsMenu() { + if (!getSherlock().dispatchCloseOptionsMenu()) { + super.closeOptionsMenu(); + } + } + + + /////////////////////////////////////////////////////////////////////////// + // Sherlock menu handling + /////////////////////////////////////////////////////////////////////////// + + @Override + public boolean onCreatePanelMenu(int featureId, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onCreateOptionsMenu(menu); + } + return false; + } + + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onPreparePanel(int featureId, View view, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onPrepareOptionsMenu(menu); + } + return false; + } + + public boolean onPrepareOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onOptionsItemSelected(item); + } + return false; + } + + public boolean onOptionsItemSelected(MenuItem item) { + return false; + } + + + /////////////////////////////////////////////////////////////////////////// + // Content + /////////////////////////////////////////////////////////////////////////// + + @Override + public void addContentView(View view, LayoutParams params) { + getSherlock().addContentView(view, params); + } + + @Override + public void setContentView(int layoutResId) { + getSherlock().setContentView(layoutResId); + } + + @Override + public void setContentView(View view, LayoutParams params) { + getSherlock().setContentView(view, params); + } + + @Override + public void setContentView(View view) { + getSherlock().setContentView(view); + } + + public void requestWindowFeature(long featureId) { + getSherlock().requestFeature((int)featureId); + } + + + /////////////////////////////////////////////////////////////////////////// + // Progress Indication + /////////////////////////////////////////////////////////////////////////// + + public void setSupportProgress(int progress) { + getSherlock().setProgress(progress); + } + + public void setSupportProgressBarIndeterminate(boolean indeterminate) { + getSherlock().setProgressBarIndeterminate(indeterminate); + } + + public void setSupportProgressBarIndeterminateVisibility(boolean visible) { + getSherlock().setProgressBarIndeterminateVisibility(visible); + } + + public void setSupportProgressBarVisibility(boolean visible) { + getSherlock().setProgressBarVisibility(visible); + } + + public void setSupportSecondaryProgress(int secondaryProgress) { + getSherlock().setSecondaryProgress(secondaryProgress); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragment.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragment.java new file mode 100644 index 0000000000..0f24e9c856 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragment.java @@ -0,0 +1,68 @@ +package com.actionbarsherlock.app; + +import android.app.Activity; +import android.support.v4.app.Fragment; +import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; +import com.actionbarsherlock.internal.view.menu.MenuWrapper; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; + +public class SherlockFragment extends Fragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { + private SherlockFragmentActivity mActivity; + + public SherlockFragmentActivity getSherlockActivity() { + return mActivity; + } + + @Override + public void onAttach(Activity activity) { + if (!(activity instanceof SherlockFragmentActivity)) { + throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); + } + mActivity = (SherlockFragmentActivity)activity; + + super.onAttach(activity); + } + + @Override + public void onDetach() { + mActivity = null; + super.onDetach(); + } + + @Override + public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { + onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + //Nothing to see here. + } + + @Override + public final void onPrepareOptionsMenu(android.view.Menu menu) { + onPrepareOptionsMenu(new MenuWrapper(menu)); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + //Nothing to see here. + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return onOptionsItemSelected(new MenuItemWrapper(item)); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + //Nothing to see here. + return false; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragmentActivity.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragmentActivity.java new file mode 100644 index 0000000000..3d092f033a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockFragmentActivity.java @@ -0,0 +1,303 @@ +package com.actionbarsherlock.app; + +import android.content.res.Configuration; +import android.os.Bundle; +import android.support.v4.app.Watson; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.view.Window; +import com.actionbarsherlock.ActionBarSherlock; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +import static com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; +import static com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; + +/** @see {@link android.support.v4.app.Watson} */ +public class SherlockFragmentActivity extends Watson implements OnActionModeStartedListener, OnActionModeFinishedListener { + private static final boolean DEBUG = false; + private static final String TAG = "SherlockFragmentActivity"; + + private ActionBarSherlock mSherlock; + private boolean mIgnoreNativeCreate = false; + private boolean mIgnoreNativePrepare = false; + private boolean mIgnoreNativeSelected = false; + + protected final ActionBarSherlock getSherlock() { + if (mSherlock == null) { + mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); + } + return mSherlock; + } + + + /////////////////////////////////////////////////////////////////////////// + // Action bar and mode + /////////////////////////////////////////////////////////////////////////// + + public ActionBar getSupportActionBar() { + return getSherlock().getActionBar(); + } + + public ActionMode startActionMode(ActionMode.Callback callback) { + return getSherlock().startActionMode(callback); + } + + @Override + public void onActionModeStarted(ActionMode mode) {} + + @Override + public void onActionModeFinished(ActionMode mode) {} + + + /////////////////////////////////////////////////////////////////////////// + // General lifecycle/callback dispatching + /////////////////////////////////////////////////////////////////////////// + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + getSherlock().dispatchConfigurationChanged(newConfig); + } + + @Override + protected void onPostResume() { + super.onPostResume(); + getSherlock().dispatchPostResume(); + } + + @Override + protected void onPause() { + getSherlock().dispatchPause(); + super.onPause(); + } + + @Override + protected void onStop() { + getSherlock().dispatchStop(); + super.onStop(); + } + + @Override + protected void onDestroy() { + getSherlock().dispatchDestroy(); + super.onDestroy(); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + getSherlock().dispatchPostCreate(savedInstanceState); + super.onPostCreate(savedInstanceState); + } + + @Override + protected void onTitleChanged(CharSequence title, int color) { + getSherlock().dispatchTitleChanged(title, color); + super.onTitleChanged(title, color); + } + + @Override + public final boolean onMenuOpened(int featureId, android.view.Menu menu) { + if (getSherlock().dispatchMenuOpened(featureId, menu)) { + return true; + } + return super.onMenuOpened(featureId, menu); + } + + @Override + public void onPanelClosed(int featureId, android.view.Menu menu) { + getSherlock().dispatchPanelClosed(featureId, menu); + super.onPanelClosed(featureId, menu); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (getSherlock().dispatchKeyEvent(event)) { + return true; + } + return super.dispatchKeyEvent(event); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + getSherlock().dispatchSaveInstanceState(outState); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + getSherlock().dispatchRestoreInstanceState(savedInstanceState); + } + + /////////////////////////////////////////////////////////////////////////// + // Native menu handling + /////////////////////////////////////////////////////////////////////////// + + public MenuInflater getSupportMenuInflater() { + if (DEBUG) Log.d(TAG, "[getSupportMenuInflater]"); + + return getSherlock().getMenuInflater(); + } + + public void invalidateOptionsMenu() { + if (DEBUG) Log.d(TAG, "[invalidateOptionsMenu]"); + + getSherlock().dispatchInvalidateOptionsMenu(); + } + + public void supportInvalidateOptionsMenu() { + if (DEBUG) Log.d(TAG, "[supportInvalidateOptionsMenu]"); + + invalidateOptionsMenu(); + } + + @Override + public final boolean onCreatePanelMenu(int featureId, android.view.Menu menu) { + if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] featureId: " + featureId + ", menu: " + menu); + + if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativeCreate) { + mIgnoreNativeCreate = true; + boolean result = getSherlock().dispatchCreateOptionsMenu(menu); + mIgnoreNativeCreate = false; + + if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] returning " + result); + return result; + } + return super.onCreatePanelMenu(featureId, menu); + } + + @Override + public final boolean onCreateOptionsMenu(android.view.Menu menu) { + return true; + } + + @Override + public final boolean onPreparePanel(int featureId, View view, android.view.Menu menu) { + if (DEBUG) Log.d(TAG, "[onPreparePanel] featureId: " + featureId + ", view: " + view + ", menu: " + menu); + + if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativePrepare) { + mIgnoreNativePrepare = true; + boolean result = getSherlock().dispatchPrepareOptionsMenu(menu); + mIgnoreNativePrepare = false; + + if (DEBUG) Log.d(TAG, "[onPreparePanel] returning " + result); + return result; + } + return super.onPreparePanel(featureId, view, menu); + } + + @Override + public final boolean onPrepareOptionsMenu(android.view.Menu menu) { + return true; + } + + @Override + public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) { + if (DEBUG) Log.d(TAG, "[onMenuItemSelected] featureId: " + featureId + ", item: " + item); + + if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativeSelected) { + mIgnoreNativeSelected = true; + boolean result = getSherlock().dispatchOptionsItemSelected(item); + mIgnoreNativeSelected = false; + + if (DEBUG) Log.d(TAG, "[onMenuItemSelected] returning " + result); + return result; + } + return super.onMenuItemSelected(featureId, item); + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return false; + } + + @Override + public void openOptionsMenu() { + if (!getSherlock().dispatchOpenOptionsMenu()) { + super.openOptionsMenu(); + } + } + + @Override + public void closeOptionsMenu() { + if (!getSherlock().dispatchCloseOptionsMenu()) { + super.closeOptionsMenu(); + } + } + + + /////////////////////////////////////////////////////////////////////////// + // Sherlock menu handling + /////////////////////////////////////////////////////////////////////////// + + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + public boolean onPrepareOptionsMenu(Menu menu) { + return true; + } + + public boolean onOptionsItemSelected(MenuItem item) { + return false; + } + + + /////////////////////////////////////////////////////////////////////////// + // Content + /////////////////////////////////////////////////////////////////////////// + + @Override + public void addContentView(View view, LayoutParams params) { + getSherlock().addContentView(view, params); + } + + @Override + public void setContentView(int layoutResId) { + getSherlock().setContentView(layoutResId); + } + + @Override + public void setContentView(View view, LayoutParams params) { + getSherlock().setContentView(view, params); + } + + @Override + public void setContentView(View view) { + getSherlock().setContentView(view); + } + + public void requestWindowFeature(long featureId) { + getSherlock().requestFeature((int)featureId); + } + + + /////////////////////////////////////////////////////////////////////////// + // Progress Indication + /////////////////////////////////////////////////////////////////////////// + + public void setSupportProgress(int progress) { + getSherlock().setProgress(progress); + } + + public void setSupportProgressBarIndeterminate(boolean indeterminate) { + getSherlock().setProgressBarIndeterminate(indeterminate); + } + + public void setSupportProgressBarIndeterminateVisibility(boolean visible) { + getSherlock().setProgressBarIndeterminateVisibility(visible); + } + + public void setSupportProgressBarVisibility(boolean visible) { + getSherlock().setProgressBarVisibility(visible); + } + + public void setSupportSecondaryProgress(int secondaryProgress) { + getSherlock().setSecondaryProgress(secondaryProgress); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListActivity.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListActivity.java new file mode 100644 index 0000000000..29e05b6556 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListActivity.java @@ -0,0 +1,270 @@ +package com.actionbarsherlock.app; + +import android.app.ListActivity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.view.Window; +import android.view.ViewGroup.LayoutParams; +import com.actionbarsherlock.ActionBarSherlock; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; +import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; +import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; +import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +public abstract class SherlockListActivity extends ListActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { + private ActionBarSherlock mSherlock; + + protected final ActionBarSherlock getSherlock() { + if (mSherlock == null) { + mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); + } + return mSherlock; + } + + + /////////////////////////////////////////////////////////////////////////// + // Action bar and mode + /////////////////////////////////////////////////////////////////////////// + + public ActionBar getSupportActionBar() { + return getSherlock().getActionBar(); + } + + public ActionMode startActionMode(ActionMode.Callback callback) { + return getSherlock().startActionMode(callback); + } + + @Override + public void onActionModeStarted(ActionMode mode) {} + + @Override + public void onActionModeFinished(ActionMode mode) {} + + + /////////////////////////////////////////////////////////////////////////// + // General lifecycle/callback dispatching + /////////////////////////////////////////////////////////////////////////// + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + getSherlock().dispatchConfigurationChanged(newConfig); + } + + @Override + protected void onPostResume() { + super.onPostResume(); + getSherlock().dispatchPostResume(); + } + + @Override + protected void onPause() { + getSherlock().dispatchPause(); + super.onPause(); + } + + @Override + protected void onStop() { + getSherlock().dispatchStop(); + super.onStop(); + } + + @Override + protected void onDestroy() { + getSherlock().dispatchDestroy(); + super.onDestroy(); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + getSherlock().dispatchPostCreate(savedInstanceState); + super.onPostCreate(savedInstanceState); + } + + @Override + protected void onTitleChanged(CharSequence title, int color) { + getSherlock().dispatchTitleChanged(title, color); + super.onTitleChanged(title, color); + } + + @Override + public final boolean onMenuOpened(int featureId, android.view.Menu menu) { + if (getSherlock().dispatchMenuOpened(featureId, menu)) { + return true; + } + return super.onMenuOpened(featureId, menu); + } + + @Override + public void onPanelClosed(int featureId, android.view.Menu menu) { + getSherlock().dispatchPanelClosed(featureId, menu); + super.onPanelClosed(featureId, menu); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (getSherlock().dispatchKeyEvent(event)) { + return true; + } + return super.dispatchKeyEvent(event); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + getSherlock().dispatchSaveInstanceState(outState); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + getSherlock().dispatchRestoreInstanceState(savedInstanceState); + } + + /////////////////////////////////////////////////////////////////////////// + // Native menu handling + /////////////////////////////////////////////////////////////////////////// + + public MenuInflater getSupportMenuInflater() { + return getSherlock().getMenuInflater(); + } + + public void invalidateOptionsMenu() { + getSherlock().dispatchInvalidateOptionsMenu(); + } + + public void supportInvalidateOptionsMenu() { + invalidateOptionsMenu(); + } + + @Override + public final boolean onCreateOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchCreateOptionsMenu(menu); + } + + @Override + public final boolean onPrepareOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchPrepareOptionsMenu(menu); + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return getSherlock().dispatchOptionsItemSelected(item); + } + + @Override + public void openOptionsMenu() { + if (!getSherlock().dispatchOpenOptionsMenu()) { + super.openOptionsMenu(); + } + } + + @Override + public void closeOptionsMenu() { + if (!getSherlock().dispatchCloseOptionsMenu()) { + super.closeOptionsMenu(); + } + } + + + /////////////////////////////////////////////////////////////////////////// + // Sherlock menu handling + /////////////////////////////////////////////////////////////////////////// + + @Override + public boolean onCreatePanelMenu(int featureId, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onCreateOptionsMenu(menu); + } + return false; + } + + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onPreparePanel(int featureId, View view, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onPrepareOptionsMenu(menu); + } + return false; + } + + public boolean onPrepareOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onOptionsItemSelected(item); + } + return false; + } + + public boolean onOptionsItemSelected(MenuItem item) { + return false; + } + + + /////////////////////////////////////////////////////////////////////////// + // Content + /////////////////////////////////////////////////////////////////////////// + + @Override + public void addContentView(View view, LayoutParams params) { + getSherlock().addContentView(view, params); + } + + @Override + public void setContentView(int layoutResId) { + getSherlock().setContentView(layoutResId); + } + + @Override + public void setContentView(View view, LayoutParams params) { + getSherlock().setContentView(view, params); + } + + @Override + public void setContentView(View view) { + getSherlock().setContentView(view); + } + + public void requestWindowFeature(long featureId) { + getSherlock().requestFeature((int)featureId); + } + + + /////////////////////////////////////////////////////////////////////////// + // Progress Indication + /////////////////////////////////////////////////////////////////////////// + + public void setSupportProgress(int progress) { + getSherlock().setProgress(progress); + } + + public void setSupportProgressBarIndeterminate(boolean indeterminate) { + getSherlock().setProgressBarIndeterminate(indeterminate); + } + + public void setSupportProgressBarIndeterminateVisibility(boolean visible) { + getSherlock().setProgressBarIndeterminateVisibility(visible); + } + + public void setSupportProgressBarVisibility(boolean visible) { + getSherlock().setProgressBarVisibility(visible); + } + + public void setSupportSecondaryProgress(int secondaryProgress) { + getSherlock().setSecondaryProgress(secondaryProgress); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListFragment.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListFragment.java new file mode 100644 index 0000000000..13ca3c49fb --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockListFragment.java @@ -0,0 +1,68 @@ +package com.actionbarsherlock.app; + +import android.app.Activity; +import android.support.v4.app.ListFragment; +import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; +import com.actionbarsherlock.internal.view.menu.MenuWrapper; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; +import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; + +public class SherlockListFragment extends ListFragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { + private SherlockFragmentActivity mActivity; + + public SherlockFragmentActivity getSherlockActivity() { + return mActivity; + } + + @Override + public void onAttach(Activity activity) { + if (!(activity instanceof SherlockFragmentActivity)) { + throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); + } + mActivity = (SherlockFragmentActivity)activity; + + super.onAttach(activity); + } + + @Override + public void onDetach() { + mActivity = null; + super.onDetach(); + } + + @Override + public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { + onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + //Nothing to see here. + } + + @Override + public final void onPrepareOptionsMenu(android.view.Menu menu) { + onPrepareOptionsMenu(new MenuWrapper(menu)); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + //Nothing to see here. + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return onOptionsItemSelected(new MenuItemWrapper(item)); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + //Nothing to see here. + return false; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java new file mode 100644 index 0000000000..a36f771097 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java @@ -0,0 +1,270 @@ +package com.actionbarsherlock.app; + +import android.content.res.Configuration; +import android.os.Bundle; +import android.preference.PreferenceActivity; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.view.Window; +import com.actionbarsherlock.ActionBarSherlock; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; +import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; +import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; +import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; +import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +public abstract class SherlockPreferenceActivity extends PreferenceActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { + private ActionBarSherlock mSherlock; + + protected final ActionBarSherlock getSherlock() { + if (mSherlock == null) { + mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); + } + return mSherlock; + } + + + /////////////////////////////////////////////////////////////////////////// + // Action bar and mode + /////////////////////////////////////////////////////////////////////////// + + public ActionBar getSupportActionBar() { + return getSherlock().getActionBar(); + } + + public ActionMode startActionMode(ActionMode.Callback callback) { + return getSherlock().startActionMode(callback); + } + + @Override + public void onActionModeStarted(ActionMode mode) {} + + @Override + public void onActionModeFinished(ActionMode mode) {} + + + /////////////////////////////////////////////////////////////////////////// + // General lifecycle/callback dispatching + /////////////////////////////////////////////////////////////////////////// + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + getSherlock().dispatchConfigurationChanged(newConfig); + } + + @Override + protected void onPostResume() { + super.onPostResume(); + getSherlock().dispatchPostResume(); + } + + @Override + protected void onPause() { + getSherlock().dispatchPause(); + super.onPause(); + } + + @Override + protected void onStop() { + getSherlock().dispatchStop(); + super.onStop(); + } + + @Override + protected void onDestroy() { + getSherlock().dispatchDestroy(); + super.onDestroy(); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + getSherlock().dispatchPostCreate(savedInstanceState); + super.onPostCreate(savedInstanceState); + } + + @Override + protected void onTitleChanged(CharSequence title, int color) { + getSherlock().dispatchTitleChanged(title, color); + super.onTitleChanged(title, color); + } + + @Override + public final boolean onMenuOpened(int featureId, android.view.Menu menu) { + if (getSherlock().dispatchMenuOpened(featureId, menu)) { + return true; + } + return super.onMenuOpened(featureId, menu); + } + + @Override + public void onPanelClosed(int featureId, android.view.Menu menu) { + getSherlock().dispatchPanelClosed(featureId, menu); + super.onPanelClosed(featureId, menu); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (getSherlock().dispatchKeyEvent(event)) { + return true; + } + return super.dispatchKeyEvent(event); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + getSherlock().dispatchSaveInstanceState(outState); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + getSherlock().dispatchRestoreInstanceState(savedInstanceState); + } + + /////////////////////////////////////////////////////////////////////////// + // Native menu handling + /////////////////////////////////////////////////////////////////////////// + + public MenuInflater getSupportMenuInflater() { + return getSherlock().getMenuInflater(); + } + + public void invalidateOptionsMenu() { + getSherlock().dispatchInvalidateOptionsMenu(); + } + + public void supportInvalidateOptionsMenu() { + invalidateOptionsMenu(); + } + + @Override + public final boolean onCreateOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchCreateOptionsMenu(menu); + } + + @Override + public final boolean onPrepareOptionsMenu(android.view.Menu menu) { + return getSherlock().dispatchPrepareOptionsMenu(menu); + } + + @Override + public final boolean onOptionsItemSelected(android.view.MenuItem item) { + return getSherlock().dispatchOptionsItemSelected(item); + } + + @Override + public void openOptionsMenu() { + if (!getSherlock().dispatchOpenOptionsMenu()) { + super.openOptionsMenu(); + } + } + + @Override + public void closeOptionsMenu() { + if (!getSherlock().dispatchCloseOptionsMenu()) { + super.closeOptionsMenu(); + } + } + + + /////////////////////////////////////////////////////////////////////////// + // Sherlock menu handling + /////////////////////////////////////////////////////////////////////////// + + @Override + public boolean onCreatePanelMenu(int featureId, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onCreateOptionsMenu(menu); + } + return false; + } + + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onPreparePanel(int featureId, View view, Menu menu) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onPrepareOptionsMenu(menu); + } + return false; + } + + public boolean onPrepareOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + if (featureId == Window.FEATURE_OPTIONS_PANEL) { + return onOptionsItemSelected(item); + } + return false; + } + + public boolean onOptionsItemSelected(MenuItem item) { + return false; + } + + + /////////////////////////////////////////////////////////////////////////// + // Content + /////////////////////////////////////////////////////////////////////////// + + @Override + public void addContentView(View view, LayoutParams params) { + getSherlock().addContentView(view, params); + } + + @Override + public void setContentView(int layoutResId) { + getSherlock().setContentView(layoutResId); + } + + @Override + public void setContentView(View view, LayoutParams params) { + getSherlock().setContentView(view, params); + } + + @Override + public void setContentView(View view) { + getSherlock().setContentView(view); + } + + public void requestWindowFeature(long featureId) { + getSherlock().requestFeature((int)featureId); + } + + + /////////////////////////////////////////////////////////////////////////// + // Progress Indication + /////////////////////////////////////////////////////////////////////////// + + public void setSupportProgress(int progress) { + getSherlock().setProgress(progress); + } + + public void setSupportProgressBarIndeterminate(boolean indeterminate) { + getSherlock().setProgressBarIndeterminate(indeterminate); + } + + public void setSupportProgressBarIndeterminateVisibility(boolean visible) { + getSherlock().setProgressBarIndeterminateVisibility(visible); + } + + public void setSupportProgressBarVisibility(boolean visible) { + getSherlock().setProgressBarVisibility(visible); + } + + public void setSupportSecondaryProgress(int secondaryProgress) { + getSherlock().setSecondaryProgress(secondaryProgress); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java new file mode 100644 index 0000000000..5e69275c7c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java @@ -0,0 +1,1203 @@ +package com.actionbarsherlock.internal; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.xmlpull.v1.XmlPullParser; +import android.app.Activity; +import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.res.AssetManager; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.os.Bundle; +import android.util.AndroidRuntimeException; +import android.util.Log; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewStub; +import android.view.Window; +import android.view.accessibility.AccessibilityEvent; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.FrameLayout; +import android.widget.TextView; +import com.actionbarsherlock.ActionBarSherlock; +import com.actionbarsherlock.R; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.internal.app.ActionBarImpl; +import com.actionbarsherlock.internal.view.StandaloneActionMode; +import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; +import com.actionbarsherlock.internal.view.menu.MenuBuilder; +import com.actionbarsherlock.internal.view.menu.MenuItemImpl; +import com.actionbarsherlock.internal.view.menu.MenuPresenter; +import com.actionbarsherlock.internal.widget.ActionBarContainer; +import com.actionbarsherlock.internal.widget.ActionBarContextView; +import com.actionbarsherlock.internal.widget.ActionBarView; +import com.actionbarsherlock.internal.widget.IcsProgressBar; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; + +@ActionBarSherlock.Implementation(api = 7) +public class ActionBarSherlockCompat extends ActionBarSherlock implements MenuBuilder.Callback, com.actionbarsherlock.view.Window.Callback, MenuPresenter.Callback, android.view.MenuItem.OnMenuItemClickListener { + /** Window features which are enabled by default. */ + protected static final int DEFAULT_FEATURES = 0; + + static private final String PANELS_TAG = "sherlock:Panels"; + + public ActionBarSherlockCompat(Activity activity, int flags) { + super(activity, flags); + } + + + /////////////////////////////////////////////////////////////////////////// + // Properties + /////////////////////////////////////////////////////////////////////////// + + /** Whether or not the device has a dedicated menu key button. */ + private boolean mReserveOverflow; + /** Lazy-load indicator for {@link #mReserveOverflow}. */ + private boolean mReserveOverflowSet = false; + + /** Current menu instance for managing action items. */ + private MenuBuilder mMenu; + /** Map between native options items and sherlock items. */ + protected HashMap mNativeItemMap; + + /** Parent view of the window decoration (action bar, mode, etc.). */ + private ViewGroup mDecor; + /** Parent view of the activity content. */ + private ViewGroup mContentParent; + + /** Whether or not the title is stable and can be displayed. */ + private boolean mIsTitleReady = false; + /** Whether or not the parent activity has been destroyed. */ + private boolean mIsDestroyed = false; + + /* Emulate PanelFeatureState */ + private boolean mClosingActionMenu; + private boolean mMenuIsPrepared; + private boolean mMenuRefreshContent; + private Bundle mMenuFrozenActionViewState; + + /** Implementation which backs the action bar interface API. */ + private ActionBarImpl aActionBar; + /** Main action bar view which displays the core content. */ + private ActionBarView wActionBar; + /** Relevant window and action bar features flags. */ + private int mFeatures = DEFAULT_FEATURES; + /** Relevant user interface option flags. */ + private int mUiOptions = 0; + + /** Decor indeterminate progress indicator. */ + private IcsProgressBar mCircularProgressBar; + /** Decor progress indicator. */ + private IcsProgressBar mHorizontalProgressBar; + + /** Current displayed context action bar, if any. */ + private ActionMode mActionMode; + /** Parent view in which the context action bar is displayed. */ + private ActionBarContextView mActionModeView; + + /** Title view used with dialogs. */ + private TextView mTitleView; + /** Current activity title. */ + private CharSequence mTitle = null; + /** Whether or not this "activity" is floating (i.e., a dialog) */ + private boolean mIsFloating; + + + + /////////////////////////////////////////////////////////////////////////// + // Instance methods + /////////////////////////////////////////////////////////////////////////// + + @Override + public ActionBar getActionBar() { + if (DEBUG) Log.d(TAG, "[getActionBar]"); + + initActionBar(); + return aActionBar; + } + + private void initActionBar() { + if (DEBUG) Log.d(TAG, "[initActionBar]"); + + // Initializing the window decor can change window feature flags. + // Make sure that we have the correct set before performing the test below. + if (mDecor == null) { + installDecor(); + } + + if ((aActionBar != null) || !hasFeature(Window.FEATURE_ACTION_BAR) || hasFeature(Window.FEATURE_NO_TITLE) || mActivity.isChild()) { + return; + } + + aActionBar = new ActionBarImpl(mActivity, mFeatures); + + if (!mIsDelegate) { + //We may never get another chance to set the title + wActionBar.setWindowTitle(mActivity.getTitle()); + } + } + + @Override + protected Context getThemedContext() { + return aActionBar.getThemedContext(); + } + + @Override + public void setTitle(CharSequence title) { + if (DEBUG) Log.d(TAG, "[setTitle] title: " + title); + + dispatchTitleChanged(title, 0); + } + + @Override + public ActionMode startActionMode(ActionMode.Callback callback) { + if (DEBUG) Log.d(TAG, "[startActionMode] callback: " + callback); + + if (mActionMode != null) { + mActionMode.finish(); + } + + final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback); + ActionMode mode = null; + + //Emulate Activity's onWindowStartingActionMode: + initActionBar(); + if (aActionBar != null) { + mode = aActionBar.startActionMode(wrappedCallback); + } + + if (mode != null) { + mActionMode = mode; + } else { + if (mActionModeView == null) { + ViewStub stub = (ViewStub)mDecor.findViewById(R.id.abs__action_mode_bar_stub); + if (stub != null) { + mActionModeView = (ActionBarContextView)stub.inflate(); + } + } + if (mActionModeView != null) { + mActionModeView.killMode(); + mode = new StandaloneActionMode(mActivity, mActionModeView, wrappedCallback, true); + if (callback.onCreateActionMode(mode, mode.getMenu())) { + mode.invalidate(); + mActionModeView.initForMode(mode); + mActionModeView.setVisibility(View.VISIBLE); + mActionMode = mode; + mActionModeView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + } else { + mActionMode = null; + } + } + } + if (mActionMode != null && mActivity instanceof OnActionModeStartedListener) { + ((OnActionModeStartedListener)mActivity).onActionModeStarted(mActionMode); + } + return mActionMode; + } + + + /////////////////////////////////////////////////////////////////////////// + // Lifecycle and interaction callbacks for delegation + /////////////////////////////////////////////////////////////////////////// + + @Override + public void dispatchConfigurationChanged(Configuration newConfig) { + if (DEBUG) Log.d(TAG, "[dispatchConfigurationChanged] newConfig: " + newConfig); + + if (aActionBar != null) { + aActionBar.onConfigurationChanged(newConfig); + } + } + + @Override + public void dispatchPostResume() { + if (DEBUG) Log.d(TAG, "[dispatchPostResume]"); + + if (aActionBar != null) { + aActionBar.setShowHideAnimationEnabled(true); + } + } + + @Override + public void dispatchPause() { + if (DEBUG) Log.d(TAG, "[dispatchPause]"); + + if (wActionBar != null && wActionBar.isOverflowMenuShowing()) { + wActionBar.hideOverflowMenu(); + } + } + + @Override + public void dispatchStop() { + if (DEBUG) Log.d(TAG, "[dispatchStop]"); + + if (aActionBar != null) { + aActionBar.setShowHideAnimationEnabled(false); + } + } + + @Override + public void dispatchInvalidateOptionsMenu() { + if (DEBUG) Log.d(TAG, "[dispatchInvalidateOptionsMenu]"); + + Bundle savedActionViewStates = null; + if (mMenu != null) { + savedActionViewStates = new Bundle(); + mMenu.saveActionViewStates(savedActionViewStates); + if (savedActionViewStates.size() > 0) { + mMenuFrozenActionViewState = savedActionViewStates; + } + // This will be started again when the panel is prepared. + mMenu.stopDispatchingItemsChanged(); + mMenu.clear(); + } + mMenuRefreshContent = true; + + // Prepare the options panel if we have an action bar + if (wActionBar != null) { + mMenuIsPrepared = false; + preparePanel(); + } + } + + @Override + public boolean dispatchOpenOptionsMenu() { + if (DEBUG) Log.d(TAG, "[dispatchOpenOptionsMenu]"); + + if (!isReservingOverflow()) { + return false; + } + + return wActionBar.showOverflowMenu(); + } + + @Override + public boolean dispatchCloseOptionsMenu() { + if (DEBUG) Log.d(TAG, "[dispatchCloseOptionsMenu]"); + + if (!isReservingOverflow()) { + return false; + } + + if (wActionBar != null) { + return wActionBar.hideOverflowMenu(); + } + return false; + } + + @Override + public void dispatchPostCreate(Bundle savedInstanceState) { + if (DEBUG) Log.d(TAG, "[dispatchOnPostCreate]"); + + if (mIsDelegate) { + mIsTitleReady = true; + } + + if (mDecor == null) { + initActionBar(); + } + } + + @Override + public boolean dispatchCreateOptionsMenu(android.view.Menu menu) { + if (DEBUG) { + Log.d(TAG, "[dispatchCreateOptionsMenu] android.view.Menu: " + menu); + Log.d(TAG, "[dispatchCreateOptionsMenu] returning true"); + } + return true; + } + + @Override + public boolean dispatchPrepareOptionsMenu(android.view.Menu menu) { + if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] android.view.Menu: " + menu); + + if (mActionMode != null) { + return false; + } + + mMenuIsPrepared = false; + if (!preparePanel()) { + return false; + } + + if (isReservingOverflow()) { + return false; + } + + if (mNativeItemMap == null) { + mNativeItemMap = new HashMap(); + } else { + mNativeItemMap.clear(); + } + + if (mMenu == null) { + return false; + } + + boolean result = mMenu.bindNativeOverflow(menu, this, mNativeItemMap); + if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] returning " + result); + return result; + } + + @Override + public boolean dispatchOptionsItemSelected(android.view.MenuItem item) { + throw new IllegalStateException("Native callback invoked. Create a test case and report!"); + } + + @Override + public boolean dispatchMenuOpened(int featureId, android.view.Menu menu) { + if (DEBUG) Log.d(TAG, "[dispatchMenuOpened] featureId: " + featureId + ", menu: " + menu); + + if (featureId == Window.FEATURE_ACTION_BAR || featureId == Window.FEATURE_OPTIONS_PANEL) { + if (aActionBar != null) { + aActionBar.dispatchMenuVisibilityChanged(true); + } + return true; + } + + return false; + } + + @Override + public void dispatchPanelClosed(int featureId, android.view.Menu menu){ + if (DEBUG) Log.d(TAG, "[dispatchPanelClosed] featureId: " + featureId + ", menu: " + menu); + + if (featureId == Window.FEATURE_ACTION_BAR || featureId == Window.FEATURE_OPTIONS_PANEL) { + if (aActionBar != null) { + aActionBar.dispatchMenuVisibilityChanged(false); + } + } + } + + @Override + public void dispatchTitleChanged(CharSequence title, int color) { + if (DEBUG) Log.d(TAG, "[dispatchTitleChanged] title: " + title + ", color: " + color); + + if (!mIsDelegate || mIsTitleReady) { + if (mTitleView != null) { + mTitleView.setText(title); + } else if (wActionBar != null) { + wActionBar.setWindowTitle(title); + } + } + + mTitle = title; + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] event: " + event); + + final int keyCode = event.getKeyCode(); + + // Not handled by the view hierarchy, does the action bar want it + // to cancel out of something special? + if (keyCode == KeyEvent.KEYCODE_BACK) { + final int action = event.getAction(); + // Back cancels action modes first. + if (mActionMode != null) { + if (action == KeyEvent.ACTION_UP) { + mActionMode.finish(); + } + if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning true"); + return true; + } + + // Next collapse any expanded action views. + if (wActionBar != null && wActionBar.hasExpandedActionView()) { + if (action == KeyEvent.ACTION_UP) { + wActionBar.collapseActionView(); + } + if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning true"); + return true; + } + } + + if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning false"); + return false; + } + + @Override + public void dispatchDestroy() { + mIsDestroyed = true; + } + + @Override + public void dispatchSaveInstanceState(Bundle outState) { + if (mMenu != null) { + mMenuFrozenActionViewState = new Bundle(); + mMenu.saveActionViewStates(mMenuFrozenActionViewState); + } + outState.putParcelable(PANELS_TAG, mMenuFrozenActionViewState); + } + + @Override + public void dispatchRestoreInstanceState(Bundle savedInstanceState) { + mMenuFrozenActionViewState = savedInstanceState.getParcelable(PANELS_TAG); + } + + /////////////////////////////////////////////////////////////////////////// + // Menu callback lifecycle and creation + /////////////////////////////////////////////////////////////////////////// + + private boolean preparePanel() { + // Already prepared (isPrepared will be reset to false later) + if (mMenuIsPrepared) { + return true; + } + + // Init the panel state's menu--return false if init failed + if (mMenu == null || mMenuRefreshContent) { + if (mMenu == null) { + if (!initializePanelMenu() || (mMenu == null)) { + return false; + } + } + + if (wActionBar != null) { + wActionBar.setMenu(mMenu, this); + } + + // Call callback, and return if it doesn't want to display menu. + + // Creating the panel menu will involve a lot of manipulation; + // don't dispatch change events to presenters until we're done. + mMenu.stopDispatchingItemsChanged(); + if (!callbackCreateOptionsMenu(mMenu)) { + // Ditch the menu created above + mMenu = null; + + if (wActionBar != null) { + // Don't show it in the action bar either + wActionBar.setMenu(null, this); + } + + return false; + } + + mMenuRefreshContent = false; + } + + // Callback and return if the callback does not want to show the menu + + // Preparing the panel menu can involve a lot of manipulation; + // don't dispatch change events to presenters until we're done. + mMenu.stopDispatchingItemsChanged(); + + // Restore action view state before we prepare. This gives apps + // an opportunity to override frozen/restored state in onPrepare. + if (mMenuFrozenActionViewState != null) { + mMenu.restoreActionViewStates(mMenuFrozenActionViewState); + mMenuFrozenActionViewState = null; + } + + if (!callbackPrepareOptionsMenu(mMenu)) { + if (wActionBar != null) { + // The app didn't want to show the menu for now but it still exists. + // Clear it out of the action bar. + wActionBar.setMenu(null, this); + } + mMenu.startDispatchingItemsChanged(); + return false; + } + + // Set the proper keymap + KeyCharacterMap kmap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); + mMenu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC); + mMenu.startDispatchingItemsChanged(); + + // Set other state + mMenuIsPrepared = true; + + return true; + } + + public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { + return callbackOptionsItemSelected(item); + } + + public void onMenuModeChange(MenuBuilder menu) { + reopenMenu(true); + } + + private void reopenMenu(boolean toggleMenuMode) { + if (wActionBar != null && wActionBar.isOverflowReserved()) { + if (!wActionBar.isOverflowMenuShowing() || !toggleMenuMode) { + if (wActionBar.getVisibility() == View.VISIBLE) { + if (callbackPrepareOptionsMenu(mMenu)) { + wActionBar.showOverflowMenu(); + } + } + } else { + wActionBar.hideOverflowMenu(); + } + return; + } + } + + private boolean initializePanelMenu() { + Context context = mActivity;//getContext(); + + // If we have an action bar, initialize the menu with a context themed for it. + if (wActionBar != null) { + TypedValue outValue = new TypedValue(); + Resources.Theme currentTheme = context.getTheme(); + currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme, + outValue, true); + final int targetThemeRes = outValue.resourceId; + + if (targetThemeRes != 0 /*&& context.getThemeResId() != targetThemeRes*/) { + context = new ContextThemeWrapper(context, targetThemeRes); + } + } + + mMenu = new MenuBuilder(context); + mMenu.setCallback(this); + + return true; + } + + void checkCloseActionMenu(Menu menu) { + if (mClosingActionMenu) { + return; + } + + mClosingActionMenu = true; + wActionBar.dismissPopupMenus(); + //Callback cb = getCallback(); + //if (cb != null && !isDestroyed()) { + // cb.onPanelClosed(FEATURE_ACTION_BAR, menu); + //} + mClosingActionMenu = false; + } + + @Override + public boolean onOpenSubMenu(MenuBuilder subMenu) { + return true; + } + + @Override + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + checkCloseActionMenu(menu); + } + + @Override + public boolean onMenuItemClick(android.view.MenuItem item) { + if (DEBUG) Log.d(TAG, "[mNativeItemListener.onMenuItemClick] item: " + item); + + final MenuItemImpl sherlockItem = mNativeItemMap.get(item); + if (sherlockItem != null) { + sherlockItem.invoke(); + } else { + Log.e(TAG, "Options item \"" + item + "\" not found in mapping"); + } + + return true; //Do not allow continuation of native handling + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + return callbackOptionsItemSelected(item); + } + + + /////////////////////////////////////////////////////////////////////////// + // Progress bar interaction and internal handling + /////////////////////////////////////////////////////////////////////////// + + @Override + public void setProgressBarVisibility(boolean visible) { + if (DEBUG) Log.d(TAG, "[setProgressBarVisibility] visible: " + visible); + + setFeatureInt(Window.FEATURE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON : + Window.PROGRESS_VISIBILITY_OFF); + } + + @Override + public void setProgressBarIndeterminateVisibility(boolean visible) { + if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminateVisibility] visible: " + visible); + + setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, + visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF); + } + + @Override + public void setProgressBarIndeterminate(boolean indeterminate) { + if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminate] indeterminate: " + indeterminate); + + setFeatureInt(Window.FEATURE_PROGRESS, + indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF); + } + + @Override + public void setProgress(int progress) { + if (DEBUG) Log.d(TAG, "[setProgress] progress: " + progress); + + setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START); + } + + @Override + public void setSecondaryProgress(int secondaryProgress) { + if (DEBUG) Log.d(TAG, "[setSecondaryProgress] secondaryProgress: " + secondaryProgress); + + setFeatureInt(Window.FEATURE_PROGRESS, + secondaryProgress + Window.PROGRESS_SECONDARY_START); + } + + private void setFeatureInt(int featureId, int value) { + updateInt(featureId, value, false); + } + + private void updateInt(int featureId, int value, boolean fromResume) { + // Do nothing if the decor is not yet installed... an update will + // need to be forced when we eventually become active. + if (mContentParent == null) { + return; + } + + final int featureMask = 1 << featureId; + + if ((getFeatures() & featureMask) == 0 && !fromResume) { + return; + } + + onIntChanged(featureId, value); + } + + private void onIntChanged(int featureId, int value) { + if (featureId == Window.FEATURE_PROGRESS || featureId == Window.FEATURE_INDETERMINATE_PROGRESS) { + updateProgressBars(value); + } + } + + private void updateProgressBars(int value) { + IcsProgressBar circularProgressBar = getCircularProgressBar(true); + IcsProgressBar horizontalProgressBar = getHorizontalProgressBar(true); + + final int features = mFeatures;//getLocalFeatures(); + if (value == Window.PROGRESS_VISIBILITY_ON) { + if ((features & (1 << Window.FEATURE_PROGRESS)) != 0) { + int level = horizontalProgressBar.getProgress(); + int visibility = (horizontalProgressBar.isIndeterminate() || level < 10000) ? + View.VISIBLE : View.INVISIBLE; + horizontalProgressBar.setVisibility(visibility); + } + if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0) { + circularProgressBar.setVisibility(View.VISIBLE); + } + } else if (value == Window.PROGRESS_VISIBILITY_OFF) { + if ((features & (1 << Window.FEATURE_PROGRESS)) != 0) { + horizontalProgressBar.setVisibility(View.GONE); + } + if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0) { + circularProgressBar.setVisibility(View.GONE); + } + } else if (value == Window.PROGRESS_INDETERMINATE_ON) { + horizontalProgressBar.setIndeterminate(true); + } else if (value == Window.PROGRESS_INDETERMINATE_OFF) { + horizontalProgressBar.setIndeterminate(false); + } else if (Window.PROGRESS_START <= value && value <= Window.PROGRESS_END) { + // We want to set the progress value before testing for visibility + // so that when the progress bar becomes visible again, it has the + // correct level. + horizontalProgressBar.setProgress(value - Window.PROGRESS_START); + + if (value < Window.PROGRESS_END) { + showProgressBars(horizontalProgressBar, circularProgressBar); + } else { + hideProgressBars(horizontalProgressBar, circularProgressBar); + } + } else if (Window.PROGRESS_SECONDARY_START <= value && value <= Window.PROGRESS_SECONDARY_END) { + horizontalProgressBar.setSecondaryProgress(value - Window.PROGRESS_SECONDARY_START); + + showProgressBars(horizontalProgressBar, circularProgressBar); + } + } + + private void showProgressBars(IcsProgressBar horizontalProgressBar, IcsProgressBar spinnyProgressBar) { + final int features = mFeatures;//getLocalFeatures(); + if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0 && + spinnyProgressBar.getVisibility() == View.INVISIBLE) { + spinnyProgressBar.setVisibility(View.VISIBLE); + } + // Only show the progress bars if the primary progress is not complete + if ((features & (1 << Window.FEATURE_PROGRESS)) != 0 && + horizontalProgressBar.getProgress() < 10000) { + horizontalProgressBar.setVisibility(View.VISIBLE); + } + } + + private void hideProgressBars(IcsProgressBar horizontalProgressBar, IcsProgressBar spinnyProgressBar) { + final int features = mFeatures;//getLocalFeatures(); + Animation anim = AnimationUtils.loadAnimation(mActivity, android.R.anim.fade_out); + anim.setDuration(1000); + if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0 && + spinnyProgressBar.getVisibility() == View.VISIBLE) { + spinnyProgressBar.startAnimation(anim); + spinnyProgressBar.setVisibility(View.INVISIBLE); + } + if ((features & (1 << Window.FEATURE_PROGRESS)) != 0 && + horizontalProgressBar.getVisibility() == View.VISIBLE) { + horizontalProgressBar.startAnimation(anim); + horizontalProgressBar.setVisibility(View.INVISIBLE); + } + } + + private IcsProgressBar getCircularProgressBar(boolean shouldInstallDecor) { + if (mCircularProgressBar != null) { + return mCircularProgressBar; + } + if (mContentParent == null && shouldInstallDecor) { + installDecor(); + } + mCircularProgressBar = (IcsProgressBar)mDecor.findViewById(R.id.abs__progress_circular); + if (mCircularProgressBar != null) { + mCircularProgressBar.setVisibility(View.INVISIBLE); + } + return mCircularProgressBar; + } + + private IcsProgressBar getHorizontalProgressBar(boolean shouldInstallDecor) { + if (mHorizontalProgressBar != null) { + return mHorizontalProgressBar; + } + if (mContentParent == null && shouldInstallDecor) { + installDecor(); + } + mHorizontalProgressBar = (IcsProgressBar)mDecor.findViewById(R.id.abs__progress_horizontal); + if (mHorizontalProgressBar != null) { + mHorizontalProgressBar.setVisibility(View.INVISIBLE); + } + return mHorizontalProgressBar; + } + + + /////////////////////////////////////////////////////////////////////////// + // Feature management and content interaction and creation + /////////////////////////////////////////////////////////////////////////// + + private int getFeatures() { + if (DEBUG) Log.d(TAG, "[getFeatures] returning " + mFeatures); + + return mFeatures; + } + + @Override + public boolean hasFeature(int featureId) { + if (DEBUG) Log.d(TAG, "[hasFeature] featureId: " + featureId); + + boolean result = (mFeatures & (1 << featureId)) != 0; + if (DEBUG) Log.d(TAG, "[hasFeature] returning " + result); + return result; + } + + @Override + public boolean requestFeature(int featureId) { + if (DEBUG) Log.d(TAG, "[requestFeature] featureId: " + featureId); + + if (mContentParent != null) { + throw new AndroidRuntimeException("requestFeature() must be called before adding content"); + } + + switch (featureId) { + case Window.FEATURE_ACTION_BAR: + case Window.FEATURE_ACTION_BAR_OVERLAY: + case Window.FEATURE_ACTION_MODE_OVERLAY: + case Window.FEATURE_INDETERMINATE_PROGRESS: + case Window.FEATURE_NO_TITLE: + case Window.FEATURE_PROGRESS: + mFeatures |= (1 << featureId); + return true; + + default: + return false; + } + } + + @Override + public void setUiOptions(int uiOptions) { + if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions); + + mUiOptions = uiOptions; + } + + @Override + public void setUiOptions(int uiOptions, int mask) { + if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions + ", mask: " + mask); + + mUiOptions = (mUiOptions & ~mask) | (uiOptions & mask); + } + + @Override + public void setContentView(int layoutResId) { + if (DEBUG) Log.d(TAG, "[setContentView] layoutResId: " + layoutResId); + + if (mContentParent == null) { + installDecor(); + } else { + mContentParent.removeAllViews(); + } + mActivity.getLayoutInflater().inflate(layoutResId, mContentParent); + + android.view.Window.Callback callback = mActivity.getWindow().getCallback(); + if (callback != null) { + callback.onContentChanged(); + } + + initActionBar(); + } + + @Override + public void setContentView(View view, ViewGroup.LayoutParams params) { + if (DEBUG) Log.d(TAG, "[setContentView] view: " + view + ", params: " + params); + + if (mContentParent == null) { + installDecor(); + } else { + mContentParent.removeAllViews(); + } + mContentParent.addView(view, params); + + android.view.Window.Callback callback = mActivity.getWindow().getCallback(); + if (callback != null) { + callback.onContentChanged(); + } + + initActionBar(); + } + + @Override + public void addContentView(View view, ViewGroup.LayoutParams params) { + if (DEBUG) Log.d(TAG, "[addContentView] view: " + view + ", params: " + params); + + if (mContentParent == null) { + installDecor(); + } + mContentParent.addView(view, params); + + initActionBar(); + } + + private void installDecor() { + if (DEBUG) Log.d(TAG, "[installDecor]"); + + if (mDecor == null) { + mDecor = (ViewGroup)mActivity.getWindow().getDecorView().findViewById(android.R.id.content); + } + if (mContentParent == null) { + //Since we are not operating at the window level we need to take + //into account the fact that the true decor may have already been + //initialized and had content attached to it. If that is the case, + //copy over its children to our new content container. + List views = null; + if (mDecor.getChildCount() > 0) { + views = new ArrayList(1); //Usually there's only one child + for (int i = 0, children = mDecor.getChildCount(); i < children; i++) { + View child = mDecor.getChildAt(0); + mDecor.removeView(child); + views.add(child); + } + } + + mContentParent = generateLayout(); + + //Copy over the old children. See above for explanation. + if (views != null) { + for (View child : views) { + mContentParent.addView(child); + } + } + + mTitleView = (TextView)mDecor.findViewById(android.R.id.title); + if (mTitleView != null) { + if (hasFeature(Window.FEATURE_NO_TITLE)) { + mTitleView.setVisibility(View.GONE); + if (mContentParent instanceof FrameLayout) { + ((FrameLayout)mContentParent).setForeground(null); + } + } else { + mTitleView.setText(mTitle); + } + } else { + wActionBar = (ActionBarView)mDecor.findViewById(R.id.abs__action_bar); + if (wActionBar != null) { + wActionBar.setWindowCallback(this); + if (wActionBar.getTitle() == null) { + wActionBar.setWindowTitle(mActivity.getTitle()); + } + if (hasFeature(Window.FEATURE_PROGRESS)) { + wActionBar.initProgress(); + } + if (hasFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) { + wActionBar.initIndeterminateProgress(); + } + + //Since we don't require onCreate dispatching, parse for uiOptions here + int uiOptions = loadUiOptionsFromManifest(mActivity); + if (uiOptions != 0) { + mUiOptions = uiOptions; + } + + boolean splitActionBar = false; + final boolean splitWhenNarrow = (mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0; + if (splitWhenNarrow) { + splitActionBar = getResources_getBoolean(mActivity, R.bool.abs__split_action_bar_is_narrow); + } else { + splitActionBar = mActivity.getTheme() + .obtainStyledAttributes(R.styleable.SherlockTheme) + .getBoolean(R.styleable.SherlockTheme_windowSplitActionBar, false); + } + final ActionBarContainer splitView = (ActionBarContainer)mDecor.findViewById(R.id.abs__split_action_bar); + if (splitView != null) { + wActionBar.setSplitView(splitView); + wActionBar.setSplitActionBar(splitActionBar); + wActionBar.setSplitWhenNarrow(splitWhenNarrow); + + mActionModeView = (ActionBarContextView)mDecor.findViewById(R.id.abs__action_context_bar); + mActionModeView.setSplitView(splitView); + mActionModeView.setSplitActionBar(splitActionBar); + mActionModeView.setSplitWhenNarrow(splitWhenNarrow); + } else if (splitActionBar) { + Log.e(TAG, "Requested split action bar with incompatible window decor! Ignoring request."); + } + + // Post the panel invalidate for later; avoid application onCreateOptionsMenu + // being called in the middle of onCreate or similar. + mDecor.post(new Runnable() { + @Override + public void run() { + //Invalidate if the panel menu hasn't been created before this. + if (!mIsDestroyed && !mActivity.isFinishing() && mMenu == null) { + dispatchInvalidateOptionsMenu(); + } + } + }); + } + } + } + } + + private ViewGroup generateLayout() { + if (DEBUG) Log.d(TAG, "[generateLayout]"); + + // Apply data from current theme. + + TypedArray a = mActivity.getTheme().obtainStyledAttributes(R.styleable.SherlockTheme); + + mIsFloating = a.getBoolean(R.styleable.SherlockTheme_android_windowIsFloating, false); + + if (!a.hasValue(R.styleable.SherlockTheme_windowActionBar)) { + throw new IllegalStateException("You must use Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar, or a derivative."); + } + + if (a.getBoolean(R.styleable.SherlockTheme_windowNoTitle, false)) { + requestFeature(Window.FEATURE_NO_TITLE); + } else if (a.getBoolean(R.styleable.SherlockTheme_windowActionBar, false)) { + // Don't allow an action bar if there is no title. + requestFeature(Window.FEATURE_ACTION_BAR); + } + + if (a.getBoolean(R.styleable.SherlockTheme_windowActionBarOverlay, false)) { + requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); + } + + if (a.getBoolean(R.styleable.SherlockTheme_windowActionModeOverlay, false)) { + requestFeature(Window.FEATURE_ACTION_MODE_OVERLAY); + } + + a.recycle(); + + int layoutResource; + if (!hasFeature(Window.FEATURE_NO_TITLE)) { + if (mIsFloating) { + //Trash original dialog LinearLayout + mDecor = (ViewGroup)mDecor.getParent(); + mDecor.removeAllViews(); + + layoutResource = R.layout.abs__dialog_title_holo; + } else { + if (hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY)) { + layoutResource = R.layout.abs__screen_action_bar_overlay; + } else { + layoutResource = R.layout.abs__screen_action_bar; + } + } + } else if (hasFeature(Window.FEATURE_ACTION_MODE_OVERLAY) && !hasFeature(Window.FEATURE_NO_TITLE)) { + layoutResource = R.layout.abs__screen_simple_overlay_action_mode; + } else { + layoutResource = R.layout.abs__screen_simple; + } + + if (DEBUG) Log.d(TAG, "[generateLayout] using screen XML " + mActivity.getResources().getString(layoutResource)); + View in = mActivity.getLayoutInflater().inflate(layoutResource, null); + mDecor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); + + ViewGroup contentParent = (ViewGroup)mDecor.findViewById(R.id.abs__content); + if (contentParent == null) { + throw new RuntimeException("Couldn't find content container view"); + } + + //Make our new child the true content view (for fragments). VERY VOLATILE! + mDecor.setId(View.NO_ID); + contentParent.setId(android.R.id.content); + + if (hasFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) { + IcsProgressBar progress = getCircularProgressBar(false); + if (progress != null) { + progress.setIndeterminate(true); + } + } + + return contentParent; + } + + + /////////////////////////////////////////////////////////////////////////// + // Miscellaneous + /////////////////////////////////////////////////////////////////////////// + + /** + * Determine whether or not the device has a dedicated menu key. + * + * @return {@code true} if native menu key is present. + */ + private boolean isReservingOverflow() { + if (!mReserveOverflowSet) { + mReserveOverflow = ActionMenuPresenter.reserveOverflow(mActivity); + mReserveOverflowSet = true; + } + return mReserveOverflow; + } + + private static int loadUiOptionsFromManifest(Activity activity) { + int uiOptions = 0; + try { + final String thisPackage = activity.getClass().getName(); + if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); + + final String packageName = activity.getApplicationInfo().packageName; + final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); + final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); + + int eventType = xml.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + String name = xml.getName(); + + if ("application".equals(name)) { + //Check if the has the attribute + if (DEBUG) Log.d(TAG, "Got "); + + for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { + if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); + + if ("uiOptions".equals(xml.getAttributeName(i))) { + uiOptions = xml.getAttributeIntValue(i, 0); + break; //out of for loop + } + } + } else if ("activity".equals(name)) { + //Check if the is us and has the attribute + if (DEBUG) Log.d(TAG, "Got "); + Integer activityUiOptions = null; + String activityPackage = null; + boolean isOurActivity = false; + + for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { + if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); + + //We need both uiOptions and name attributes + String attrName = xml.getAttributeName(i); + if ("uiOptions".equals(attrName)) { + activityUiOptions = xml.getAttributeIntValue(i, 0); + } else if ("name".equals(attrName)) { + activityPackage = cleanActivityName(packageName, xml.getAttributeValue(i)); + if (!thisPackage.equals(activityPackage)) { + break; //out of for loop + } + isOurActivity = true; + } + + //Make sure we have both attributes before processing + if ((activityUiOptions != null) && (activityPackage != null)) { + //Our activity, uiOptions specified, override with our value + uiOptions = activityUiOptions.intValue(); + } + } + if (isOurActivity) { + //If we matched our activity but it had no logo don't + //do any more processing of the manifest + break; + } + } + } + eventType = xml.nextToken(); + } + } catch (Exception e) { + e.printStackTrace(); + } + if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(uiOptions)); + return uiOptions; + } + + public static String cleanActivityName(String manifestPackage, String activityName) { + if (activityName.charAt(0) == '.') { + //Relative activity name (e.g., android:name=".ui.SomeClass") + return manifestPackage + activityName; + } + if (activityName.indexOf('.', 1) == -1) { + //Unqualified activity name (e.g., android:name="SomeClass") + return manifestPackage + "." + activityName; + } + //Fully-qualified activity name (e.g., "com.my.package.SomeClass") + return activityName; + } + + /** + * Clears out internal reference when the action mode is destroyed. + */ + private class ActionModeCallbackWrapper implements ActionMode.Callback { + private final ActionMode.Callback mWrapped; + + public ActionModeCallbackWrapper(ActionMode.Callback wrapped) { + mWrapped = wrapped; + } + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return mWrapped.onCreateActionMode(mode, menu); + } + + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return mWrapped.onPrepareActionMode(mode, menu); + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return mWrapped.onActionItemClicked(mode, item); + } + + public void onDestroyActionMode(ActionMode mode) { + mWrapped.onDestroyActionMode(mode); + if (mActionModeView != null) { + mActionModeView.setVisibility(View.GONE); + mActionModeView.removeAllViews(); + } + if (mActivity instanceof OnActionModeFinishedListener) { + ((OnActionModeFinishedListener)mActivity).onActionModeFinished(mActionMode); + } + mActionMode = null; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java new file mode 100644 index 0000000000..0824d3848f --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java @@ -0,0 +1,336 @@ +package com.actionbarsherlock.internal; + +import com.actionbarsherlock.ActionBarSherlock; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.internal.app.ActionBarWrapper; +import com.actionbarsherlock.internal.view.menu.MenuWrapper; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.MenuInflater; +import android.app.Activity; +import android.content.Context; +import android.util.Log; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.View; +import android.view.Window; +import android.view.ViewGroup.LayoutParams; + +@ActionBarSherlock.Implementation(api = 14) +public class ActionBarSherlockNative extends ActionBarSherlock { + private ActionBarWrapper mActionBar; + private ActionModeWrapper mActionMode; + private MenuWrapper mMenu; + + public ActionBarSherlockNative(Activity activity, int flags) { + super(activity, flags); + } + + + @Override + public ActionBar getActionBar() { + if (DEBUG) Log.d(TAG, "[getActionBar]"); + + initActionBar(); + return mActionBar; + } + + private void initActionBar() { + if (mActionBar != null || mActivity.getActionBar() == null) { + return; + } + + mActionBar = new ActionBarWrapper(mActivity); + } + + @Override + public void dispatchInvalidateOptionsMenu() { + if (DEBUG) Log.d(TAG, "[dispatchInvalidateOptionsMenu]"); + + mActivity.getWindow().invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL); + } + + @Override + public boolean dispatchCreateOptionsMenu(android.view.Menu menu) { + if (DEBUG) Log.d(TAG, "[dispatchCreateOptionsMenu] menu: " + menu); + + if (mMenu == null || menu != mMenu.unwrap()) { + mMenu = new MenuWrapper(menu); + } + + final boolean result = callbackCreateOptionsMenu(mMenu); + if (DEBUG) Log.d(TAG, "[dispatchCreateOptionsMenu] returning " + result); + return result; + } + + @Override + public boolean dispatchPrepareOptionsMenu(android.view.Menu menu) { + if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] menu: " + menu); + + final boolean result = callbackPrepareOptionsMenu(mMenu); + if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] returning " + result); + return result; + } + + @Override + public boolean dispatchOptionsItemSelected(android.view.MenuItem item) { + if (DEBUG) Log.d(TAG, "[dispatchOptionsItemSelected] item: " + item.getTitleCondensed()); + + final boolean result = callbackOptionsItemSelected(mMenu.findItem(item)); + if (DEBUG) Log.d(TAG, "[dispatchOptionsItemSelected] returning " + result); + return result; + } + + @Override + public boolean hasFeature(int feature) { + if (DEBUG) Log.d(TAG, "[hasFeature] feature: " + feature); + + final boolean result = mActivity.getWindow().hasFeature(feature); + if (DEBUG) Log.d(TAG, "[hasFeature] returning " + result); + return result; + } + + @Override + public boolean requestFeature(int featureId) { + if (DEBUG) Log.d(TAG, "[requestFeature] featureId: " + featureId); + + final boolean result = mActivity.getWindow().requestFeature(featureId); + if (DEBUG) Log.d(TAG, "[requestFeature] returning " + result); + return result; + } + + @Override + public void setUiOptions(int uiOptions) { + if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions); + + mActivity.getWindow().setUiOptions(uiOptions); + } + + @Override + public void setUiOptions(int uiOptions, int mask) { + if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions + ", mask: " + mask); + + mActivity.getWindow().setUiOptions(uiOptions, mask); + } + + @Override + public void setContentView(int layoutResId) { + if (DEBUG) Log.d(TAG, "[setContentView] layoutResId: " + layoutResId); + + mActivity.getWindow().setContentView(layoutResId); + initActionBar(); + } + + @Override + public void setContentView(View view, LayoutParams params) { + if (DEBUG) Log.d(TAG, "[setContentView] view: " + view + ", params: " + params); + + mActivity.getWindow().setContentView(view, params); + initActionBar(); + } + + @Override + public void addContentView(View view, LayoutParams params) { + if (DEBUG) Log.d(TAG, "[addContentView] view: " + view + ", params: " + params); + + mActivity.getWindow().addContentView(view, params); + initActionBar(); + } + + @Override + public void setTitle(CharSequence title) { + if (DEBUG) Log.d(TAG, "[setTitle] title: " + title); + + mActivity.getWindow().setTitle(title); + } + + @Override + public void setProgressBarVisibility(boolean visible) { + if (DEBUG) Log.d(TAG, "[setProgressBarVisibility] visible: " + visible); + + mActivity.setProgressBarVisibility(visible); + } + + @Override + public void setProgressBarIndeterminateVisibility(boolean visible) { + if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminateVisibility] visible: " + visible); + + mActivity.setProgressBarIndeterminateVisibility(visible); + } + + @Override + public void setProgressBarIndeterminate(boolean indeterminate) { + if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminate] indeterminate: " + indeterminate); + + mActivity.setProgressBarIndeterminate(indeterminate); + } + + @Override + public void setProgress(int progress) { + if (DEBUG) Log.d(TAG, "[setProgress] progress: " + progress); + + mActivity.setProgress(progress); + } + + @Override + public void setSecondaryProgress(int secondaryProgress) { + if (DEBUG) Log.d(TAG, "[setSecondaryProgress] secondaryProgress: " + secondaryProgress); + + mActivity.setSecondaryProgress(secondaryProgress); + } + + @Override + protected Context getThemedContext() { + Context context = mActivity; + TypedValue outValue = new TypedValue(); + mActivity.getTheme().resolveAttribute(android.R.attr.actionBarWidgetTheme, outValue, true); + if (outValue.resourceId != 0) { + //We are unable to test if this is the same as our current theme + //so we just wrap it and hope that if the attribute was specified + //then the user is intentionally specifying an alternate theme. + context = new ContextThemeWrapper(context, outValue.resourceId); + } + return context; + } + + @Override + public ActionMode startActionMode(com.actionbarsherlock.view.ActionMode.Callback callback) { + if (DEBUG) Log.d(TAG, "[startActionMode] callback: " + callback); + + if (mActionMode != null) { + mActionMode.finish(); + } + ActionModeCallbackWrapper wrapped = null; + if (callback != null) { + wrapped = new ActionModeCallbackWrapper(callback); + } + + //Calling this will trigger the callback wrapper's onCreate which + //is where we will set the new instance to mActionMode since we need + //to pass it through to the sherlock callbacks and the call below + //will not have returned yet to store its value. + if (mActivity.startActionMode(wrapped) == null) { + mActionMode = null; + } + if (mActivity instanceof OnActionModeStartedListener && mActionMode != null) { + ((OnActionModeStartedListener)mActivity).onActionModeStarted(mActionMode); + } + + return mActionMode; + } + + private class ActionModeCallbackWrapper implements android.view.ActionMode.Callback { + private final ActionMode.Callback mCallback; + + public ActionModeCallbackWrapper(ActionMode.Callback callback) { + mCallback = callback; + } + + @Override + public boolean onCreateActionMode(android.view.ActionMode mode, android.view.Menu menu) { + //See ActionBarSherlockNative#startActionMode + mActionMode = new ActionModeWrapper(mode); + + return mCallback.onCreateActionMode(mActionMode, mActionMode.getMenu()); + } + + @Override + public boolean onPrepareActionMode(android.view.ActionMode mode, android.view.Menu menu) { + return mCallback.onPrepareActionMode(mActionMode, mActionMode.getMenu()); + } + + @Override + public boolean onActionItemClicked(android.view.ActionMode mode, android.view.MenuItem item) { + return mCallback.onActionItemClicked(mActionMode, mActionMode.getMenu().findItem(item)); + } + + @Override + public void onDestroyActionMode(android.view.ActionMode mode) { + mCallback.onDestroyActionMode(mActionMode); + if (mActivity instanceof OnActionModeFinishedListener) { + ((OnActionModeFinishedListener)mActivity).onActionModeFinished(mActionMode); + } + } + } + + private class ActionModeWrapper extends ActionMode { + private final android.view.ActionMode mActionMode; + private MenuWrapper mMenu = null; + + ActionModeWrapper(android.view.ActionMode actionMode) { + mActionMode = actionMode; + } + + @Override + public void setTitle(CharSequence title) { + mActionMode.setTitle(title); + } + + @Override + public void setTitle(int resId) { + mActionMode.setTitle(resId); + } + + @Override + public void setSubtitle(CharSequence subtitle) { + mActionMode.setSubtitle(subtitle); + } + + @Override + public void setSubtitle(int resId) { + mActionMode.setSubtitle(resId); + } + + @Override + public void setCustomView(View view) { + mActionMode.setCustomView(view); + } + + @Override + public void invalidate() { + mActionMode.invalidate(); + } + + @Override + public void finish() { + mActionMode.finish(); + } + + @Override + public MenuWrapper getMenu() { + if (mMenu == null) { + mMenu = new MenuWrapper(mActionMode.getMenu()); + } + return mMenu; + } + + @Override + public CharSequence getTitle() { + return mActionMode.getTitle(); + } + + @Override + public CharSequence getSubtitle() { + return mActionMode.getSubtitle(); + } + + @Override + public View getCustomView() { + return mActionMode.getCustomView(); + } + + @Override + public MenuInflater getMenuInflater() { + return ActionBarSherlockNative.this.getMenuInflater(); + } + + @Override + public void setTag(Object tag) { + mActionMode.setTag(tag); + } + + @Override + public Object getTag() { + return mActionMode.getTag(); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ResourcesCompat.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ResourcesCompat.java new file mode 100644 index 0000000000..8e1efe8c54 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/ResourcesCompat.java @@ -0,0 +1,95 @@ +package com.actionbarsherlock.internal; + +import android.content.Context; +import android.os.Build; +import android.util.DisplayMetrics; +import com.actionbarsherlock.R; + +public final class ResourcesCompat { + //No instances + private ResourcesCompat() {} + + + /** + * Support implementation of {@code getResources().getBoolean()} that we + * can use to simulate filtering based on width and smallest width + * qualifiers on pre-3.2. + * + * @param context Context to load booleans from on 3.2+ and to fetch the + * display metrics. + * @param id Id of boolean to load. + * @return Associated boolean value as reflected by the current display + * metrics. + */ + public static boolean getResources_getBoolean(Context context, int id) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { + return context.getResources().getBoolean(id); + } + + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + float widthDp = metrics.widthPixels / metrics.density; + float heightDp = metrics.heightPixels / metrics.density; + float smallestWidthDp = (widthDp < heightDp) ? widthDp : heightDp; + + if (id == R.bool.abs__action_bar_embed_tabs) { + if (widthDp >= 480) { + return true; //values-w480dp + } + return false; //values + } + if (id == R.bool.abs__split_action_bar_is_narrow) { + if (widthDp >= 480) { + return false; //values-w480dp + } + return true; //values + } + if (id == R.bool.abs__action_bar_expanded_action_views_exclusive) { + if (smallestWidthDp >= 600) { + return false; //values-sw600dp + } + return true; //values + } + if (id == R.bool.abs__config_allowActionMenuItemTextWithIcon) { + if (widthDp >= 480) { + return true; //values-w480dp + } + return false; //values + } + + throw new IllegalArgumentException("Unknown boolean resource ID " + id); + } + + /** + * Support implementation of {@code getResources().getInteger()} that we + * can use to simulate filtering based on width qualifiers on pre-3.2. + * + * @param context Context to load integers from on 3.2+ and to fetch the + * display metrics. + * @param id Id of integer to load. + * @return Associated integer value as reflected by the current display + * metrics. + */ + public static int getResources_getInteger(Context context, int id) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { + return context.getResources().getInteger(id); + } + + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + float widthDp = metrics.widthPixels / metrics.density; + + if (id == R.integer.abs__max_action_buttons) { + if (widthDp >= 600) { + return 5; //values-w600dp + } + if (widthDp >= 500) { + return 4; //values-w500dp + } + if (widthDp >= 360) { + return 3; //values-w360dp + } + return 2; //values + } + + throw new IllegalArgumentException("Unknown integer resource ID " + id); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarImpl.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarImpl.java new file mode 100644 index 0000000000..d022a24659 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarImpl.java @@ -0,0 +1,1026 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.app; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Handler; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentTransaction; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.accessibility.AccessibilityEvent; +import android.widget.SpinnerAdapter; +import com.actionbarsherlock.R; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; +import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorListenerAdapter; +import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; +import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener; +import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; +import com.actionbarsherlock.internal.view.menu.MenuBuilder; +import com.actionbarsherlock.internal.view.menu.MenuPopupHelper; +import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; +import com.actionbarsherlock.internal.widget.ActionBarContainer; +import com.actionbarsherlock.internal.widget.ActionBarContextView; +import com.actionbarsherlock.internal.widget.ActionBarView; +import com.actionbarsherlock.internal.widget.ScrollingTabContainerView; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; +import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; + +/** + * ActionBarImpl is the ActionBar implementation used + * by devices of all screen sizes. If it detects a compatible decor, + * it will split contextual modes across both the ActionBarView at + * the top of the screen and a horizontal LinearLayout at the bottom + * which is normally hidden. + */ +public class ActionBarImpl extends ActionBar { + //UNUSED private static final String TAG = "ActionBarImpl"; + + private Context mContext; + private Context mThemedContext; + private Activity mActivity; + //UNUSED private Dialog mDialog; + + private ActionBarContainer mContainerView; + private ActionBarView mActionView; + private ActionBarContextView mContextView; + private ActionBarContainer mSplitView; + private NineFrameLayout mContentView; + private ScrollingTabContainerView mTabScrollView; + + private ArrayList mTabs = new ArrayList(); + + private TabImpl mSelectedTab; + private int mSavedTabPosition = INVALID_POSITION; + + ActionModeImpl mActionMode; + ActionMode mDeferredDestroyActionMode; + ActionMode.Callback mDeferredModeDestroyCallback; + + private boolean mLastMenuVisibility; + private ArrayList mMenuVisibilityListeners = + new ArrayList(); + + private static final int CONTEXT_DISPLAY_NORMAL = 0; + private static final int CONTEXT_DISPLAY_SPLIT = 1; + + private static final int INVALID_POSITION = -1; + + private int mContextDisplayMode; + private boolean mHasEmbeddedTabs; + + final Handler mHandler = new Handler(); + Runnable mTabSelector; + + private Animator mCurrentShowAnim; + private Animator mCurrentModeAnim; + private boolean mShowHideAnimationEnabled; + boolean mWasHiddenBeforeMode; + + final AnimatorListener mHideListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (mContentView != null) { + mContentView.setTranslationY(0); + mContainerView.setTranslationY(0); + } + if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { + mSplitView.setVisibility(View.GONE); + } + mContainerView.setVisibility(View.GONE); + mContainerView.setTransitioning(false); + mCurrentShowAnim = null; + completeDeferredDestroyActionMode(); + } + }; + + final AnimatorListener mShowListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mCurrentShowAnim = null; + mContainerView.requestLayout(); + } + }; + + public ActionBarImpl(Activity activity, int features) { + mActivity = activity; + Window window = activity.getWindow(); + View decor = window.getDecorView(); + init(decor); + + //window.hasFeature() workaround for pre-3.0 + if ((features & (1 << Window.FEATURE_ACTION_BAR_OVERLAY)) == 0) { + mContentView = (NineFrameLayout)decor.findViewById(android.R.id.content); + } + } + + public ActionBarImpl(Dialog dialog) { + //UNUSED mDialog = dialog; + init(dialog.getWindow().getDecorView()); + } + + private void init(View decor) { + mContext = decor.getContext(); + mActionView = (ActionBarView) decor.findViewById(R.id.abs__action_bar); + mContextView = (ActionBarContextView) decor.findViewById( + R.id.abs__action_context_bar); + mContainerView = (ActionBarContainer) decor.findViewById( + R.id.abs__action_bar_container); + mSplitView = (ActionBarContainer) decor.findViewById( + R.id.abs__split_action_bar); + + if (mActionView == null || mContextView == null || mContainerView == null) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with a compatible window decor layout"); + } + + mActionView.setContextView(mContextView); + mContextDisplayMode = mActionView.isSplitActionBar() ? + CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL; + + // Older apps get the home button interaction enabled by default. + // Newer apps need to enable it explicitly. + setHomeButtonEnabled(mContext.getApplicationInfo().targetSdkVersion < 14); + + setHasEmbeddedTabs(getResources_getBoolean(mContext, + R.bool.abs__action_bar_embed_tabs)); + } + + public void onConfigurationChanged(Configuration newConfig) { + setHasEmbeddedTabs(getResources_getBoolean(mContext, + R.bool.abs__action_bar_embed_tabs)); + + //Manually dispatch a configuration change to the action bar view on pre-2.2 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { + mActionView.onConfigurationChanged(newConfig); + if (mContextView != null) { + mContextView.onConfigurationChanged(newConfig); + } + } + } + + private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) { + mHasEmbeddedTabs = hasEmbeddedTabs; + // Switch tab layout configuration if needed + if (!mHasEmbeddedTabs) { + mActionView.setEmbeddedTabView(null); + mContainerView.setTabContainer(mTabScrollView); + } else { + mContainerView.setTabContainer(null); + mActionView.setEmbeddedTabView(mTabScrollView); + } + final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS; + if (mTabScrollView != null) { + mTabScrollView.setVisibility(isInTabMode ? View.VISIBLE : View.GONE); + } + mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode); + } + + private void ensureTabsExist() { + if (mTabScrollView != null) { + return; + } + + ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext); + + if (mHasEmbeddedTabs) { + tabScroller.setVisibility(View.VISIBLE); + mActionView.setEmbeddedTabView(tabScroller); + } else { + tabScroller.setVisibility(getNavigationMode() == NAVIGATION_MODE_TABS ? + View.VISIBLE : View.GONE); + mContainerView.setTabContainer(tabScroller); + } + mTabScrollView = tabScroller; + } + + void completeDeferredDestroyActionMode() { + if (mDeferredModeDestroyCallback != null) { + mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode); + mDeferredDestroyActionMode = null; + mDeferredModeDestroyCallback = null; + } + } + + /** + * Enables or disables animation between show/hide states. + * If animation is disabled using this method, animations in progress + * will be finished. + * + * @param enabled true to animate, false to not animate. + */ + public void setShowHideAnimationEnabled(boolean enabled) { + mShowHideAnimationEnabled = enabled; + if (!enabled && mCurrentShowAnim != null) { + mCurrentShowAnim.end(); + } + } + + public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.add(listener); + } + + public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.remove(listener); + } + + public void dispatchMenuVisibilityChanged(boolean isVisible) { + if (isVisible == mLastMenuVisibility) { + return; + } + mLastMenuVisibility = isVisible; + + final int count = mMenuVisibilityListeners.size(); + for (int i = 0; i < count; i++) { + mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible); + } + } + + @Override + public void setCustomView(int resId) { + setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false)); + } + + @Override + public void setDisplayUseLogoEnabled(boolean useLogo) { + setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO); + } + + @Override + public void setDisplayShowHomeEnabled(boolean showHome) { + setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME); + } + + @Override + public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) { + setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP); + } + + @Override + public void setDisplayShowTitleEnabled(boolean showTitle) { + setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE); + } + + @Override + public void setDisplayShowCustomEnabled(boolean showCustom) { + setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM); + } + + @Override + public void setHomeButtonEnabled(boolean enable) { + mActionView.setHomeButtonEnabled(enable); + } + + @Override + public void setTitle(int resId) { + setTitle(mContext.getString(resId)); + } + + @Override + public void setSubtitle(int resId) { + setSubtitle(mContext.getString(resId)); + } + + public void setSelectedNavigationItem(int position) { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + selectTab(mTabs.get(position)); + break; + case NAVIGATION_MODE_LIST: + mActionView.setDropdownSelectedPosition(position); + break; + default: + throw new IllegalStateException( + "setSelectedNavigationIndex not valid for current navigation mode"); + } + } + + public void removeAllTabs() { + cleanupTabs(); + } + + private void cleanupTabs() { + if (mSelectedTab != null) { + selectTab(null); + } + mTabs.clear(); + if (mTabScrollView != null) { + mTabScrollView.removeAllTabs(); + } + mSavedTabPosition = INVALID_POSITION; + } + + public void setTitle(CharSequence title) { + mActionView.setTitle(title); + } + + public void setSubtitle(CharSequence subtitle) { + mActionView.setSubtitle(subtitle); + } + + public void setDisplayOptions(int options) { + mActionView.setDisplayOptions(options); + } + + public void setDisplayOptions(int options, int mask) { + final int current = mActionView.getDisplayOptions(); + mActionView.setDisplayOptions((options & mask) | (current & ~mask)); + } + + public void setBackgroundDrawable(Drawable d) { + mContainerView.setPrimaryBackground(d); + } + + public void setStackedBackgroundDrawable(Drawable d) { + mContainerView.setStackedBackground(d); + } + + public void setSplitBackgroundDrawable(Drawable d) { + if (mSplitView != null) { + mSplitView.setSplitBackground(d); + } + } + + public View getCustomView() { + return mActionView.getCustomNavigationView(); + } + + public CharSequence getTitle() { + return mActionView.getTitle(); + } + + public CharSequence getSubtitle() { + return mActionView.getSubtitle(); + } + + public int getNavigationMode() { + return mActionView.getNavigationMode(); + } + + public int getDisplayOptions() { + return mActionView.getDisplayOptions(); + } + + public ActionMode startActionMode(ActionMode.Callback callback) { + boolean wasHidden = false; + if (mActionMode != null) { + wasHidden = mWasHiddenBeforeMode; + mActionMode.finish(); + } + + mContextView.killMode(); + ActionModeImpl mode = new ActionModeImpl(callback); + if (mode.dispatchOnCreate()) { + mWasHiddenBeforeMode = !isShowing() || wasHidden; + mode.invalidate(); + mContextView.initForMode(mode); + animateToMode(true); + if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { + // TODO animate this + mSplitView.setVisibility(View.VISIBLE); + } + mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + mActionMode = mode; + return mode; + } + return null; + } + + private void configureTab(Tab tab, int position) { + final TabImpl tabi = (TabImpl) tab; + final ActionBar.TabListener callback = tabi.getCallback(); + + if (callback == null) { + throw new IllegalStateException("Action Bar Tab must have a Callback"); + } + + tabi.setPosition(position); + mTabs.add(position, tabi); + + final int count = mTabs.size(); + for (int i = position + 1; i < count; i++) { + mTabs.get(i).setPosition(i); + } + } + + @Override + public void addTab(Tab tab) { + addTab(tab, mTabs.isEmpty()); + } + + @Override + public void addTab(Tab tab, int position) { + addTab(tab, position, mTabs.isEmpty()); + } + + @Override + public void addTab(Tab tab, boolean setSelected) { + ensureTabsExist(); + mTabScrollView.addTab(tab, setSelected); + configureTab(tab, mTabs.size()); + if (setSelected) { + selectTab(tab); + } + } + + @Override + public void addTab(Tab tab, int position, boolean setSelected) { + ensureTabsExist(); + mTabScrollView.addTab(tab, position, setSelected); + configureTab(tab, position); + if (setSelected) { + selectTab(tab); + } + } + + @Override + public Tab newTab() { + return new TabImpl(); + } + + @Override + public void removeTab(Tab tab) { + removeTabAt(tab.getPosition()); + } + + @Override + public void removeTabAt(int position) { + if (mTabScrollView == null) { + // No tabs around to remove + return; + } + + int selectedTabPosition = mSelectedTab != null + ? mSelectedTab.getPosition() : mSavedTabPosition; + mTabScrollView.removeTabAt(position); + TabImpl removedTab = mTabs.remove(position); + if (removedTab != null) { + removedTab.setPosition(-1); + } + + final int newTabCount = mTabs.size(); + for (int i = position; i < newTabCount; i++) { + mTabs.get(i).setPosition(i); + } + + if (selectedTabPosition == position) { + selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1))); + } + } + + @Override + public void selectTab(Tab tab) { + if (getNavigationMode() != NAVIGATION_MODE_TABS) { + mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION; + return; + } + + FragmentTransaction trans = null; + if (mActivity instanceof FragmentActivity) { + trans = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() + .disallowAddToBackStack(); + } + + if (mSelectedTab == tab) { + if (mSelectedTab != null) { + mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans); + mTabScrollView.animateToTab(tab.getPosition()); + } + } else { + mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION); + if (mSelectedTab != null) { + mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans); + } + mSelectedTab = (TabImpl) tab; + if (mSelectedTab != null) { + mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans); + } + } + + if (trans != null && !trans.isEmpty()) { + trans.commit(); + } + } + + @Override + public Tab getSelectedTab() { + return mSelectedTab; + } + + @Override + public int getHeight() { + return mContainerView.getHeight(); + } + + @Override + public void show() { + show(true); + } + + void show(boolean markHiddenBeforeMode) { + if (mCurrentShowAnim != null) { + mCurrentShowAnim.end(); + } + if (mContainerView.getVisibility() == View.VISIBLE) { + if (markHiddenBeforeMode) mWasHiddenBeforeMode = false; + return; + } + mContainerView.setVisibility(View.VISIBLE); + + if (mShowHideAnimationEnabled) { + mContainerView.setAlpha(0); + AnimatorSet anim = new AnimatorSet(); + AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 1)); + if (mContentView != null) { + b.with(ObjectAnimator.ofFloat(mContentView, "translationY", + -mContainerView.getHeight(), 0)); + mContainerView.setTranslationY(-mContainerView.getHeight()); + b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", 0)); + } + if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { + mSplitView.setAlpha(0); + mSplitView.setVisibility(View.VISIBLE); + b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1)); + } + anim.addListener(mShowListener); + mCurrentShowAnim = anim; + anim.start(); + } else { + mContainerView.setAlpha(1); + mContainerView.setTranslationY(0); + mShowListener.onAnimationEnd(null); + } + } + + @Override + public void hide() { + if (mCurrentShowAnim != null) { + mCurrentShowAnim.end(); + } + if (mContainerView.getVisibility() == View.GONE) { + return; + } + + if (mShowHideAnimationEnabled) { + mContainerView.setAlpha(1); + mContainerView.setTransitioning(true); + AnimatorSet anim = new AnimatorSet(); + AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 0)); + if (mContentView != null) { + b.with(ObjectAnimator.ofFloat(mContentView, "translationY", + 0, -mContainerView.getHeight())); + b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", + -mContainerView.getHeight())); + } + if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) { + mSplitView.setAlpha(1); + b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0)); + } + anim.addListener(mHideListener); + mCurrentShowAnim = anim; + anim.start(); + } else { + mHideListener.onAnimationEnd(null); + } + } + + public boolean isShowing() { + return mContainerView.getVisibility() == View.VISIBLE; + } + + void animateToMode(boolean toActionMode) { + if (toActionMode) { + show(false); + } + if (mCurrentModeAnim != null) { + mCurrentModeAnim.end(); + } + + mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); + mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE); + if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) { + mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); + } + } + + public Context getThemedContext() { + if (mThemedContext == null) { + TypedValue outValue = new TypedValue(); + Resources.Theme currentTheme = mContext.getTheme(); + currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme, + outValue, true); + final int targetThemeRes = outValue.resourceId; + + if (targetThemeRes != 0) { //XXX && mContext.getThemeResId() != targetThemeRes) { + mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes); + } else { + mThemedContext = mContext; + } + } + return mThemedContext; + } + + /** + * @hide + */ + public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback { + private ActionMode.Callback mCallback; + private MenuBuilder mMenu; + private WeakReference mCustomView; + + public ActionModeImpl(ActionMode.Callback callback) { + mCallback = callback; + mMenu = new MenuBuilder(getThemedContext()) + .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + mMenu.setCallback(this); + } + + @Override + public MenuInflater getMenuInflater() { + return new MenuInflater(getThemedContext()); + } + + @Override + public Menu getMenu() { + return mMenu; + } + + @Override + public void finish() { + if (mActionMode != this) { + // Not the active action mode - no-op + return; + } + + // If we were hidden before the mode was shown, defer the onDestroy + // callback until the animation is finished and associated relayout + // is about to happen. This lets apps better anticipate visibility + // and layout behavior. + if (mWasHiddenBeforeMode) { + mDeferredDestroyActionMode = this; + mDeferredModeDestroyCallback = mCallback; + } else { + mCallback.onDestroyActionMode(this); + } + mCallback = null; + animateToMode(false); + + // Clear out the context mode views after the animation finishes + mContextView.closeMode(); + mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + + mActionMode = null; + + if (mWasHiddenBeforeMode) { + hide(); + } + } + + @Override + public void invalidate() { + mMenu.stopDispatchingItemsChanged(); + try { + mCallback.onPrepareActionMode(this, mMenu); + } finally { + mMenu.startDispatchingItemsChanged(); + } + } + + public boolean dispatchOnCreate() { + mMenu.stopDispatchingItemsChanged(); + try { + return mCallback.onCreateActionMode(this, mMenu); + } finally { + mMenu.startDispatchingItemsChanged(); + } + } + + @Override + public void setCustomView(View view) { + mContextView.setCustomView(view); + mCustomView = new WeakReference(view); + } + + @Override + public void setSubtitle(CharSequence subtitle) { + mContextView.setSubtitle(subtitle); + } + + @Override + public void setTitle(CharSequence title) { + mContextView.setTitle(title); + } + + @Override + public void setTitle(int resId) { + setTitle(mContext.getResources().getString(resId)); + } + + @Override + public void setSubtitle(int resId) { + setSubtitle(mContext.getResources().getString(resId)); + } + + @Override + public CharSequence getTitle() { + return mContextView.getTitle(); + } + + @Override + public CharSequence getSubtitle() { + return mContextView.getSubtitle(); + } + + @Override + public View getCustomView() { + return mCustomView != null ? mCustomView.get() : null; + } + + public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { + if (mCallback != null) { + return mCallback.onActionItemClicked(this, item); + } else { + return false; + } + } + + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + } + + public boolean onSubMenuSelected(SubMenuBuilder subMenu) { + if (mCallback == null) { + return false; + } + + if (!subMenu.hasVisibleItems()) { + return true; + } + + new MenuPopupHelper(getThemedContext(), subMenu).show(); + return true; + } + + public void onCloseSubMenu(SubMenuBuilder menu) { + } + + public void onMenuModeChange(MenuBuilder menu) { + if (mCallback == null) { + return; + } + invalidate(); + mContextView.showOverflowMenu(); + } + } + + /** + * @hide + */ + public class TabImpl extends ActionBar.Tab { + private ActionBar.TabListener mCallback; + private Object mTag; + private Drawable mIcon; + private CharSequence mText; + private CharSequence mContentDesc; + private int mPosition = -1; + private View mCustomView; + + @Override + public Object getTag() { + return mTag; + } + + @Override + public Tab setTag(Object tag) { + mTag = tag; + return this; + } + + public ActionBar.TabListener getCallback() { + return mCallback; + } + + @Override + public Tab setTabListener(ActionBar.TabListener callback) { + mCallback = callback; + return this; + } + + @Override + public View getCustomView() { + return mCustomView; + } + + @Override + public Tab setCustomView(View view) { + mCustomView = view; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public Tab setCustomView(int layoutResId) { + return setCustomView(LayoutInflater.from(getThemedContext()) + .inflate(layoutResId, null)); + } + + @Override + public Drawable getIcon() { + return mIcon; + } + + @Override + public int getPosition() { + return mPosition; + } + + public void setPosition(int position) { + mPosition = position; + } + + @Override + public CharSequence getText() { + return mText; + } + + @Override + public Tab setIcon(Drawable icon) { + mIcon = icon; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public Tab setIcon(int resId) { + return setIcon(mContext.getResources().getDrawable(resId)); + } + + @Override + public Tab setText(CharSequence text) { + mText = text; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public Tab setText(int resId) { + return setText(mContext.getResources().getText(resId)); + } + + @Override + public void select() { + selectTab(this); + } + + @Override + public Tab setContentDescription(int resId) { + return setContentDescription(mContext.getResources().getText(resId)); + } + + @Override + public Tab setContentDescription(CharSequence contentDesc) { + mContentDesc = contentDesc; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public CharSequence getContentDescription() { + return mContentDesc; + } + } + + @Override + public void setCustomView(View view) { + mActionView.setCustomNavigationView(view); + } + + @Override + public void setCustomView(View view, LayoutParams layoutParams) { + view.setLayoutParams(layoutParams); + mActionView.setCustomNavigationView(view); + } + + @Override + public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { + mActionView.setDropdownAdapter(adapter); + mActionView.setCallback(callback); + } + + @Override + public int getSelectedNavigationIndex() { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + return mSelectedTab != null ? mSelectedTab.getPosition() : -1; + case NAVIGATION_MODE_LIST: + return mActionView.getDropdownSelectedPosition(); + default: + return -1; + } + } + + @Override + public int getNavigationItemCount() { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + return mTabs.size(); + case NAVIGATION_MODE_LIST: + SpinnerAdapter adapter = mActionView.getDropdownAdapter(); + return adapter != null ? adapter.getCount() : 0; + default: + return 0; + } + } + + @Override + public int getTabCount() { + return mTabs.size(); + } + + @Override + public void setNavigationMode(int mode) { + final int oldMode = mActionView.getNavigationMode(); + switch (oldMode) { + case NAVIGATION_MODE_TABS: + mSavedTabPosition = getSelectedNavigationIndex(); + selectTab(null); + mTabScrollView.setVisibility(View.GONE); + break; + } + mActionView.setNavigationMode(mode); + switch (mode) { + case NAVIGATION_MODE_TABS: + ensureTabsExist(); + mTabScrollView.setVisibility(View.VISIBLE); + if (mSavedTabPosition != INVALID_POSITION) { + setSelectedNavigationItem(mSavedTabPosition); + mSavedTabPosition = INVALID_POSITION; + } + break; + } + mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs); + } + + @Override + public Tab getTabAt(int index) { + return mTabs.get(index); + } + + + @Override + public void setIcon(int resId) { + mActionView.setIcon(resId); + } + + @Override + public void setIcon(Drawable icon) { + mActionView.setIcon(icon); + } + + @Override + public void setLogo(int resId) { + mActionView.setLogo(resId); + } + + @Override + public void setLogo(Drawable logo) { + mActionView.setLogo(logo); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java new file mode 100644 index 0000000000..840cb3d27c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java @@ -0,0 +1,468 @@ +package com.actionbarsherlock.internal.app; + +import java.util.HashSet; +import java.util.Set; + +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentTransaction; +import android.view.View; +import android.widget.SpinnerAdapter; + +import com.actionbarsherlock.app.ActionBar; + +public class ActionBarWrapper extends ActionBar implements android.app.ActionBar.OnNavigationListener, android.app.ActionBar.OnMenuVisibilityListener { + private final Activity mActivity; + private final android.app.ActionBar mActionBar; + private ActionBar.OnNavigationListener mNavigationListener; + private Set mMenuVisibilityListeners = new HashSet(1); + private FragmentTransaction mFragmentTransaction; + + + public ActionBarWrapper(Activity activity) { + mActivity = activity; + mActionBar = activity.getActionBar(); + if (mActionBar != null) { + mActionBar.addOnMenuVisibilityListener(this); + } + } + + + @Override + public void setHomeButtonEnabled(boolean enabled) { + mActionBar.setHomeButtonEnabled(enabled); + } + + @Override + public Context getThemedContext() { + return mActionBar.getThemedContext(); + } + + @Override + public void setCustomView(View view) { + mActionBar.setCustomView(view); + } + + @Override + public void setCustomView(View view, LayoutParams layoutParams) { + android.app.ActionBar.LayoutParams lp = new android.app.ActionBar.LayoutParams(layoutParams); + lp.gravity = layoutParams.gravity; + lp.bottomMargin = layoutParams.bottomMargin; + lp.topMargin = layoutParams.topMargin; + lp.leftMargin = layoutParams.leftMargin; + lp.rightMargin = layoutParams.rightMargin; + mActionBar.setCustomView(view, lp); + } + + @Override + public void setCustomView(int resId) { + mActionBar.setCustomView(resId); + } + + @Override + public void setIcon(int resId) { + mActionBar.setIcon(resId); + } + + @Override + public void setIcon(Drawable icon) { + mActionBar.setIcon(icon); + } + + @Override + public void setLogo(int resId) { + mActionBar.setLogo(resId); + } + + @Override + public void setLogo(Drawable logo) { + mActionBar.setLogo(logo); + } + + @Override + public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { + mNavigationListener = callback; + mActionBar.setListNavigationCallbacks(adapter, (callback != null) ? this : null); + } + + @Override + public boolean onNavigationItemSelected(int itemPosition, long itemId) { + //This should never be a NullPointerException since we only set + //ourselves as the listener when the callback is not null. + return mNavigationListener.onNavigationItemSelected(itemPosition, itemId); + } + + @Override + public void setSelectedNavigationItem(int position) { + mActionBar.setSelectedNavigationItem(position); + } + + @Override + public int getSelectedNavigationIndex() { + return mActionBar.getSelectedNavigationIndex(); + } + + @Override + public int getNavigationItemCount() { + return mActionBar.getNavigationItemCount(); + } + + @Override + public void setTitle(CharSequence title) { + mActionBar.setTitle(title); + } + + @Override + public void setTitle(int resId) { + mActionBar.setTitle(resId); + } + + @Override + public void setSubtitle(CharSequence subtitle) { + mActionBar.setSubtitle(subtitle); + } + + @Override + public void setSubtitle(int resId) { + mActionBar.setSubtitle(resId); + } + + @Override + public void setDisplayOptions(int options) { + mActionBar.setDisplayOptions(options); + } + + @Override + public void setDisplayOptions(int options, int mask) { + mActionBar.setDisplayOptions(options, mask); + } + + @Override + public void setDisplayUseLogoEnabled(boolean useLogo) { + mActionBar.setDisplayUseLogoEnabled(useLogo); + } + + @Override + public void setDisplayShowHomeEnabled(boolean showHome) { + mActionBar.setDisplayShowHomeEnabled(showHome); + } + + @Override + public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) { + mActionBar.setDisplayHomeAsUpEnabled(showHomeAsUp); + } + + @Override + public void setDisplayShowTitleEnabled(boolean showTitle) { + mActionBar.setDisplayShowTitleEnabled(showTitle); + } + + @Override + public void setDisplayShowCustomEnabled(boolean showCustom) { + mActionBar.setDisplayShowCustomEnabled(showCustom); + } + + @Override + public void setBackgroundDrawable(Drawable d) { + mActionBar.setBackgroundDrawable(d); + } + + @Override + public void setStackedBackgroundDrawable(Drawable d) { + mActionBar.setStackedBackgroundDrawable(d); + } + + @Override + public void setSplitBackgroundDrawable(Drawable d) { + mActionBar.setSplitBackgroundDrawable(d); + } + + @Override + public View getCustomView() { + return mActionBar.getCustomView(); + } + + @Override + public CharSequence getTitle() { + return mActionBar.getTitle(); + } + + @Override + public CharSequence getSubtitle() { + return mActionBar.getSubtitle(); + } + + @Override + public int getNavigationMode() { + return mActionBar.getNavigationMode(); + } + + @Override + public void setNavigationMode(int mode) { + mActionBar.setNavigationMode(mode); + } + + @Override + public int getDisplayOptions() { + return mActionBar.getDisplayOptions(); + } + + public class TabWrapper extends ActionBar.Tab implements android.app.ActionBar.TabListener { + final android.app.ActionBar.Tab mNativeTab; + private Object mTag; + private TabListener mListener; + + public TabWrapper(android.app.ActionBar.Tab nativeTab) { + mNativeTab = nativeTab; + mNativeTab.setTag(this); + } + + @Override + public int getPosition() { + return mNativeTab.getPosition(); + } + + @Override + public Drawable getIcon() { + return mNativeTab.getIcon(); + } + + @Override + public CharSequence getText() { + return mNativeTab.getText(); + } + + @Override + public Tab setIcon(Drawable icon) { + mNativeTab.setIcon(icon); + return this; + } + + @Override + public Tab setIcon(int resId) { + mNativeTab.setIcon(resId); + return this; + } + + @Override + public Tab setText(CharSequence text) { + mNativeTab.setText(text); + return this; + } + + @Override + public Tab setText(int resId) { + mNativeTab.setText(resId); + return this; + } + + @Override + public Tab setCustomView(View view) { + mNativeTab.setCustomView(view); + return this; + } + + @Override + public Tab setCustomView(int layoutResId) { + mNativeTab.setCustomView(layoutResId); + return this; + } + + @Override + public View getCustomView() { + return mNativeTab.getCustomView(); + } + + @Override + public Tab setTag(Object obj) { + mTag = obj; + return this; + } + + @Override + public Object getTag() { + return mTag; + } + + @Override + public Tab setTabListener(TabListener listener) { + mNativeTab.setTabListener(listener != null ? this : null); + mListener = listener; + return this; + } + + @Override + public void select() { + mNativeTab.select(); + } + + @Override + public Tab setContentDescription(int resId) { + mNativeTab.setContentDescription(resId); + return this; + } + + @Override + public Tab setContentDescription(CharSequence contentDesc) { + mNativeTab.setContentDescription(contentDesc); + return this; + } + + @Override + public CharSequence getContentDescription() { + return mNativeTab.getContentDescription(); + } + + @Override + public void onTabReselected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { + if (mListener != null) { + FragmentTransaction trans = null; + if (mActivity instanceof FragmentActivity) { + trans = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() + .disallowAddToBackStack(); + } + + mListener.onTabReselected(this, trans); + + if (trans != null && !trans.isEmpty()) { + trans.commit(); + } + } + } + + @Override + public void onTabSelected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { + if (mListener != null) { + + if (mFragmentTransaction == null && mActivity instanceof FragmentActivity) { + mFragmentTransaction = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() + .disallowAddToBackStack(); + } + + mListener.onTabSelected(this, mFragmentTransaction); + + if (mFragmentTransaction != null) { + if (!mFragmentTransaction.isEmpty()) { + mFragmentTransaction.commit(); + } + mFragmentTransaction = null; + } + } + } + + @Override + public void onTabUnselected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { + if (mListener != null) { + FragmentTransaction trans = null; + if (mActivity instanceof FragmentActivity) { + trans = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() + .disallowAddToBackStack(); + mFragmentTransaction = trans; + } + + mListener.onTabUnselected(this, trans); + } + } + } + + @Override + public Tab newTab() { + return new TabWrapper(mActionBar.newTab()); + } + + @Override + public void addTab(Tab tab) { + mActionBar.addTab(((TabWrapper)tab).mNativeTab); + } + + @Override + public void addTab(Tab tab, boolean setSelected) { + mActionBar.addTab(((TabWrapper)tab).mNativeTab, setSelected); + } + + @Override + public void addTab(Tab tab, int position) { + mActionBar.addTab(((TabWrapper)tab).mNativeTab, position); + } + + @Override + public void addTab(Tab tab, int position, boolean setSelected) { + mActionBar.addTab(((TabWrapper)tab).mNativeTab, position, setSelected); + } + + @Override + public void removeTab(Tab tab) { + mActionBar.removeTab(((TabWrapper)tab).mNativeTab); + } + + @Override + public void removeTabAt(int position) { + mActionBar.removeTabAt(position); + } + + @Override + public void removeAllTabs() { + mActionBar.removeAllTabs(); + } + + @Override + public void selectTab(Tab tab) { + mActionBar.selectTab(((TabWrapper)tab).mNativeTab); + } + + @Override + public Tab getSelectedTab() { + android.app.ActionBar.Tab selected = mActionBar.getSelectedTab(); + return (selected != null) ? (Tab)selected.getTag() : null; + } + + @Override + public Tab getTabAt(int index) { + android.app.ActionBar.Tab selected = mActionBar.getTabAt(index); + return (selected != null) ? (Tab)selected.getTag() : null; + } + + @Override + public int getTabCount() { + return mActionBar.getTabCount(); + } + + @Override + public int getHeight() { + return mActionBar.getHeight(); + } + + @Override + public void show() { + mActionBar.show(); + } + + @Override + public void hide() { + mActionBar.hide(); + } + + @Override + public boolean isShowing() { + return mActionBar.isShowing(); + } + + @Override + public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.add(listener); + } + + @Override + public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.remove(listener); + } + + @Override + public void onMenuVisibilityChanged(boolean isVisible) { + for (OnMenuVisibilityListener listener : mMenuVisibilityListeners) { + listener.onMenuVisibilityChanged(isVisible); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java new file mode 100644 index 0000000000..9e1abc2063 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import java.util.ArrayList; + +import android.view.animation.Interpolator; + +/** + * This is the superclass for classes which provide basic support for animations which can be + * started, ended, and have AnimatorListeners added to them. + */ +public abstract class Animator implements Cloneable { + + + /** + * The set of listeners to be sent events through the life of an animation. + */ + ArrayList mListeners = null; + + /** + * Starts this animation. If the animation has a nonzero startDelay, the animation will start + * running after that delay elapses. A non-delayed animation will have its initial + * value(s) set immediately, followed by calls to + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener#onAnimationStart(com.actionbarsherlock.internal.nineoldandroids.animation.Animator)} for any listeners of this animator. + * + *

The animation started by calling this method will be run on the thread that called + * this method. This thread should have a Looper on it (a runtime exception will be thrown if + * this is not the case). Also, if the animation will animate + * properties of objects in the view hierarchy, then the calling thread should be the UI + * thread for that view hierarchy.

+ * + */ + public void start() { + } + + /** + * Cancels the animation. Unlike {@link #end()}, cancel() causes the animation to + * stop in its tracks, sending an + * {@link android.animation.Animator.AnimatorListener#onAnimationCancel(com.actionbarsherlock.internal.nineoldandroids.animation.Animator)} to + * its listeners, followed by an + * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(com.actionbarsherlock.internal.nineoldandroids.animation.Animator)} message. + * + *

This method must be called on the thread that is running the animation.

+ */ + public void cancel() { + } + + /** + * Ends the animation. This causes the animation to assign the end value of the property being + * animated, then calling the + * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(com.actionbarsherlock.internal.nineoldandroids.animation.Animator)} method on + * its listeners. + * + *

This method must be called on the thread that is running the animation.

+ */ + public void end() { + } + + /** + * The amount of time, in milliseconds, to delay starting the animation after + * {@link #start()} is called. + * + * @return the number of milliseconds to delay running the animation + */ + public abstract long getStartDelay(); + + /** + * The amount of time, in milliseconds, to delay starting the animation after + * {@link #start()} is called. + + * @param startDelay The amount of the delay, in milliseconds + */ + public abstract void setStartDelay(long startDelay); + + + /** + * Sets the length of the animation. + * + * @param duration The length of the animation, in milliseconds. + */ + public abstract Animator setDuration(long duration); + + /** + * Gets the length of the animation. + * + * @return The length of the animation, in milliseconds. + */ + public abstract long getDuration(); + + /** + * The time interpolator used in calculating the elapsed fraction of this animation. The + * interpolator determines whether the animation runs with linear or non-linear motion, + * such as acceleration and deceleration. The default value is + * {@link android.view.animation.AccelerateDecelerateInterpolator} + * + * @param value the interpolator to be used by this animation + */ + public abstract void setInterpolator(/*Time*/Interpolator value); + + /** + * Returns whether this Animator is currently running (having been started and gone past any + * initial startDelay period and not yet ended). + * + * @return Whether the Animator is running. + */ + public abstract boolean isRunning(); + + /** + * Returns whether this Animator has been started and not yet ended. This state is a superset + * of the state of {@link #isRunning()}, because an Animator with a nonzero + * {@link #getStartDelay() startDelay} will return true for {@link #isStarted()} during the + * delay phase, whereas {@link #isRunning()} will return true only after the delay phase + * is complete. + * + * @return Whether the Animator has been started and not yet ended. + */ + public boolean isStarted() { + // Default method returns value for isRunning(). Subclasses should override to return a + // real value. + return isRunning(); + } + + /** + * Adds a listener to the set of listeners that are sent events through the life of an + * animation, such as start, repeat, and end. + * + * @param listener the listener to be added to the current set of listeners for this animation. + */ + public void addListener(AnimatorListener listener) { + if (mListeners == null) { + mListeners = new ArrayList(); + } + mListeners.add(listener); + } + + /** + * Removes a listener from the set listening to this animation. + * + * @param listener the listener to be removed from the current set of listeners for this + * animation. + */ + public void removeListener(AnimatorListener listener) { + if (mListeners == null) { + return; + } + mListeners.remove(listener); + if (mListeners.size() == 0) { + mListeners = null; + } + } + + /** + * Gets the set of {@link android.animation.Animator.AnimatorListener} objects that are currently + * listening for events on this Animator object. + * + * @return ArrayList The set of listeners. + */ + public ArrayList getListeners() { + return mListeners; + } + + /** + * Removes all listeners from this object. This is equivalent to calling + * getListeners() followed by calling clear() on the + * returned list of listeners. + */ + public void removeAllListeners() { + if (mListeners != null) { + mListeners.clear(); + mListeners = null; + } + } + + @Override + public Animator clone() { + try { + final Animator anim = (Animator) super.clone(); + if (mListeners != null) { + ArrayList oldListeners = mListeners; + anim.mListeners = new ArrayList(); + int numListeners = oldListeners.size(); + for (int i = 0; i < numListeners; ++i) { + anim.mListeners.add(oldListeners.get(i)); + } + } + return anim; + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + + /** + * This method tells the object to use appropriate information to extract + * starting values for the animation. For example, a AnimatorSet object will pass + * this call to its child objects to tell them to set up the values. A + * ObjectAnimator object will use the information it has about its target object + * and PropertyValuesHolder objects to get the start values for its properties. + * An ValueAnimator object will ignore the request since it does not have enough + * information (such as a target object) to gather these values. + */ + public void setupStartValues() { + } + + /** + * This method tells the object to use appropriate information to extract + * ending values for the animation. For example, a AnimatorSet object will pass + * this call to its child objects to tell them to set up the values. A + * ObjectAnimator object will use the information it has about its target object + * and PropertyValuesHolder objects to get the start values for its properties. + * An ValueAnimator object will ignore the request since it does not have enough + * information (such as a target object) to gather these values. + */ + public void setupEndValues() { + } + + /** + * Sets the target object whose property will be animated by this animation. Not all subclasses + * operate on target objects (for example, {@link ValueAnimator}, but this method + * is on the superclass for the convenience of dealing generically with those subclasses + * that do handle targets. + * + * @param target The object being animated + */ + public void setTarget(Object target) { + } + + /** + *

An animation listener receives notifications from an animation. + * Notifications indicate animation related events, such as the end or the + * repetition of the animation.

+ */ + public static interface AnimatorListener { + /** + *

Notifies the start of the animation.

+ * + * @param animation The started animation. + */ + void onAnimationStart(Animator animation); + + /** + *

Notifies the end of the animation. This callback is not invoked + * for animations with repeat count set to INFINITE.

+ * + * @param animation The animation which reached its end. + */ + void onAnimationEnd(Animator animation); + + /** + *

Notifies the cancellation of the animation. This callback is not invoked + * for animations with repeat count set to INFINITE.

+ * + * @param animation The animation which was canceled. + */ + void onAnimationCancel(Animator animation); + + /** + *

Notifies the repetition of the animation.

+ * + * @param animation The animation which was repeated. + */ + void onAnimationRepeat(Animator animation); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java new file mode 100644 index 0000000000..02ddff48d2 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +/** + * This adapter class provides empty implementations of the methods from {@link android.animation.Animator.AnimatorListener}. + * Any custom listener that cares only about a subset of the methods of this listener can + * simply subclass this adapter class instead of implementing the interface directly. + */ +public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener { + + /** + * {@inheritDoc} + */ + @Override + public void onAnimationCancel(Animator animation) { + } + + /** + * {@inheritDoc} + */ + @Override + public void onAnimationEnd(Animator animation) { + } + + /** + * {@inheritDoc} + */ + @Override + public void onAnimationRepeat(Animator animation) { + } + + /** + * {@inheritDoc} + */ + @Override + public void onAnimationStart(Animator animation) { + } + +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java new file mode 100644 index 0000000000..cbb06657dc --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java @@ -0,0 +1,1111 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +import android.view.animation.Interpolator; + +/** + * This class plays a set of {@link Animator} objects in the specified order. Animations + * can be set up to play together, in sequence, or after a specified delay. + * + *

There are two different approaches to adding animations to a AnimatorSet: + * either the {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#playTogether(Animator[]) playTogether()} or + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#playSequentially(Animator[]) playSequentially()} methods can be called to add + * a set of animations all at once, or the {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} can be + * used in conjunction with methods in the {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet.Builder Builder} + * class to add animations + * one by one.

+ * + *

It is possible to set up a AnimatorSet with circular dependencies between + * its animations. For example, an animation a1 could be set up to start before animation a2, a2 + * before a3, and a3 before a1. The results of this configuration are undefined, but will typically + * result in none of the affected animations being played. Because of this (and because + * circular dependencies do not make logical sense anyway), circular dependencies + * should be avoided, and the dependency flow of animations should only be in one direction. + */ +@SuppressWarnings("unchecked") +public final class AnimatorSet extends Animator { + + /** + * Internal variables + * NOTE: This object implements the clone() method, making a deep copy of any referenced + * objects. As other non-trivial fields are added to this class, make sure to add logic + * to clone() to make deep copies of them. + */ + + /** + * Tracks animations currently being played, so that we know what to + * cancel or end when cancel() or end() is called on this AnimatorSet + */ + private ArrayList mPlayingSet = new ArrayList(); + + /** + * Contains all nodes, mapped to their respective Animators. When new + * dependency information is added for an Animator, we want to add it + * to a single node representing that Animator, not create a new Node + * if one already exists. + */ + private HashMap mNodeMap = new HashMap(); + + /** + * Set of all nodes created for this AnimatorSet. This list is used upon + * starting the set, and the nodes are placed in sorted order into the + * sortedNodes collection. + */ + private ArrayList mNodes = new ArrayList(); + + /** + * The sorted list of nodes. This is the order in which the animations will + * be played. The details about when exactly they will be played depend + * on the dependency relationships of the nodes. + */ + private ArrayList mSortedNodes = new ArrayList(); + + /** + * Flag indicating whether the nodes should be sorted prior to playing. This + * flag allows us to cache the previous sorted nodes so that if the sequence + * is replayed with no changes, it does not have to re-sort the nodes again. + */ + private boolean mNeedsSort = true; + + private AnimatorSetListener mSetListener = null; + + /** + * Flag indicating that the AnimatorSet has been manually + * terminated (by calling cancel() or end()). + * This flag is used to avoid starting other animations when currently-playing + * child animations of this AnimatorSet end. It also determines whether cancel/end + * notifications are sent out via the normal AnimatorSetListener mechanism. + */ + boolean mTerminated = false; + + /** + * Indicates whether an AnimatorSet has been start()'d, whether or + * not there is a nonzero startDelay. + */ + private boolean mStarted = false; + + // The amount of time in ms to delay starting the animation after start() is called + private long mStartDelay = 0; + + // Animator used for a nonzero startDelay + private ValueAnimator mDelayAnim = null; + + + // How long the child animations should last in ms. The default value is negative, which + // simply means that there is no duration set on the AnimatorSet. When a real duration is + // set, it is passed along to the child animations. + private long mDuration = -1; + + + /** + * Sets up this AnimatorSet to play all of the supplied animations at the same time. + * + * @param items The animations that will be started simultaneously. + */ + public void playTogether(Animator... items) { + if (items != null) { + mNeedsSort = true; + Builder builder = play(items[0]); + for (int i = 1; i < items.length; ++i) { + builder.with(items[i]); + } + } + } + + /** + * Sets up this AnimatorSet to play all of the supplied animations at the same time. + * + * @param items The animations that will be started simultaneously. + */ + public void playTogether(Collection items) { + if (items != null && items.size() > 0) { + mNeedsSort = true; + Builder builder = null; + for (Animator anim : items) { + if (builder == null) { + builder = play(anim); + } else { + builder.with(anim); + } + } + } + } + + /** + * Sets up this AnimatorSet to play each of the supplied animations when the + * previous animation ends. + * + * @param items The animations that will be started one after another. + */ + public void playSequentially(Animator... items) { + if (items != null) { + mNeedsSort = true; + if (items.length == 1) { + play(items[0]); + } else { + for (int i = 0; i < items.length - 1; ++i) { + play(items[i]).before(items[i+1]); + } + } + } + } + + /** + * Sets up this AnimatorSet to play each of the supplied animations when the + * previous animation ends. + * + * @param items The animations that will be started one after another. + */ + public void playSequentially(List items) { + if (items != null && items.size() > 0) { + mNeedsSort = true; + if (items.size() == 1) { + play(items.get(0)); + } else { + for (int i = 0; i < items.size() - 1; ++i) { + play(items.get(i)).before(items.get(i+1)); + } + } + } + } + + /** + * Returns the current list of child Animator objects controlled by this + * AnimatorSet. This is a copy of the internal list; modifications to the returned list + * will not affect the AnimatorSet, although changes to the underlying Animator objects + * will affect those objects being managed by the AnimatorSet. + * + * @return ArrayList The list of child animations of this AnimatorSet. + */ + public ArrayList getChildAnimations() { + ArrayList childList = new ArrayList(); + for (Node node : mNodes) { + childList.add(node.animation); + } + return childList; + } + + /** + * Sets the target object for all current {@link #getChildAnimations() child animations} + * of this AnimatorSet that take targets ({@link ObjectAnimator} and + * AnimatorSet). + * + * @param target The object being animated + */ + @Override + public void setTarget(Object target) { + for (Node node : mNodes) { + Animator animation = node.animation; + if (animation instanceof AnimatorSet) { + ((AnimatorSet)animation).setTarget(target); + } else if (animation instanceof ObjectAnimator) { + ((ObjectAnimator)animation).setTarget(target); + } + } + } + + /** + * Sets the TimeInterpolator for all current {@link #getChildAnimations() child animations} + * of this AnimatorSet. + * + * @param interpolator the interpolator to be used by each child animation of this AnimatorSet + */ + @Override + public void setInterpolator(/*Time*/Interpolator interpolator) { + for (Node node : mNodes) { + node.animation.setInterpolator(interpolator); + } + } + + /** + * This method creates a Builder object, which is used to + * set up playing constraints. This initial play() method + * tells the Builder the animation that is the dependency for + * the succeeding commands to the Builder. For example, + * calling play(a1).with(a2) sets up the AnimatorSet to play + * a1 and a2 at the same time, + * play(a1).before(a2) sets up the AnimatorSet to play + * a1 first, followed by a2, and + * play(a1).after(a2) sets up the AnimatorSet to play + * a2 first, followed by a1. + * + *

Note that play() is the only way to tell the + * Builder the animation upon which the dependency is created, + * so successive calls to the various functions in Builder + * will all refer to the initial parameter supplied in play() + * as the dependency of the other animations. For example, calling + * play(a1).before(a2).before(a3) will play both a2 + * and a3 when a1 ends; it does not set up a dependency between + * a2 and a3.

+ * + * @param anim The animation that is the dependency used in later calls to the + * methods in the returned Builder object. A null parameter will result + * in a null Builder return value. + * @return Builder The object that constructs the AnimatorSet based on the dependencies + * outlined in the calls to play and the other methods in the + * BuilderNote that canceling a AnimatorSet also cancels all of the animations that it + * is responsible for.

+ */ + @Override + public void cancel() { + mTerminated = true; + if (isStarted()) { + ArrayList tmpListeners = null; + if (mListeners != null) { + tmpListeners = (ArrayList) mListeners.clone(); + for (AnimatorListener listener : tmpListeners) { + listener.onAnimationCancel(this); + } + } + if (mDelayAnim != null && mDelayAnim.isRunning()) { + // If we're currently in the startDelay period, just cancel that animator and + // send out the end event to all listeners + mDelayAnim.cancel(); + } else if (mSortedNodes.size() > 0) { + for (Node node : mSortedNodes) { + node.animation.cancel(); + } + } + if (tmpListeners != null) { + for (AnimatorListener listener : tmpListeners) { + listener.onAnimationEnd(this); + } + } + mStarted = false; + } + } + + /** + * {@inheritDoc} + * + *

Note that ending a AnimatorSet also ends all of the animations that it is + * responsible for.

+ */ + @Override + public void end() { + mTerminated = true; + if (isStarted()) { + if (mSortedNodes.size() != mNodes.size()) { + // hasn't been started yet - sort the nodes now, then end them + sortNodes(); + for (Node node : mSortedNodes) { + if (mSetListener == null) { + mSetListener = new AnimatorSetListener(this); + } + node.animation.addListener(mSetListener); + } + } + if (mDelayAnim != null) { + mDelayAnim.cancel(); + } + if (mSortedNodes.size() > 0) { + for (Node node : mSortedNodes) { + node.animation.end(); + } + } + if (mListeners != null) { + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + for (AnimatorListener listener : tmpListeners) { + listener.onAnimationEnd(this); + } + } + mStarted = false; + } + } + + /** + * Returns true if any of the child animations of this AnimatorSet have been started and have + * not yet ended. + * @return Whether this AnimatorSet has been started and has not yet ended. + */ + @Override + public boolean isRunning() { + for (Node node : mNodes) { + if (node.animation.isRunning()) { + return true; + } + } + return false; + } + + @Override + public boolean isStarted() { + return mStarted; + } + + /** + * The amount of time, in milliseconds, to delay starting the animation after + * {@link #start()} is called. + * + * @return the number of milliseconds to delay running the animation + */ + @Override + public long getStartDelay() { + return mStartDelay; + } + + /** + * The amount of time, in milliseconds, to delay starting the animation after + * {@link #start()} is called. + + * @param startDelay The amount of the delay, in milliseconds + */ + @Override + public void setStartDelay(long startDelay) { + mStartDelay = startDelay; + } + + /** + * Gets the length of each of the child animations of this AnimatorSet. This value may + * be less than 0, which indicates that no duration has been set on this AnimatorSet + * and each of the child animations will use their own duration. + * + * @return The length of the animation, in milliseconds, of each of the child + * animations of this AnimatorSet. + */ + @Override + public long getDuration() { + return mDuration; + } + + /** + * Sets the length of each of the current child animations of this AnimatorSet. By default, + * each child animation will use its own duration. If the duration is set on the AnimatorSet, + * then each child animation inherits this duration. + * + * @param duration The length of the animation, in milliseconds, of each of the child + * animations of this AnimatorSet. + */ + @Override + public AnimatorSet setDuration(long duration) { + if (duration < 0) { + throw new IllegalArgumentException("duration must be a value of zero or greater"); + } + for (Node node : mNodes) { + // TODO: don't set the duration of the timing-only nodes created by AnimatorSet to + // insert "play-after" delays + node.animation.setDuration(duration); + } + mDuration = duration; + return this; + } + + @Override + public void setupStartValues() { + for (Node node : mNodes) { + node.animation.setupStartValues(); + } + } + + @Override + public void setupEndValues() { + for (Node node : mNodes) { + node.animation.setupEndValues(); + } + } + + /** + * {@inheritDoc} + * + *

Starting this AnimatorSet will, in turn, start the animations for which + * it is responsible. The details of when exactly those animations are started depends on + * the dependency relationships that have been set up between the animations. + */ + @Override + public void start() { + mTerminated = false; + mStarted = true; + + // First, sort the nodes (if necessary). This will ensure that sortedNodes + // contains the animation nodes in the correct order. + sortNodes(); + + int numSortedNodes = mSortedNodes.size(); + for (int i = 0; i < numSortedNodes; ++i) { + Node node = mSortedNodes.get(i); + // First, clear out the old listeners + ArrayList oldListeners = node.animation.getListeners(); + if (oldListeners != null && oldListeners.size() > 0) { + final ArrayList clonedListeners = new + ArrayList(oldListeners); + + for (AnimatorListener listener : clonedListeners) { + if (listener instanceof DependencyListener || + listener instanceof AnimatorSetListener) { + node.animation.removeListener(listener); + } + } + } + } + + // nodesToStart holds the list of nodes to be started immediately. We don't want to + // start the animations in the loop directly because we first need to set up + // dependencies on all of the nodes. For example, we don't want to start an animation + // when some other animation also wants to start when the first animation begins. + final ArrayList nodesToStart = new ArrayList(); + for (int i = 0; i < numSortedNodes; ++i) { + Node node = mSortedNodes.get(i); + if (mSetListener == null) { + mSetListener = new AnimatorSetListener(this); + } + if (node.dependencies == null || node.dependencies.size() == 0) { + nodesToStart.add(node); + } else { + int numDependencies = node.dependencies.size(); + for (int j = 0; j < numDependencies; ++j) { + Dependency dependency = node.dependencies.get(j); + dependency.node.animation.addListener( + new DependencyListener(this, node, dependency.rule)); + } + node.tmpDependencies = (ArrayList) node.dependencies.clone(); + } + node.animation.addListener(mSetListener); + } + // Now that all dependencies are set up, start the animations that should be started. + if (mStartDelay <= 0) { + for (Node node : nodesToStart) { + node.animation.start(); + mPlayingSet.add(node.animation); + } + } else { + mDelayAnim = ValueAnimator.ofFloat(0f, 1f); + mDelayAnim.setDuration(mStartDelay); + mDelayAnim.addListener(new AnimatorListenerAdapter() { + boolean canceled = false; + public void onAnimationCancel(Animator anim) { + canceled = true; + } + public void onAnimationEnd(Animator anim) { + if (!canceled) { + int numNodes = nodesToStart.size(); + for (int i = 0; i < numNodes; ++i) { + Node node = nodesToStart.get(i); + node.animation.start(); + mPlayingSet.add(node.animation); + } + } + } + }); + mDelayAnim.start(); + } + if (mListeners != null) { + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onAnimationStart(this); + } + } + if (mNodes.size() == 0 && mStartDelay == 0) { + // Handle unusual case where empty AnimatorSet is started - should send out + // end event immediately since the event will not be sent out at all otherwise + mStarted = false; + if (mListeners != null) { + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onAnimationEnd(this); + } + } + } + } + + @Override + public AnimatorSet clone() { + final AnimatorSet anim = (AnimatorSet) super.clone(); + /* + * The basic clone() operation copies all items. This doesn't work very well for + * AnimatorSet, because it will copy references that need to be recreated and state + * that may not apply. What we need to do now is put the clone in an uninitialized + * state, with fresh, empty data structures. Then we will build up the nodes list + * manually, as we clone each Node (and its animation). The clone will then be sorted, + * and will populate any appropriate lists, when it is started. + */ + anim.mNeedsSort = true; + anim.mTerminated = false; + anim.mStarted = false; + anim.mPlayingSet = new ArrayList(); + anim.mNodeMap = new HashMap(); + anim.mNodes = new ArrayList(); + anim.mSortedNodes = new ArrayList(); + + // Walk through the old nodes list, cloning each node and adding it to the new nodemap. + // One problem is that the old node dependencies point to nodes in the old AnimatorSet. + // We need to track the old/new nodes in order to reconstruct the dependencies in the clone. + HashMap nodeCloneMap = new HashMap(); // + for (Node node : mNodes) { + Node nodeClone = node.clone(); + nodeCloneMap.put(node, nodeClone); + anim.mNodes.add(nodeClone); + anim.mNodeMap.put(nodeClone.animation, nodeClone); + // Clear out the dependencies in the clone; we'll set these up manually later + nodeClone.dependencies = null; + nodeClone.tmpDependencies = null; + nodeClone.nodeDependents = null; + nodeClone.nodeDependencies = null; + // clear out any listeners that were set up by the AnimatorSet; these will + // be set up when the clone's nodes are sorted + ArrayList cloneListeners = nodeClone.animation.getListeners(); + if (cloneListeners != null) { + ArrayList listenersToRemove = null; + for (AnimatorListener listener : cloneListeners) { + if (listener instanceof AnimatorSetListener) { + if (listenersToRemove == null) { + listenersToRemove = new ArrayList(); + } + listenersToRemove.add(listener); + } + } + if (listenersToRemove != null) { + for (AnimatorListener listener : listenersToRemove) { + cloneListeners.remove(listener); + } + } + } + } + // Now that we've cloned all of the nodes, we're ready to walk through their + // dependencies, mapping the old dependencies to the new nodes + for (Node node : mNodes) { + Node nodeClone = nodeCloneMap.get(node); + if (node.dependencies != null) { + for (Dependency dependency : node.dependencies) { + Node clonedDependencyNode = nodeCloneMap.get(dependency.node); + Dependency cloneDependency = new Dependency(clonedDependencyNode, + dependency.rule); + nodeClone.addDependency(cloneDependency); + } + } + } + + return anim; + } + + /** + * This class is the mechanism by which animations are started based on events in other + * animations. If an animation has multiple dependencies on other animations, then + * all dependencies must be satisfied before the animation is started. + */ + private static class DependencyListener implements AnimatorListener { + + private AnimatorSet mAnimatorSet; + + // The node upon which the dependency is based. + private Node mNode; + + // The Dependency rule (WITH or AFTER) that the listener should wait for on + // the node + private int mRule; + + public DependencyListener(AnimatorSet animatorSet, Node node, int rule) { + this.mAnimatorSet = animatorSet; + this.mNode = node; + this.mRule = rule; + } + + /** + * Ignore cancel events for now. We may want to handle this eventually, + * to prevent follow-on animations from running when some dependency + * animation is canceled. + */ + public void onAnimationCancel(Animator animation) { + } + + /** + * An end event is received - see if this is an event we are listening for + */ + public void onAnimationEnd(Animator animation) { + if (mRule == Dependency.AFTER) { + startIfReady(animation); + } + } + + /** + * Ignore repeat events for now + */ + public void onAnimationRepeat(Animator animation) { + } + + /** + * A start event is received - see if this is an event we are listening for + */ + public void onAnimationStart(Animator animation) { + if (mRule == Dependency.WITH) { + startIfReady(animation); + } + } + + /** + * Check whether the event received is one that the node was waiting for. + * If so, mark it as complete and see whether it's time to start + * the animation. + * @param dependencyAnimation the animation that sent the event. + */ + private void startIfReady(Animator dependencyAnimation) { + if (mAnimatorSet.mTerminated) { + // if the parent AnimatorSet was canceled, then don't start any dependent anims + return; + } + Dependency dependencyToRemove = null; + int numDependencies = mNode.tmpDependencies.size(); + for (int i = 0; i < numDependencies; ++i) { + Dependency dependency = mNode.tmpDependencies.get(i); + if (dependency.rule == mRule && + dependency.node.animation == dependencyAnimation) { + // rule fired - remove the dependency and listener and check to + // see whether it's time to start the animation + dependencyToRemove = dependency; + dependencyAnimation.removeListener(this); + break; + } + } + mNode.tmpDependencies.remove(dependencyToRemove); + if (mNode.tmpDependencies.size() == 0) { + // all dependencies satisfied: start the animation + mNode.animation.start(); + mAnimatorSet.mPlayingSet.add(mNode.animation); + } + } + + } + + private class AnimatorSetListener implements AnimatorListener { + + private AnimatorSet mAnimatorSet; + + AnimatorSetListener(AnimatorSet animatorSet) { + mAnimatorSet = animatorSet; + } + + public void onAnimationCancel(Animator animation) { + if (!mTerminated) { + // Listeners are already notified of the AnimatorSet canceling in cancel(). + // The logic below only kicks in when animations end normally + if (mPlayingSet.size() == 0) { + if (mListeners != null) { + int numListeners = mListeners.size(); + for (int i = 0; i < numListeners; ++i) { + mListeners.get(i).onAnimationCancel(mAnimatorSet); + } + } + } + } + } + + public void onAnimationEnd(Animator animation) { + animation.removeListener(this); + mPlayingSet.remove(animation); + Node animNode = mAnimatorSet.mNodeMap.get(animation); + animNode.done = true; + if (!mTerminated) { + // Listeners are already notified of the AnimatorSet ending in cancel() or + // end(); the logic below only kicks in when animations end normally + ArrayList sortedNodes = mAnimatorSet.mSortedNodes; + boolean allDone = true; + int numSortedNodes = sortedNodes.size(); + for (int i = 0; i < numSortedNodes; ++i) { + if (!sortedNodes.get(i).done) { + allDone = false; + break; + } + } + if (allDone) { + // If this was the last child animation to end, then notify listeners that this + // AnimatorSet has ended + if (mListeners != null) { + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onAnimationEnd(mAnimatorSet); + } + } + mAnimatorSet.mStarted = false; + } + } + } + + // Nothing to do + public void onAnimationRepeat(Animator animation) { + } + + // Nothing to do + public void onAnimationStart(Animator animation) { + } + + } + + /** + * This method sorts the current set of nodes, if needed. The sort is a simple + * DependencyGraph sort, which goes like this: + * - All nodes without dependencies become 'roots' + * - while roots list is not null + * - for each root r + * - add r to sorted list + * - remove r as a dependency from any other node + * - any nodes with no dependencies are added to the roots list + */ + private void sortNodes() { + if (mNeedsSort) { + mSortedNodes.clear(); + ArrayList roots = new ArrayList(); + int numNodes = mNodes.size(); + for (int i = 0; i < numNodes; ++i) { + Node node = mNodes.get(i); + if (node.dependencies == null || node.dependencies.size() == 0) { + roots.add(node); + } + } + ArrayList tmpRoots = new ArrayList(); + while (roots.size() > 0) { + int numRoots = roots.size(); + for (int i = 0; i < numRoots; ++i) { + Node root = roots.get(i); + mSortedNodes.add(root); + if (root.nodeDependents != null) { + int numDependents = root.nodeDependents.size(); + for (int j = 0; j < numDependents; ++j) { + Node node = root.nodeDependents.get(j); + node.nodeDependencies.remove(root); + if (node.nodeDependencies.size() == 0) { + tmpRoots.add(node); + } + } + } + } + roots.clear(); + roots.addAll(tmpRoots); + tmpRoots.clear(); + } + mNeedsSort = false; + if (mSortedNodes.size() != mNodes.size()) { + throw new IllegalStateException("Circular dependencies cannot exist" + + " in AnimatorSet"); + } + } else { + // Doesn't need sorting, but still need to add in the nodeDependencies list + // because these get removed as the event listeners fire and the dependencies + // are satisfied + int numNodes = mNodes.size(); + for (int i = 0; i < numNodes; ++i) { + Node node = mNodes.get(i); + if (node.dependencies != null && node.dependencies.size() > 0) { + int numDependencies = node.dependencies.size(); + for (int j = 0; j < numDependencies; ++j) { + Dependency dependency = node.dependencies.get(j); + if (node.nodeDependencies == null) { + node.nodeDependencies = new ArrayList(); + } + if (!node.nodeDependencies.contains(dependency.node)) { + node.nodeDependencies.add(dependency.node); + } + } + } + // nodes are 'done' by default; they become un-done when started, and done + // again when ended + node.done = false; + } + } + } + + /** + * Dependency holds information about the node that some other node is + * dependent upon and the nature of that dependency. + * + */ + private static class Dependency { + static final int WITH = 0; // dependent node must start with this dependency node + static final int AFTER = 1; // dependent node must start when this dependency node finishes + + // The node that the other node with this Dependency is dependent upon + public Node node; + + // The nature of the dependency (WITH or AFTER) + public int rule; + + public Dependency(Node node, int rule) { + this.node = node; + this.rule = rule; + } + } + + /** + * A Node is an embodiment of both the Animator that it wraps as well as + * any dependencies that are associated with that Animation. This includes + * both dependencies upon other nodes (in the dependencies list) as + * well as dependencies of other nodes upon this (in the nodeDependents list). + */ + private static class Node implements Cloneable { + public Animator animation; + + /** + * These are the dependencies that this node's animation has on other + * nodes. For example, if this node's animation should begin with some + * other animation ends, then there will be an item in this node's + * dependencies list for that other animation's node. + */ + public ArrayList dependencies = null; + + /** + * tmpDependencies is a runtime detail. We use the dependencies list for sorting. + * But we also use the list to keep track of when multiple dependencies are satisfied, + * but removing each dependency as it is satisfied. We do not want to remove + * the dependency itself from the list, because we need to retain that information + * if the AnimatorSet is launched in the future. So we create a copy of the dependency + * list when the AnimatorSet starts and use this tmpDependencies list to track the + * list of satisfied dependencies. + */ + public ArrayList tmpDependencies = null; + + /** + * nodeDependencies is just a list of the nodes that this Node is dependent upon. + * This information is used in sortNodes(), to determine when a node is a root. + */ + public ArrayList nodeDependencies = null; + + /** + * nodeDepdendents is the list of nodes that have this node as a dependency. This + * is a utility field used in sortNodes to facilitate removing this node as a + * dependency when it is a root node. + */ + public ArrayList nodeDependents = null; + + /** + * Flag indicating whether the animation in this node is finished. This flag + * is used by AnimatorSet to check, as each animation ends, whether all child animations + * are done and it's time to send out an end event for the entire AnimatorSet. + */ + public boolean done = false; + + /** + * Constructs the Node with the animation that it encapsulates. A Node has no + * dependencies by default; dependencies are added via the addDependency() + * method. + * + * @param animation The animation that the Node encapsulates. + */ + public Node(Animator animation) { + this.animation = animation; + } + + /** + * Add a dependency to this Node. The dependency includes information about the + * node that this node is dependency upon and the nature of the dependency. + * @param dependency + */ + public void addDependency(Dependency dependency) { + if (dependencies == null) { + dependencies = new ArrayList(); + nodeDependencies = new ArrayList(); + } + dependencies.add(dependency); + if (!nodeDependencies.contains(dependency.node)) { + nodeDependencies.add(dependency.node); + } + Node dependencyNode = dependency.node; + if (dependencyNode.nodeDependents == null) { + dependencyNode.nodeDependents = new ArrayList(); + } + dependencyNode.nodeDependents.add(this); + } + + @Override + public Node clone() { + try { + Node node = (Node) super.clone(); + node.animation = animation.clone(); + return node; + } catch (CloneNotSupportedException e) { + throw new AssertionError(); + } + } + } + + /** + * The Builder object is a utility class to facilitate adding animations to a + * AnimatorSet along with the relationships between the various animations. The + * intention of the Builder methods, along with the {@link + * com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator) play()} method of AnimatorSet is to make it possible + * to express the dependency relationships of animations in a natural way. Developers can also + * use the {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#playTogether(Animator[]) playTogether()} and {@link + * com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#playSequentially(Animator[]) playSequentially()} methods if these suit the need, + * but it might be easier in some situations to express the AnimatorSet of animations in pairs. + *

+ *

The Builder object cannot be constructed directly, but is rather constructed + * internally via a call to {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)}.

+ *

+ *

For example, this sets up a AnimatorSet to play anim1 and anim2 at the same time, anim3 to + * play when anim2 finishes, and anim4 to play when anim3 finishes:

+ *
+     *     AnimatorSet s = new AnimatorSet();
+     *     s.play(anim1).with(anim2);
+     *     s.play(anim2).before(anim3);
+     *     s.play(anim4).after(anim3);
+     * 
+ *

+ *

Note in the example that both {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet.Builder#before(Animator)} and {@link + * com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet.Builder#after(Animator)} are used. These are just different ways of expressing the same + * relationship and are provided to make it easier to say things in a way that is more natural, + * depending on the situation.

+ *

+ *

It is possible to make several calls into the same Builder object to express + * multiple relationships. However, note that it is only the animation passed into the initial + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} method that is the dependency in any of the successive + * calls to the Builder object. For example, the following code starts both anim2 + * and anim3 when anim1 ends; there is no direct dependency relationship between anim2 and + * anim3: + *

+     *   AnimatorSet s = new AnimatorSet();
+     *   s.play(anim1).before(anim2).before(anim3);
+     * 
+ * If the desired result is to play anim1 then anim2 then anim3, this code expresses the + * relationship correctly:

+ *
+     *   AnimatorSet s = new AnimatorSet();
+     *   s.play(anim1).before(anim2);
+     *   s.play(anim2).before(anim3);
+     * 
+ *

+ *

Note that it is possible to express relationships that cannot be resolved and will not + * result in sensible results. For example, play(anim1).after(anim1) makes no + * sense. In general, circular dependencies like this one (or more indirect ones where a depends + * on b, which depends on c, which depends on a) should be avoided. Only create AnimatorSets + * that can boil down to a simple, one-way relationship of animations starting with, before, and + * after other, different, animations.

+ */ + public class Builder { + + /** + * This tracks the current node being processed. It is supplied to the play() method + * of AnimatorSet and passed into the constructor of Builder. + */ + private Node mCurrentNode; + + /** + * package-private constructor. Builders are only constructed by AnimatorSet, when the + * play() method is called. + * + * @param anim The animation that is the dependency for the other animations passed into + * the other methods of this Builder object. + */ + Builder(Animator anim) { + mCurrentNode = mNodeMap.get(anim); + if (mCurrentNode == null) { + mCurrentNode = new Node(anim); + mNodeMap.put(anim, mCurrentNode); + mNodes.add(mCurrentNode); + } + } + + /** + * Sets up the given animation to play at the same time as the animation supplied in the + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} call that created this Builder object. + * + * @param anim The animation that will play when the animation supplied to the + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} method starts. + */ + public Builder with(Animator anim) { + Node node = mNodeMap.get(anim); + if (node == null) { + node = new Node(anim); + mNodeMap.put(anim, node); + mNodes.add(node); + } + Dependency dependency = new Dependency(mCurrentNode, Dependency.WITH); + node.addDependency(dependency); + return this; + } + + /** + * Sets up the given animation to play when the animation supplied in the + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} call that created this Builder object + * ends. + * + * @param anim The animation that will play when the animation supplied to the + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} method ends. + */ + public Builder before(Animator anim) { + Node node = mNodeMap.get(anim); + if (node == null) { + node = new Node(anim); + mNodeMap.put(anim, node); + mNodes.add(node); + } + Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER); + node.addDependency(dependency); + return this; + } + + /** + * Sets up the given animation to play when the animation supplied in the + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} call that created this Builder object + * to start when the animation supplied in this method call ends. + * + * @param anim The animation whose end will cause the animation supplied to the + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} method to play. + */ + public Builder after(Animator anim) { + Node node = mNodeMap.get(anim); + if (node == null) { + node = new Node(anim); + mNodeMap.put(anim, node); + mNodes.add(node); + } + Dependency dependency = new Dependency(node, Dependency.AFTER); + mCurrentNode.addDependency(dependency); + return this; + } + + /** + * Sets up the animation supplied in the + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet#play(Animator)} call that created this Builder object + * to play when the given amount of time elapses. + * + * @param delay The number of milliseconds that should elapse before the + * animation starts. + */ + public Builder after(long delay) { + // setup dummy ValueAnimator just to run the clock + ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); + anim.setDuration(delay); + after(anim); + return this; + } + + } + +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java new file mode 100644 index 0000000000..e41019364d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +/** + * This evaluator can be used to perform type interpolation between float values. + */ +public class FloatEvaluator implements TypeEvaluator { + + /** + * This function returns the result of linearly interpolating the start and end values, with + * fraction representing the proportion between the start and end values. The + * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), + * where x0 is startValue, x1 is endValue, + * and t is fraction. + * + * @param fraction The fraction from the starting to the ending values + * @param startValue The start value; should be of type float or + * Float + * @param endValue The end value; should be of type float or Float + * @return A linear interpolation between the start and end values, given the + * fraction parameter. + */ + public Float evaluate(float fraction, Number startValue, Number endValue) { + float startFloat = startValue.floatValue(); + return startFloat + fraction * (endValue.floatValue() - startFloat); + } +} \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java new file mode 100644 index 0000000000..6d9dafa7a4 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import java.util.ArrayList; +import android.view.animation.Interpolator; + +import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.FloatKeyframe; + +/** + * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate + * values between those keyframes for a given animation. The class internal to the animation + * package because it is an implementation detail of how Keyframes are stored and used. + * + *

This type-specific subclass of KeyframeSet, along with the other type-specific subclass for + * int, exists to speed up the getValue() method when there is no custom + * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the + * Object equivalents of these primitive types.

+ */ +@SuppressWarnings("unchecked") +class FloatKeyframeSet extends KeyframeSet { + private float firstValue; + private float lastValue; + private float deltaValue; + private boolean firstTime = true; + + public FloatKeyframeSet(FloatKeyframe... keyframes) { + super(keyframes); + } + + @Override + public Object getValue(float fraction) { + return getFloatValue(fraction); + } + + @Override + public FloatKeyframeSet clone() { + ArrayList keyframes = mKeyframes; + int numKeyframes = mKeyframes.size(); + FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes]; + for (int i = 0; i < numKeyframes; ++i) { + newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone(); + } + FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes); + return newSet; + } + + public float getFloatValue(float fraction) { + if (mNumKeyframes == 2) { + if (firstTime) { + firstTime = false; + firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue(); + lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue(); + deltaValue = lastValue - firstValue; + } + if (mInterpolator != null) { + fraction = mInterpolator.getInterpolation(fraction); + } + if (mEvaluator == null) { + return firstValue + fraction * deltaValue; + } else { + return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue(); + } + } + if (fraction <= 0f) { + final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); + final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1); + float prevValue = prevKeyframe.getFloatValue(); + float nextValue = nextKeyframe.getFloatValue(); + float prevFraction = prevKeyframe.getFraction(); + float nextFraction = nextKeyframe.getFraction(); + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); + return mEvaluator == null ? + prevValue + intervalFraction * (nextValue - prevValue) : + ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). + floatValue(); + } else if (fraction >= 1f) { + final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2); + final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1); + float prevValue = prevKeyframe.getFloatValue(); + float nextValue = nextKeyframe.getFloatValue(); + float prevFraction = prevKeyframe.getFraction(); + float nextFraction = nextKeyframe.getFraction(); + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); + return mEvaluator == null ? + prevValue + intervalFraction * (nextValue - prevValue) : + ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). + floatValue(); + } + FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); + for (int i = 1; i < mNumKeyframes; ++i) { + FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i); + if (fraction < nextKeyframe.getFraction()) { + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + float intervalFraction = (fraction - prevKeyframe.getFraction()) / + (nextKeyframe.getFraction() - prevKeyframe.getFraction()); + float prevValue = prevKeyframe.getFloatValue(); + float nextValue = nextKeyframe.getFloatValue(); + return mEvaluator == null ? + prevValue + intervalFraction * (nextValue - prevValue) : + ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). + floatValue(); + } + prevKeyframe = nextKeyframe; + } + // shouldn't get here + return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue(); + } + +} + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java new file mode 100644 index 0000000000..ed5e79ec64 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +/** + * This evaluator can be used to perform type interpolation between int values. + */ +public class IntEvaluator implements TypeEvaluator { + + /** + * This function returns the result of linearly interpolating the start and end values, with + * fraction representing the proportion between the start and end values. The + * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), + * where x0 is startValue, x1 is endValue, + * and t is fraction. + * + * @param fraction The fraction from the starting to the ending values + * @param startValue The start value; should be of type int or + * Integer + * @param endValue The end value; should be of type int or Integer + * @return A linear interpolation between the start and end values, given the + * fraction parameter. + */ + public Integer evaluate(float fraction, Integer startValue, Integer endValue) { + int startInt = startValue; + return (int)(startInt + fraction * (endValue - startInt)); + } +} \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java new file mode 100644 index 0000000000..e9215e7f8c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import java.util.ArrayList; +import android.view.animation.Interpolator; + +import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.IntKeyframe; + +/** + * This class holds a collection of IntKeyframe objects and is called by ValueAnimator to calculate + * values between those keyframes for a given animation. The class internal to the animation + * package because it is an implementation detail of how Keyframes are stored and used. + * + *

This type-specific subclass of KeyframeSet, along with the other type-specific subclass for + * float, exists to speed up the getValue() method when there is no custom + * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the + * Object equivalents of these primitive types.

+ */ +@SuppressWarnings("unchecked") +class IntKeyframeSet extends KeyframeSet { + private int firstValue; + private int lastValue; + private int deltaValue; + private boolean firstTime = true; + + public IntKeyframeSet(IntKeyframe... keyframes) { + super(keyframes); + } + + @Override + public Object getValue(float fraction) { + return getIntValue(fraction); + } + + @Override + public IntKeyframeSet clone() { + ArrayList keyframes = mKeyframes; + int numKeyframes = mKeyframes.size(); + IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes]; + for (int i = 0; i < numKeyframes; ++i) { + newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone(); + } + IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes); + return newSet; + } + + public int getIntValue(float fraction) { + if (mNumKeyframes == 2) { + if (firstTime) { + firstTime = false; + firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue(); + lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue(); + deltaValue = lastValue - firstValue; + } + if (mInterpolator != null) { + fraction = mInterpolator.getInterpolation(fraction); + } + if (mEvaluator == null) { + return firstValue + (int)(fraction * deltaValue); + } else { + return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue(); + } + } + if (fraction <= 0f) { + final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0); + final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1); + int prevValue = prevKeyframe.getIntValue(); + int nextValue = nextKeyframe.getIntValue(); + float prevFraction = prevKeyframe.getFraction(); + float nextFraction = nextKeyframe.getFraction(); + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); + return mEvaluator == null ? + prevValue + (int)(intervalFraction * (nextValue - prevValue)) : + ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). + intValue(); + } else if (fraction >= 1f) { + final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2); + final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1); + int prevValue = prevKeyframe.getIntValue(); + int nextValue = nextKeyframe.getIntValue(); + float prevFraction = prevKeyframe.getFraction(); + float nextFraction = nextKeyframe.getFraction(); + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); + return mEvaluator == null ? + prevValue + (int)(intervalFraction * (nextValue - prevValue)) : + ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue(); + } + IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0); + for (int i = 1; i < mNumKeyframes; ++i) { + IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i); + if (fraction < nextKeyframe.getFraction()) { + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + float intervalFraction = (fraction - prevKeyframe.getFraction()) / + (nextKeyframe.getFraction() - prevKeyframe.getFraction()); + int prevValue = prevKeyframe.getIntValue(); + int nextValue = nextKeyframe.getIntValue(); + return mEvaluator == null ? + prevValue + (int)(intervalFraction * (nextValue - prevValue)) : + ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). + intValue(); + } + prevKeyframe = nextKeyframe; + } + // shouldn't get here + return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue(); + } + +} + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java new file mode 100644 index 0000000000..ab76fa7f68 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import android.view.animation.Interpolator; + +/** + * This class holds a time/value pair for an animation. The Keyframe class is used + * by {@link ValueAnimator} to define the values that the animation target will have over the course + * of the animation. As the time proceeds from one keyframe to the other, the value of the + * target object will animate between the value at the previous keyframe and the value at the + * next keyframe. Each keyframe also holds an optional {@link TimeInterpolator} + * object, which defines the time interpolation over the intervalue preceding the keyframe. + * + *

The Keyframe class itself is abstract. The type-specific factory methods will return + * a subclass of Keyframe specific to the type of value being stored. This is done to improve + * performance when dealing with the most common cases (e.g., float and + * int values). Other types will fall into a more general Keyframe class that + * treats its values as Objects. Unless your animation requires dealing with a custom type + * or a data structure that needs to be animated directly (and evaluated using an implementation + * of {@link TypeEvaluator}), you should stick to using float and int as animations using those + * types have lower runtime overhead than other types.

+ */ +@SuppressWarnings("rawtypes") +public abstract class Keyframe implements Cloneable { + /** + * The time at which mValue will hold true. + */ + float mFraction; + + /** + * The type of the value in this Keyframe. This type is determined at construction time, + * based on the type of the value object passed into the constructor. + */ + Class mValueType; + + /** + * The optional time interpolator for the interval preceding this keyframe. A null interpolator + * (the default) results in linear interpolation over the interval. + */ + private /*Time*/Interpolator mInterpolator = null; + + /** + * Flag to indicate whether this keyframe has a valid value. This flag is used when an + * animation first starts, to populate placeholder keyframes with real values derived + * from the target object. + */ + boolean mHasValue = false; + + /** + * Constructs a Keyframe object with the given time and value. The time defines the + * time, as a proportion of an overall animation's duration, at which the value will hold true + * for the animation. The value for the animation between keyframes will be calculated as + * an interpolation between the values at those keyframes. + * + * @param fraction The time, expressed as a value between 0 and 1, representing the fraction + * of time elapsed of the overall animation duration. + * @param value The value that the object will animate to as the animation time approaches + * the time in this keyframe, and the the value animated from as the time passes the time in + * this keyframe. + */ + public static Keyframe ofInt(float fraction, int value) { + return new IntKeyframe(fraction, value); + } + + /** + * Constructs a Keyframe object with the given time. The value at this time will be derived + * from the target object when the animation first starts (note that this implies that keyframes + * with no initial value must be used as part of an {@link ObjectAnimator}). + * The time defines the + * time, as a proportion of an overall animation's duration, at which the value will hold true + * for the animation. The value for the animation between keyframes will be calculated as + * an interpolation between the values at those keyframes. + * + * @param fraction The time, expressed as a value between 0 and 1, representing the fraction + * of time elapsed of the overall animation duration. + */ + public static Keyframe ofInt(float fraction) { + return new IntKeyframe(fraction); + } + + /** + * Constructs a Keyframe object with the given time and value. The time defines the + * time, as a proportion of an overall animation's duration, at which the value will hold true + * for the animation. The value for the animation between keyframes will be calculated as + * an interpolation between the values at those keyframes. + * + * @param fraction The time, expressed as a value between 0 and 1, representing the fraction + * of time elapsed of the overall animation duration. + * @param value The value that the object will animate to as the animation time approaches + * the time in this keyframe, and the the value animated from as the time passes the time in + * this keyframe. + */ + public static Keyframe ofFloat(float fraction, float value) { + return new FloatKeyframe(fraction, value); + } + + /** + * Constructs a Keyframe object with the given time. The value at this time will be derived + * from the target object when the animation first starts (note that this implies that keyframes + * with no initial value must be used as part of an {@link ObjectAnimator}). + * The time defines the + * time, as a proportion of an overall animation's duration, at which the value will hold true + * for the animation. The value for the animation between keyframes will be calculated as + * an interpolation between the values at those keyframes. + * + * @param fraction The time, expressed as a value between 0 and 1, representing the fraction + * of time elapsed of the overall animation duration. + */ + public static Keyframe ofFloat(float fraction) { + return new FloatKeyframe(fraction); + } + + /** + * Constructs a Keyframe object with the given time and value. The time defines the + * time, as a proportion of an overall animation's duration, at which the value will hold true + * for the animation. The value for the animation between keyframes will be calculated as + * an interpolation between the values at those keyframes. + * + * @param fraction The time, expressed as a value between 0 and 1, representing the fraction + * of time elapsed of the overall animation duration. + * @param value The value that the object will animate to as the animation time approaches + * the time in this keyframe, and the the value animated from as the time passes the time in + * this keyframe. + */ + public static Keyframe ofObject(float fraction, Object value) { + return new ObjectKeyframe(fraction, value); + } + + /** + * Constructs a Keyframe object with the given time. The value at this time will be derived + * from the target object when the animation first starts (note that this implies that keyframes + * with no initial value must be used as part of an {@link ObjectAnimator}). + * The time defines the + * time, as a proportion of an overall animation's duration, at which the value will hold true + * for the animation. The value for the animation between keyframes will be calculated as + * an interpolation between the values at those keyframes. + * + * @param fraction The time, expressed as a value between 0 and 1, representing the fraction + * of time elapsed of the overall animation duration. + */ + public static Keyframe ofObject(float fraction) { + return new ObjectKeyframe(fraction, null); + } + + /** + * Indicates whether this keyframe has a valid value. This method is called internally when + * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at + * that time by deriving the value for the property from the target object. + * + * @return boolean Whether this object has a value assigned. + */ + public boolean hasValue() { + return mHasValue; + } + + /** + * Gets the value for this Keyframe. + * + * @return The value for this Keyframe. + */ + public abstract Object getValue(); + + /** + * Sets the value for this Keyframe. + * + * @param value value for this Keyframe. + */ + public abstract void setValue(Object value); + + /** + * Gets the time for this keyframe, as a fraction of the overall animation duration. + * + * @return The time associated with this keyframe, as a fraction of the overall animation + * duration. This should be a value between 0 and 1. + */ + public float getFraction() { + return mFraction; + } + + /** + * Sets the time for this keyframe, as a fraction of the overall animation duration. + * + * @param fraction time associated with this keyframe, as a fraction of the overall animation + * duration. This should be a value between 0 and 1. + */ + public void setFraction(float fraction) { + mFraction = fraction; + } + + /** + * Gets the optional interpolator for this Keyframe. A value of null indicates + * that there is no interpolation, which is the same as linear interpolation. + * + * @return The optional interpolator for this Keyframe. + */ + public /*Time*/Interpolator getInterpolator() { + return mInterpolator; + } + + /** + * Sets the optional interpolator for this Keyframe. A value of null indicates + * that there is no interpolation, which is the same as linear interpolation. + * + * @return The optional interpolator for this Keyframe. + */ + public void setInterpolator(/*Time*/Interpolator interpolator) { + mInterpolator = interpolator; + } + + /** + * Gets the type of keyframe. This information is used by ValueAnimator to determine the type of + * {@link TypeEvaluator} to use when calculating values between keyframes. The type is based + * on the type of Keyframe created. + * + * @return The type of the value stored in the Keyframe. + */ + public Class getType() { + return mValueType; + } + + @Override + public abstract Keyframe clone(); + + /** + * This internal subclass is used for all types which are not int or float. + */ + static class ObjectKeyframe extends Keyframe { + + /** + * The value of the animation at the time mFraction. + */ + Object mValue; + + ObjectKeyframe(float fraction, Object value) { + mFraction = fraction; + mValue = value; + mHasValue = (value != null); + mValueType = mHasValue ? value.getClass() : Object.class; + } + + public Object getValue() { + return mValue; + } + + public void setValue(Object value) { + mValue = value; + mHasValue = (value != null); + } + + @Override + public ObjectKeyframe clone() { + ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue); + kfClone.setInterpolator(getInterpolator()); + return kfClone; + } + } + + /** + * Internal subclass used when the keyframe value is of type int. + */ + static class IntKeyframe extends Keyframe { + + /** + * The value of the animation at the time mFraction. + */ + int mValue; + + IntKeyframe(float fraction, int value) { + mFraction = fraction; + mValue = value; + mValueType = int.class; + mHasValue = true; + } + + IntKeyframe(float fraction) { + mFraction = fraction; + mValueType = int.class; + } + + public int getIntValue() { + return mValue; + } + + public Object getValue() { + return mValue; + } + + public void setValue(Object value) { + if (value != null && value.getClass() == Integer.class) { + mValue = ((Integer)value).intValue(); + mHasValue = true; + } + } + + @Override + public IntKeyframe clone() { + IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue); + kfClone.setInterpolator(getInterpolator()); + return kfClone; + } + } + + /** + * Internal subclass used when the keyframe value is of type float. + */ + static class FloatKeyframe extends Keyframe { + /** + * The value of the animation at the time mFraction. + */ + float mValue; + + FloatKeyframe(float fraction, float value) { + mFraction = fraction; + mValue = value; + mValueType = float.class; + mHasValue = true; + } + + FloatKeyframe(float fraction) { + mFraction = fraction; + mValueType = float.class; + } + + public float getFloatValue() { + return mValue; + } + + public Object getValue() { + return mValue; + } + + public void setValue(Object value) { + if (value != null && value.getClass() == Float.class) { + mValue = ((Float)value).floatValue(); + mHasValue = true; + } + } + + @Override + public FloatKeyframe clone() { + FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue); + kfClone.setInterpolator(getInterpolator()); + return kfClone; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java new file mode 100644 index 0000000000..a71e1ad3cf --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import java.util.ArrayList; +import java.util.Arrays; +import android.view.animation.Interpolator; + +import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.FloatKeyframe; +import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.IntKeyframe; +import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.ObjectKeyframe; + +/** + * This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate + * values between those keyframes for a given animation. The class internal to the animation + * package because it is an implementation detail of how Keyframes are stored and used. + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +class KeyframeSet { + + int mNumKeyframes; + + Keyframe mFirstKeyframe; + Keyframe mLastKeyframe; + /*Time*/Interpolator mInterpolator; // only used in the 2-keyframe case + ArrayList mKeyframes; // only used when there are not 2 keyframes + TypeEvaluator mEvaluator; + + + public KeyframeSet(Keyframe... keyframes) { + mNumKeyframes = keyframes.length; + mKeyframes = new ArrayList(); + mKeyframes.addAll(Arrays.asList(keyframes)); + mFirstKeyframe = mKeyframes.get(0); + mLastKeyframe = mKeyframes.get(mNumKeyframes - 1); + mInterpolator = mLastKeyframe.getInterpolator(); + } + + public static KeyframeSet ofInt(int... values) { + int numKeyframes = values.length; + IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f); + keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]); + } else { + keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]); + } + } + return new IntKeyframeSet(keyframes); + } + + public static KeyframeSet ofFloat(float... values) { + int numKeyframes = values.length; + FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f); + keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]); + } else { + keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]); + } + } + return new FloatKeyframeSet(keyframes); + } + + public static KeyframeSet ofKeyframe(Keyframe... keyframes) { + // if all keyframes of same primitive type, create the appropriate KeyframeSet + int numKeyframes = keyframes.length; + boolean hasFloat = false; + boolean hasInt = false; + boolean hasOther = false; + for (int i = 0; i < numKeyframes; ++i) { + if (keyframes[i] instanceof FloatKeyframe) { + hasFloat = true; + } else if (keyframes[i] instanceof IntKeyframe) { + hasInt = true; + } else { + hasOther = true; + } + } + if (hasFloat && !hasInt && !hasOther) { + FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes]; + for (int i = 0; i < numKeyframes; ++i) { + floatKeyframes[i] = (FloatKeyframe) keyframes[i]; + } + return new FloatKeyframeSet(floatKeyframes); + } else if (hasInt && !hasFloat && !hasOther) { + IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes]; + for (int i = 0; i < numKeyframes; ++i) { + intKeyframes[i] = (IntKeyframe) keyframes[i]; + } + return new IntKeyframeSet(intKeyframes); + } else { + return new KeyframeSet(keyframes); + } + } + + public static KeyframeSet ofObject(Object... values) { + int numKeyframes = values.length; + ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f); + keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]); + } else { + keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]); + } + } + return new KeyframeSet(keyframes); + } + + /** + * Sets the TypeEvaluator to be used when calculating animated values. This object + * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet, + * both of which assume their own evaluator to speed up calculations with those primitive + * types. + * + * @param evaluator The TypeEvaluator to be used to calculate animated values. + */ + public void setEvaluator(TypeEvaluator evaluator) { + mEvaluator = evaluator; + } + + @Override + public KeyframeSet clone() { + ArrayList keyframes = mKeyframes; + int numKeyframes = mKeyframes.size(); + Keyframe[] newKeyframes = new Keyframe[numKeyframes]; + for (int i = 0; i < numKeyframes; ++i) { + newKeyframes[i] = keyframes.get(i).clone(); + } + KeyframeSet newSet = new KeyframeSet(newKeyframes); + return newSet; + } + + /** + * Gets the animated value, given the elapsed fraction of the animation (interpolated by the + * animation's interpolator) and the evaluator used to calculate in-between values. This + * function maps the input fraction to the appropriate keyframe interval and a fraction + * between them and returns the interpolated value. Note that the input fraction may fall + * outside the [0-1] bounds, if the animation's interpolator made that happen (e.g., a + * spring interpolation that might send the fraction past 1.0). We handle this situation by + * just using the two keyframes at the appropriate end when the value is outside those bounds. + * + * @param fraction The elapsed fraction of the animation + * @return The animated value. + */ + public Object getValue(float fraction) { + + // Special-case optimization for the common case of only two keyframes + if (mNumKeyframes == 2) { + if (mInterpolator != null) { + fraction = mInterpolator.getInterpolation(fraction); + } + return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(), + mLastKeyframe.getValue()); + } + if (fraction <= 0f) { + final Keyframe nextKeyframe = mKeyframes.get(1); + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + final float prevFraction = mFirstKeyframe.getFraction(); + float intervalFraction = (fraction - prevFraction) / + (nextKeyframe.getFraction() - prevFraction); + return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(), + nextKeyframe.getValue()); + } else if (fraction >= 1f) { + final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2); + final /*Time*/Interpolator interpolator = mLastKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + final float prevFraction = prevKeyframe.getFraction(); + float intervalFraction = (fraction - prevFraction) / + (mLastKeyframe.getFraction() - prevFraction); + return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), + mLastKeyframe.getValue()); + } + Keyframe prevKeyframe = mFirstKeyframe; + for (int i = 1; i < mNumKeyframes; ++i) { + Keyframe nextKeyframe = mKeyframes.get(i); + if (fraction < nextKeyframe.getFraction()) { + final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); + if (interpolator != null) { + fraction = interpolator.getInterpolation(fraction); + } + final float prevFraction = prevKeyframe.getFraction(); + float intervalFraction = (fraction - prevFraction) / + (nextKeyframe.getFraction() - prevFraction); + return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), + nextKeyframe.getValue()); + } + prevKeyframe = nextKeyframe; + } + // shouldn't reach here + return mLastKeyframe.getValue(); + } + + @Override + public String toString() { + String returnVal = " "; + for (int i = 0; i < mNumKeyframes; ++i) { + returnVal += mKeyframes.get(i).getValue() + " "; + } + return returnVal; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java new file mode 100644 index 0000000000..21d15c02ac --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java @@ -0,0 +1,491 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import android.util.Log; +//import android.util.Property; + +//import java.lang.reflect.Method; +import java.util.ArrayList; + +/** + * This subclass of {@link ValueAnimator} provides support for animating properties on target objects. + * The constructors of this class take parameters to define the target object that will be animated + * as well as the name of the property that will be animated. Appropriate set/get functions + * are then determined internally and the animation will call these functions as necessary to + * animate the property. + * + * @see #setPropertyName(String) + * + */ +@SuppressWarnings("rawtypes") +public final class ObjectAnimator extends ValueAnimator { + private static final boolean DBG = false; + + // The target object on which the property exists, set in the constructor + private Object mTarget; + + private String mPropertyName; + + //private Property mProperty; + + /** + * Sets the name of the property that will be animated. This name is used to derive + * a setter function that will be called to set animated values. + * For example, a property name of foo will result + * in a call to the function setFoo() on the target object. If either + * valueFrom or valueTo is null, then a getter function will + * also be derived and called. + * + *

For best performance of the mechanism that calls the setter function determined by the + * name of the property being animated, use float or int typed values, + * and make the setter function for those properties have a void return value. This + * will cause the code to take an optimized path for these constrained circumstances. Other + * property types and return types will work, but will have more overhead in processing + * the requests due to normal reflection mechanisms.

+ * + *

Note that the setter function derived from this property name + * must take the same parameter type as the + * valueFrom and valueTo properties, otherwise the call to + * the setter function will fail.

+ * + *

If this ObjectAnimator has been set up to animate several properties together, + * using more than one PropertyValuesHolder objects, then setting the propertyName simply + * sets the propertyName in the first of those PropertyValuesHolder objects.

+ * + * @param propertyName The name of the property being animated. Should not be null. + */ + public void setPropertyName(String propertyName) { + // mValues could be null if this is being constructed piecemeal. Just record the + // propertyName to be used later when setValues() is called if so. + if (mValues != null) { + PropertyValuesHolder valuesHolder = mValues[0]; + String oldName = valuesHolder.getPropertyName(); + valuesHolder.setPropertyName(propertyName); + mValuesMap.remove(oldName); + mValuesMap.put(propertyName, valuesHolder); + } + mPropertyName = propertyName; + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets the property that will be animated. Property objects will take precedence over + * properties specified by the {@link #setPropertyName(String)} method. Animations should + * be set up to use one or the other, not both. + * + * @param property The property being animated. Should not be null. + */ + //public void setProperty(Property property) { + // // mValues could be null if this is being constructed piecemeal. Just record the + // // propertyName to be used later when setValues() is called if so. + // if (mValues != null) { + // PropertyValuesHolder valuesHolder = mValues[0]; + // String oldName = valuesHolder.getPropertyName(); + // valuesHolder.setProperty(property); + // mValuesMap.remove(oldName); + // mValuesMap.put(mPropertyName, valuesHolder); + // } + // if (mProperty != null) { + // mPropertyName = property.getName(); + // } + // mProperty = property; + // // New property/values/target should cause re-initialization prior to starting + // mInitialized = false; + //} + + /** + * Gets the name of the property that will be animated. This name will be used to derive + * a setter function that will be called to set animated values. + * For example, a property name of foo will result + * in a call to the function setFoo() on the target object. If either + * valueFrom or valueTo is null, then a getter function will + * also be derived and called. + */ + public String getPropertyName() { + return mPropertyName; + } + + /** + * Creates a new ObjectAnimator object. This default constructor is primarily for + * use internally; the other constructors which take parameters are more generally + * useful. + */ + public ObjectAnimator() { + } + + /** + * Private utility constructor that initializes the target object and name of the + * property being animated. + * + * @param target The object whose property is to be animated. This object should + * have a public method on it called setName(), where name is + * the value of the propertyName parameter. + * @param propertyName The name of the property being animated. + */ + private ObjectAnimator(Object target, String propertyName) { + mTarget = target; + setPropertyName(propertyName); + } + + /** + * Private utility constructor that initializes the target object and property being animated. + * + * @param target The object whose property is to be animated. + * @param property The property being animated. + */ + //private ObjectAnimator(T target, Property property) { + // mTarget = target; + // setProperty(property); + //} + + /** + * Constructs and returns an ObjectAnimator that animates between int values. A single + * value implies that that value is the one being animated to. Two values imply a starting + * and ending values. More than two values imply a starting value, values to animate through + * along the way, and an ending value (these values will be distributed evenly across + * the duration of the animation). + * + * @param target The object whose property is to be animated. This object should + * have a public method on it called setName(), where name is + * the value of the propertyName parameter. + * @param propertyName The name of the property being animated. + * @param values A set of values that the animation will animate between over time. + * @return An ObjectAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setIntValues(values); + return anim; + } + + /** + * Constructs and returns an ObjectAnimator that animates between int values. A single + * value implies that that value is the one being animated to. Two values imply a starting + * and ending values. More than two values imply a starting value, values to animate through + * along the way, and an ending value (these values will be distributed evenly across + * the duration of the animation). + * + * @param target The object whose property is to be animated. + * @param property The property being animated. + * @param values A set of values that the animation will animate between over time. + * @return An ObjectAnimator object that is set up to animate between the given values. + */ + //public static ObjectAnimator ofInt(T target, Property property, int... values) { + // ObjectAnimator anim = new ObjectAnimator(target, property); + // anim.setIntValues(values); + // return anim; + //} + + /** + * Constructs and returns an ObjectAnimator that animates between float values. A single + * value implies that that value is the one being animated to. Two values imply a starting + * and ending values. More than two values imply a starting value, values to animate through + * along the way, and an ending value (these values will be distributed evenly across + * the duration of the animation). + * + * @param target The object whose property is to be animated. This object should + * have a public method on it called setName(), where name is + * the value of the propertyName parameter. + * @param propertyName The name of the property being animated. + * @param values A set of values that the animation will animate between over time. + * @return An ObjectAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setFloatValues(values); + return anim; + } + + /** + * Constructs and returns an ObjectAnimator that animates between float values. A single + * value implies that that value is the one being animated to. Two values imply a starting + * and ending values. More than two values imply a starting value, values to animate through + * along the way, and an ending value (these values will be distributed evenly across + * the duration of the animation). + * + * @param target The object whose property is to be animated. + * @param property The property being animated. + * @param values A set of values that the animation will animate between over time. + * @return An ObjectAnimator object that is set up to animate between the given values. + */ + //public static ObjectAnimator ofFloat(T target, Property property, + // float... values) { + // ObjectAnimator anim = new ObjectAnimator(target, property); + // anim.setFloatValues(values); + // return anim; + //} + + /** + * Constructs and returns an ObjectAnimator that animates between Object values. A single + * value implies that that value is the one being animated to. Two values imply a starting + * and ending values. More than two values imply a starting value, values to animate through + * along the way, and an ending value (these values will be distributed evenly across + * the duration of the animation). + * + * @param target The object whose property is to be animated. This object should + * have a public method on it called setName(), where name is + * the value of the propertyName parameter. + * @param propertyName The name of the property being animated. + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the necessary interpolation between the Object values to derive the animated + * value. + * @param values A set of values that the animation will animate between over time. + * @return An ObjectAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofObject(Object target, String propertyName, + TypeEvaluator evaluator, Object... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setObjectValues(values); + anim.setEvaluator(evaluator); + return anim; + } + + /** + * Constructs and returns an ObjectAnimator that animates between Object values. A single + * value implies that that value is the one being animated to. Two values imply a starting + * and ending values. More than two values imply a starting value, values to animate through + * along the way, and an ending value (these values will be distributed evenly across + * the duration of the animation). + * + * @param target The object whose property is to be animated. + * @param property The property being animated. + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the necessary interpolation between the Object values to derive the animated + * value. + * @param values A set of values that the animation will animate between over time. + * @return An ObjectAnimator object that is set up to animate between the given values. + */ + //public static ObjectAnimator ofObject(T target, Property property, + // TypeEvaluator evaluator, V... values) { + // ObjectAnimator anim = new ObjectAnimator(target, property); + // anim.setObjectValues(values); + // anim.setEvaluator(evaluator); + // return anim; + //} + + /** + * Constructs and returns an ObjectAnimator that animates between the sets of values specified + * in PropertyValueHolder objects. This variant should be used when animating + * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows + * you to associate a set of animation values with a property name. + * + * @param target The object whose property is to be animated. Depending on how the + * PropertyValuesObjects were constructed, the target object should either have the {@link + * android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the + * PropertyValuesHOlder objects were created with property names) the target object should have + * public methods on it called setName(), where name is the name of + * the property passed in as the propertyName parameter for each of the + * PropertyValuesHolder objects. + * @param values A set of PropertyValuesHolder objects whose values will be animated between + * over time. + * @return An ObjectAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofPropertyValuesHolder(Object target, + PropertyValuesHolder... values) { + ObjectAnimator anim = new ObjectAnimator(); + anim.mTarget = target; + anim.setValues(values); + return anim; + } + + @Override + public void setIntValues(int... values) { + if (mValues == null || mValues.length == 0) { + // No values yet - this animator is being constructed piecemeal. Init the values with + // whatever the current propertyName is + //if (mProperty != null) { + // setValues(PropertyValuesHolder.ofInt(mProperty, values)); + //} else { + setValues(PropertyValuesHolder.ofInt(mPropertyName, values)); + //} + } else { + super.setIntValues(values); + } + } + + @Override + public void setFloatValues(float... values) { + if (mValues == null || mValues.length == 0) { + // No values yet - this animator is being constructed piecemeal. Init the values with + // whatever the current propertyName is + //if (mProperty != null) { + // setValues(PropertyValuesHolder.ofFloat(mProperty, values)); + //} else { + setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); + //} + } else { + super.setFloatValues(values); + } + } + + @Override + public void setObjectValues(Object... values) { + if (mValues == null || mValues.length == 0) { + // No values yet - this animator is being constructed piecemeal. Init the values with + // whatever the current propertyName is + //if (mProperty != null) { + // setValues(PropertyValuesHolder.ofObject(mProperty, (TypeEvaluator)null, values)); + //} else { + setValues(PropertyValuesHolder.ofObject(mPropertyName, (TypeEvaluator)null, values)); + //} + } else { + super.setObjectValues(values); + } + } + + @Override + public void start() { + if (DBG) { + Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration()); + for (int i = 0; i < mValues.length; ++i) { + PropertyValuesHolder pvh = mValues[i]; + ArrayList keyframes = pvh.mKeyframeSet.mKeyframes; + Log.d("ObjectAnimator", " Values[" + i + "]: " + + pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " + + keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue()); + } + } + super.start(); + } + + /** + * This function is called immediately before processing the first animation + * frame of an animation. If there is a nonzero startDelay, the + * function is called after that delay ends. + * It takes care of the final initialization steps for the + * animation. This includes setting mEvaluator, if the user has not yet + * set it up, and the setter/getter methods, if the user did not supply + * them. + * + *

Overriders of this method should call the superclass method to cause + * internal mechanisms to be set up correctly.

+ */ + @Override + void initAnimation() { + if (!mInitialized) { + // mValueType may change due to setter/getter setup; do this before calling super.init(), + // which uses mValueType to set up the default type evaluator. + int numValues = mValues.length; + for (int i = 0; i < numValues; ++i) { + mValues[i].setupSetterAndGetter(mTarget); + } + super.initAnimation(); + } + } + + /** + * Sets the length of the animation. The default duration is 300 milliseconds. + * + * @param duration The length of the animation, in milliseconds. + * @return ObjectAnimator The object called with setDuration(). This return + * value makes it easier to compose statements together that construct and then set the + * duration, as in + * ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start(). + */ + @Override + public ObjectAnimator setDuration(long duration) { + super.setDuration(duration); + return this; + } + + + /** + * The target object whose property will be animated by this animation + * + * @return The object being animated + */ + public Object getTarget() { + return mTarget; + } + + /** + * Sets the target object whose property will be animated by this animation + * + * @param target The object being animated + */ + @Override + public void setTarget(Object target) { + if (mTarget != target) { + final Object oldTarget = mTarget; + mTarget = target; + if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) { + return; + } + // New target type should cause re-initialization prior to starting + mInitialized = false; + } + } + + @Override + public void setupStartValues() { + initAnimation(); + int numValues = mValues.length; + for (int i = 0; i < numValues; ++i) { + mValues[i].setupStartValue(mTarget); + } + } + + @Override + public void setupEndValues() { + initAnimation(); + int numValues = mValues.length; + for (int i = 0; i < numValues; ++i) { + mValues[i].setupEndValue(mTarget); + } + } + + /** + * This method is called with the elapsed fraction of the animation during every + * animation frame. This function turns the elapsed fraction into an interpolated fraction + * and then into an animated value (from the evaluator. The function is called mostly during + * animation updates, but it is also called when the end() + * function is called, to set the final value on the property. + * + *

Overrides of this method must call the superclass to perform the calculation + * of the animated value.

+ * + * @param fraction The elapsed fraction of the animation. + */ + @Override + void animateValue(float fraction) { + super.animateValue(fraction); + int numValues = mValues.length; + for (int i = 0; i < numValues; ++i) { + mValues[i].setAnimatedValue(mTarget); + } + } + + @Override + public ObjectAnimator clone() { + final ObjectAnimator anim = (ObjectAnimator) super.clone(); + return anim; + } + + @Override + public String toString() { + String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " + + mTarget; + if (mValues != null) { + for (int i = 0; i < mValues.length; ++i) { + returnVal += "\n " + mValues[i].toString(); + } + } + return returnVal; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java new file mode 100644 index 0000000000..84f7504abc --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java @@ -0,0 +1,1012 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +//import android.util.FloatProperty; +//import android.util.IntProperty; +import android.util.Log; +//import android.util.Property; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * This class holds information about a property and the values that that property + * should take on during an animation. PropertyValuesHolder objects can be used to create + * animations with ValueAnimator or ObjectAnimator that operate on several different properties + * in parallel. + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class PropertyValuesHolder implements Cloneable { + + /** + * The name of the property associated with the values. This need not be a real property, + * unless this object is being used with ObjectAnimator. But this is the name by which + * aniamted values are looked up with getAnimatedValue(String) in ValueAnimator. + */ + String mPropertyName; + + /** + * @hide + */ + //protected Property mProperty; + + /** + * The setter function, if needed. ObjectAnimator hands off this functionality to + * PropertyValuesHolder, since it holds all of the per-property information. This + * property is automatically + * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. + */ + Method mSetter = null; + + /** + * The getter function, if needed. ObjectAnimator hands off this functionality to + * PropertyValuesHolder, since it holds all of the per-property information. This + * property is automatically + * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. + * The getter is only derived and used if one of the values is null. + */ + private Method mGetter = null; + + /** + * The type of values supplied. This information is used both in deriving the setter/getter + * functions and in deriving the type of TypeEvaluator. + */ + Class mValueType; + + /** + * The set of keyframes (time/value pairs) that define this animation. + */ + KeyframeSet mKeyframeSet = null; + + + // type evaluators for the primitive types handled by this implementation + private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); + private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); + + // We try several different types when searching for appropriate setter/getter functions. + // The caller may have supplied values in a type that does not match the setter/getter + // functions (such as the integers 0 and 1 to represent floating point values for alpha). + // Also, the use of generics in constructors means that we end up with the Object versions + // of primitive types (Float vs. float). But most likely, the setter/getter functions + // will take primitive types instead. + // So we supply an ordered array of other types to try before giving up. + private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class, + Double.class, Integer.class}; + private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class, + Float.class, Double.class}; + private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class, + Float.class, Integer.class}; + + // These maps hold all property entries for a particular class. This map + // is used to speed up property/setter/getter lookups for a given class/property + // combination. No need to use reflection on the combination more than once. + private static final HashMap> sSetterPropertyMap = + new HashMap>(); + private static final HashMap> sGetterPropertyMap = + new HashMap>(); + + // This lock is used to ensure that only one thread is accessing the property maps + // at a time. + final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock(); + + // Used to pass single value to varargs parameter in setter invocation + final Object[] mTmpValueArray = new Object[1]; + + /** + * The type evaluator used to calculate the animated values. This evaluator is determined + * automatically based on the type of the start/end objects passed into the constructor, + * but the system only knows about the primitive types int and float. Any other + * type will need to set the evaluator to a custom evaluator for that type. + */ + private TypeEvaluator mEvaluator; + + /** + * The value most recently calculated by calculateValue(). This is set during + * that function and might be retrieved later either by ValueAnimator.animatedValue() or + * by the property-setting logic in ObjectAnimator.animatedValue(). + */ + private Object mAnimatedValue; + + /** + * Internal utility constructor, used by the factory methods to set the property name. + * @param propertyName The name of the property for this holder. + */ + private PropertyValuesHolder(String propertyName) { + mPropertyName = propertyName; + } + + /** + * Internal utility constructor, used by the factory methods to set the property. + * @param property The property for this holder. + */ + //private PropertyValuesHolder(Property property) { + // mProperty = property; + // if (property != null) { + // mPropertyName = property.getName(); + // } + //} + + /** + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of int values. + * @param propertyName The name of the property being animated. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofInt(String propertyName, int... values) { + return new IntPropertyValuesHolder(propertyName, values); + } + + /** + * Constructs and returns a PropertyValuesHolder with a given property and + * set of int values. + * @param property The property being animated. Should not be null. + * @param values The values that the property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + //public static PropertyValuesHolder ofInt(Property property, int... values) { + // return new IntPropertyValuesHolder(property, values); + //} + + /** + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of float values. + * @param propertyName The name of the property being animated. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofFloat(String propertyName, float... values) { + return new FloatPropertyValuesHolder(propertyName, values); + } + + /** + * Constructs and returns a PropertyValuesHolder with a given property and + * set of float values. + * @param property The property being animated. Should not be null. + * @param values The values that the property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + //public static PropertyValuesHolder ofFloat(Property property, float... values) { + // return new FloatPropertyValuesHolder(property, values); + //} + + /** + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of Object values. This variant also takes a TypeEvaluator because the system + * cannot automatically interpolate between objects of unknown type. + * + * @param propertyName The name of the property being animated. + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the necessary interpolation between the Object values to derive the animated + * value. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator, + Object... values) { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.setObjectValues(values); + pvh.setEvaluator(evaluator); + return pvh; + } + + /** + * Constructs and returns a PropertyValuesHolder with a given property and + * set of Object values. This variant also takes a TypeEvaluator because the system + * cannot automatically interpolate between objects of unknown type. + * + * @param property The property being animated. Should not be null. + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the necessary interpolation between the Object values to derive the animated + * value. + * @param values The values that the property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + //public static PropertyValuesHolder ofObject(Property property, + // TypeEvaluator evaluator, V... values) { + // PropertyValuesHolder pvh = new PropertyValuesHolder(property); + // pvh.setObjectValues(values); + // pvh.setEvaluator(evaluator); + // return pvh; + //} + + /** + * Constructs and returns a PropertyValuesHolder object with the specified property name and set + * of values. These values can be of any type, but the type should be consistent so that + * an appropriate {@link android.animation.TypeEvaluator} can be found that matches + * the common type. + *

If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function + * derived automatically from propertyName, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * @param propertyName The name of the property associated with this set of values. This + * can be the actual property name to be used when using a ObjectAnimator object, or + * just a name used to get animated values, such as if this object is used with an + * ValueAnimator object. + * @param values The set of values to animate between. + */ + public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) { + KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); + if (keyframeSet instanceof IntKeyframeSet) { + return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet); + } else if (keyframeSet instanceof FloatKeyframeSet) { + return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet); + } + else { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.mKeyframeSet = keyframeSet; + pvh.mValueType = values[0].getType(); + return pvh; + } + } + + /** + * Constructs and returns a PropertyValuesHolder object with the specified property and set + * of values. These values can be of any type, but the type should be consistent so that + * an appropriate {@link android.animation.TypeEvaluator} can be found that matches + * the common type. + *

If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling the property's + * {@link android.util.Property#get(Object)} function. + * Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction with + * {@link ObjectAnimator}, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * @param property The property associated with this set of values. Should not be null. + * @param values The set of values to animate between. + */ + //public static PropertyValuesHolder ofKeyframe(Property property, Keyframe... values) { + // KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); + // if (keyframeSet instanceof IntKeyframeSet) { + // return new IntPropertyValuesHolder(property, (IntKeyframeSet) keyframeSet); + // } else if (keyframeSet instanceof FloatKeyframeSet) { + // return new FloatPropertyValuesHolder(property, (FloatKeyframeSet) keyframeSet); + // } + // else { + // PropertyValuesHolder pvh = new PropertyValuesHolder(property); + // pvh.mKeyframeSet = keyframeSet; + // pvh.mValueType = ((Keyframe)values[0]).getType(); + // return pvh; + // } + //} + + /** + * Set the animated values for this object to this set of ints. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function + * derived automatically from propertyName, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setIntValues(int... values) { + mValueType = int.class; + mKeyframeSet = KeyframeSet.ofInt(values); + } + + /** + * Set the animated values for this object to this set of floats. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function + * derived automatically from propertyName, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setFloatValues(float... values) { + mValueType = float.class; + mKeyframeSet = KeyframeSet.ofFloat(values); + } + + /** + * Set the animated values for this object to this set of Keyframes. + * + * @param values One or more values that the animation will animate between. + */ + public void setKeyframes(Keyframe... values) { + int numKeyframes = values.length; + Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; + mValueType = values[0].getType(); + for (int i = 0; i < numKeyframes; ++i) { + keyframes[i] = values[i]; + } + mKeyframeSet = new KeyframeSet(keyframes); + } + + /** + * Set the animated values for this object to this set of Objects. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function + * derived automatically from propertyName, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setObjectValues(Object... values) { + mValueType = values[0].getClass(); + mKeyframeSet = KeyframeSet.ofObject(values); + } + + /** + * Determine the setter or getter function using the JavaBeans convention of setFoo or + * getFoo for a property named 'foo'. This function figures out what the name of the + * function should be and uses reflection to find the Method with that name on the + * target object. + * + * @param targetClass The class to search for the method + * @param prefix "set" or "get", depending on whether we need a setter or getter. + * @param valueType The type of the parameter (in the case of a setter). This type + * is derived from the values set on this PropertyValuesHolder. This type is used as + * a first guess at the parameter type, but we check for methods with several different + * types to avoid problems with slight mis-matches between supplied values and actual + * value types used on the setter. + * @return Method the method associated with mPropertyName. + */ + private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) { + // TODO: faster implementation... + Method returnVal = null; + String methodName = getMethodName(prefix, mPropertyName); + Class args[] = null; + if (valueType == null) { + try { + returnVal = targetClass.getMethod(methodName, args); + } catch (NoSuchMethodException e) { + Log.e("PropertyValuesHolder", targetClass.getSimpleName() + " - " + + "Couldn't find no-arg method for property " + mPropertyName + ": " + e); + } + } else { + args = new Class[1]; + Class typeVariants[]; + if (mValueType.equals(Float.class)) { + typeVariants = FLOAT_VARIANTS; + } else if (mValueType.equals(Integer.class)) { + typeVariants = INTEGER_VARIANTS; + } else if (mValueType.equals(Double.class)) { + typeVariants = DOUBLE_VARIANTS; + } else { + typeVariants = new Class[1]; + typeVariants[0] = mValueType; + } + for (Class typeVariant : typeVariants) { + args[0] = typeVariant; + try { + returnVal = targetClass.getMethod(methodName, args); + // change the value type to suit + mValueType = typeVariant; + return returnVal; + } catch (NoSuchMethodException e) { + // Swallow the error and keep trying other variants + } + } + // If we got here, then no appropriate function was found + Log.e("PropertyValuesHolder", + "Couldn't find " + prefix + "ter property " + mPropertyName + + " for " + targetClass.getSimpleName() + + " with value type "+ mValueType); + } + + return returnVal; + } + + + /** + * Returns the setter or getter requested. This utility function checks whether the + * requested method exists in the propertyMapMap cache. If not, it calls another + * utility function to request the Method from the targetClass directly. + * @param targetClass The Class on which the requested method should exist. + * @param propertyMapMap The cache of setters/getters derived so far. + * @param prefix "set" or "get", for the setter or getter. + * @param valueType The type of parameter passed into the method (null for getter). + * @return Method the method associated with mPropertyName. + */ + private Method setupSetterOrGetter(Class targetClass, + HashMap> propertyMapMap, + String prefix, Class valueType) { + Method setterOrGetter = null; + try { + // Have to lock property map prior to reading it, to guard against + // another thread putting something in there after we've checked it + // but before we've added an entry to it + mPropertyMapLock.writeLock().lock(); + HashMap propertyMap = propertyMapMap.get(targetClass); + if (propertyMap != null) { + setterOrGetter = propertyMap.get(mPropertyName); + } + if (setterOrGetter == null) { + setterOrGetter = getPropertyFunction(targetClass, prefix, valueType); + if (propertyMap == null) { + propertyMap = new HashMap(); + propertyMapMap.put(targetClass, propertyMap); + } + propertyMap.put(mPropertyName, setterOrGetter); + } + } finally { + mPropertyMapLock.writeLock().unlock(); + } + return setterOrGetter; + } + + /** + * Utility function to get the setter from targetClass + * @param targetClass The Class on which the requested method should exist. + */ + void setupSetter(Class targetClass) { + mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType); + } + + /** + * Utility function to get the getter from targetClass + */ + private void setupGetter(Class targetClass) { + mGetter = setupSetterOrGetter(targetClass, sGetterPropertyMap, "get", null); + } + + /** + * Internal function (called from ObjectAnimator) to set up the setter and getter + * prior to running the animation. If the setter has not been manually set for this + * object, it will be derived automatically given the property name, target object, and + * types of values supplied. If no getter has been set, it will be supplied iff any of the + * supplied values was null. If there is a null value, then the getter (supplied or derived) + * will be called to set those null values to the current value of the property + * on the target object. + * @param target The object on which the setter (and possibly getter) exist. + */ + void setupSetterAndGetter(Object target) { + //if (mProperty != null) { + // // check to make sure that mProperty is on the class of target + // try { + // Object testValue = mProperty.get(target); + // for (Keyframe kf : mKeyframeSet.mKeyframes) { + // if (!kf.hasValue()) { + // kf.setValue(mProperty.get(target)); + // } + // } + // return; + // } catch (ClassCastException e) { + // Log.e("PropertyValuesHolder","No such property (" + mProperty.getName() + + // ") on target object " + target + ". Trying reflection instead"); + // mProperty = null; + // } + //} + Class targetClass = target.getClass(); + if (mSetter == null) { + setupSetter(targetClass); + } + for (Keyframe kf : mKeyframeSet.mKeyframes) { + if (!kf.hasValue()) { + if (mGetter == null) { + setupGetter(targetClass); + } + try { + kf.setValue(mGetter.invoke(target)); + } catch (InvocationTargetException e) { + Log.e("PropertyValuesHolder", e.toString()); + } catch (IllegalAccessException e) { + Log.e("PropertyValuesHolder", e.toString()); + } + } + } + } + + /** + * Utility function to set the value stored in a particular Keyframe. The value used is + * whatever the value is for the property name specified in the keyframe on the target object. + * + * @param target The target object from which the current value should be extracted. + * @param kf The keyframe which holds the property name and value. + */ + private void setupValue(Object target, Keyframe kf) { + //if (mProperty != null) { + // kf.setValue(mProperty.get(target)); + //} + try { + if (mGetter == null) { + Class targetClass = target.getClass(); + setupGetter(targetClass); + } + kf.setValue(mGetter.invoke(target)); + } catch (InvocationTargetException e) { + Log.e("PropertyValuesHolder", e.toString()); + } catch (IllegalAccessException e) { + Log.e("PropertyValuesHolder", e.toString()); + } + } + + /** + * This function is called by ObjectAnimator when setting the start values for an animation. + * The start values are set according to the current values in the target object. The + * property whose value is extracted is whatever is specified by the propertyName of this + * PropertyValuesHolder object. + * + * @param target The object which holds the start values that should be set. + */ + void setupStartValue(Object target) { + setupValue(target, mKeyframeSet.mKeyframes.get(0)); + } + + /** + * This function is called by ObjectAnimator when setting the end values for an animation. + * The end values are set according to the current values in the target object. The + * property whose value is extracted is whatever is specified by the propertyName of this + * PropertyValuesHolder object. + * + * @param target The object which holds the start values that should be set. + */ + void setupEndValue(Object target) { + setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1)); + } + + @Override + public PropertyValuesHolder clone() { + try { + PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone(); + newPVH.mPropertyName = mPropertyName; + //newPVH.mProperty = mProperty; + newPVH.mKeyframeSet = mKeyframeSet.clone(); + newPVH.mEvaluator = mEvaluator; + return newPVH; + } catch (CloneNotSupportedException e) { + // won't reach here + return null; + } + } + + /** + * Internal function to set the value on the target object, using the setter set up + * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator + * to handle turning the value calculated by ValueAnimator into a value set on the object + * according to the name of the property. + * @param target The target object on which the value is set + */ + void setAnimatedValue(Object target) { + //if (mProperty != null) { + // mProperty.set(target, getAnimatedValue()); + //} + if (mSetter != null) { + try { + mTmpValueArray[0] = getAnimatedValue(); + mSetter.invoke(target, mTmpValueArray); + } catch (InvocationTargetException e) { + Log.e("PropertyValuesHolder", e.toString()); + } catch (IllegalAccessException e) { + Log.e("PropertyValuesHolder", e.toString()); + } + } + } + + /** + * Internal function, called by ValueAnimator, to set up the TypeEvaluator that will be used + * to calculate animated values. + */ + void init() { + if (mEvaluator == null) { + // We already handle int and float automatically, but not their Object + // equivalents + mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : + (mValueType == Float.class) ? sFloatEvaluator : + null; + } + if (mEvaluator != null) { + // KeyframeSet knows how to evaluate the common types - only give it a custom + // evaluator if one has been set on this class + mKeyframeSet.setEvaluator(mEvaluator); + } + } + + /** + * The TypeEvaluator will the automatically determined based on the type of values + * supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so + * desired. This may be important in cases where either the type of the values supplied + * do not match the way that they should be interpolated between, or if the values + * are of a custom type or one not currently understood by the animation system. Currently, + * only values of type float and int (and their Object equivalents: Float + * and Integer) are correctly interpolated; all other types require setting a TypeEvaluator. + * @param evaluator + */ + public void setEvaluator(TypeEvaluator evaluator) { + mEvaluator = evaluator; + mKeyframeSet.setEvaluator(evaluator); + } + + /** + * Function used to calculate the value according to the evaluator set up for + * this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue(). + * + * @param fraction The elapsed, interpolated fraction of the animation. + */ + void calculateValue(float fraction) { + mAnimatedValue = mKeyframeSet.getValue(fraction); + } + + /** + * Sets the name of the property that will be animated. This name is used to derive + * a setter function that will be called to set animated values. + * For example, a property name of foo will result + * in a call to the function setFoo() on the target object. If either + * valueFrom or valueTo is null, then a getter function will + * also be derived and called. + * + *

Note that the setter function derived from this property name + * must take the same parameter type as the + * valueFrom and valueTo properties, otherwise the call to + * the setter function will fail.

+ * + * @param propertyName The name of the property being animated. + */ + public void setPropertyName(String propertyName) { + mPropertyName = propertyName; + } + + /** + * Sets the property that will be animated. + * + *

Note that if this PropertyValuesHolder object is used with ObjectAnimator, the property + * must exist on the target object specified in that ObjectAnimator.

+ * + * @param property The property being animated. + */ + //public void setProperty(Property property) { + // mProperty = property; + //} + + /** + * Gets the name of the property that will be animated. This name will be used to derive + * a setter function that will be called to set animated values. + * For example, a property name of foo will result + * in a call to the function setFoo() on the target object. If either + * valueFrom or valueTo is null, then a getter function will + * also be derived and called. + */ + public String getPropertyName() { + return mPropertyName; + } + + /** + * Internal function, called by ValueAnimator and ObjectAnimator, to retrieve the value + * most recently calculated in calculateValue(). + * @return + */ + Object getAnimatedValue() { + return mAnimatedValue; + } + + @Override + public String toString() { + return mPropertyName + ": " + mKeyframeSet.toString(); + } + + /** + * Utility method to derive a setter/getter method name from a property name, where the + * prefix is typically "set" or "get" and the first letter of the property name is + * capitalized. + * + * @param prefix The precursor to the method name, before the property name begins, typically + * "set" or "get". + * @param propertyName The name of the property that represents the bulk of the method name + * after the prefix. The first letter of this word will be capitalized in the resulting + * method name. + * @return String the property name converted to a method name according to the conventions + * specified above. + */ + static String getMethodName(String prefix, String propertyName) { + if (propertyName == null || propertyName.length() == 0) { + // shouldn't get here + return prefix; + } + char firstLetter = Character.toUpperCase(propertyName.charAt(0)); + String theRest = propertyName.substring(1); + return prefix + firstLetter + theRest; + } + + static class IntPropertyValuesHolder extends PropertyValuesHolder { + + // Cache JNI functions to avoid looking them up twice + //private static final HashMap> sJNISetterPropertyMap = + // new HashMap>(); + //int mJniSetter; + //private IntProperty mIntProperty; + + IntKeyframeSet mIntKeyframeSet; + int mIntAnimatedValue; + + public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) { + super(propertyName); + mValueType = int.class; + mKeyframeSet = keyframeSet; + mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; + } + + //public IntPropertyValuesHolder(Property property, IntKeyframeSet keyframeSet) { + // super(property); + // mValueType = int.class; + // mKeyframeSet = keyframeSet; + // mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; + // if (property instanceof IntProperty) { + // mIntProperty = (IntProperty) mProperty; + // } + //} + + public IntPropertyValuesHolder(String propertyName, int... values) { + super(propertyName); + setIntValues(values); + } + + //public IntPropertyValuesHolder(Property property, int... values) { + // super(property); + // setIntValues(values); + // if (property instanceof IntProperty) { + // mIntProperty = (IntProperty) mProperty; + // } + //} + + @Override + public void setIntValues(int... values) { + super.setIntValues(values); + mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; + } + + @Override + void calculateValue(float fraction) { + mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction); + } + + @Override + Object getAnimatedValue() { + return mIntAnimatedValue; + } + + @Override + public IntPropertyValuesHolder clone() { + IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone(); + newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet; + return newPVH; + } + + /** + * Internal function to set the value on the target object, using the setter set up + * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator + * to handle turning the value calculated by ValueAnimator into a value set on the object + * according to the name of the property. + * @param target The target object on which the value is set + */ + @Override + void setAnimatedValue(Object target) { + //if (mIntProperty != null) { + // mIntProperty.setValue(target, mIntAnimatedValue); + // return; + //} + //if (mProperty != null) { + // mProperty.set(target, mIntAnimatedValue); + // return; + //} + //if (mJniSetter != 0) { + // nCallIntMethod(target, mJniSetter, mIntAnimatedValue); + // return; + //} + if (mSetter != null) { + try { + mTmpValueArray[0] = mIntAnimatedValue; + mSetter.invoke(target, mTmpValueArray); + } catch (InvocationTargetException e) { + Log.e("PropertyValuesHolder", e.toString()); + } catch (IllegalAccessException e) { + Log.e("PropertyValuesHolder", e.toString()); + } + } + } + + @Override + void setupSetter(Class targetClass) { + //if (mProperty != null) { + // return; + //} + // Check new static hashmap for setter method + //try { + // mPropertyMapLock.writeLock().lock(); + // HashMap propertyMap = sJNISetterPropertyMap.get(targetClass); + // if (propertyMap != null) { + // Integer mJniSetterInteger = propertyMap.get(mPropertyName); + // if (mJniSetterInteger != null) { + // mJniSetter = mJniSetterInteger; + // } + // } + // if (mJniSetter == 0) { + // String methodName = getMethodName("set", mPropertyName); + // mJniSetter = nGetIntMethod(targetClass, methodName); + // if (mJniSetter != 0) { + // if (propertyMap == null) { + // propertyMap = new HashMap(); + // sJNISetterPropertyMap.put(targetClass, propertyMap); + // } + // propertyMap.put(mPropertyName, mJniSetter); + // } + // } + //} catch (NoSuchMethodError e) { + // Log.d("PropertyValuesHolder", + // "Can't find native method using JNI, use reflection" + e); + //} finally { + // mPropertyMapLock.writeLock().unlock(); + //} + //if (mJniSetter == 0) { + // Couldn't find method through fast JNI approach - just use reflection + super.setupSetter(targetClass); + //} + } + } + + static class FloatPropertyValuesHolder extends PropertyValuesHolder { + + // Cache JNI functions to avoid looking them up twice + //private static final HashMap> sJNISetterPropertyMap = + // new HashMap>(); + //int mJniSetter; + //private FloatProperty mFloatProperty; + + FloatKeyframeSet mFloatKeyframeSet; + float mFloatAnimatedValue; + + public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) { + super(propertyName); + mValueType = float.class; + mKeyframeSet = keyframeSet; + mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; + } + + //public FloatPropertyValuesHolder(Property property, FloatKeyframeSet keyframeSet) { + // super(property); + // mValueType = float.class; + // mKeyframeSet = keyframeSet; + // mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; + // if (property instanceof FloatProperty) { + // mFloatProperty = (FloatProperty) mProperty; + // } + //} + + public FloatPropertyValuesHolder(String propertyName, float... values) { + super(propertyName); + setFloatValues(values); + } + + //public FloatPropertyValuesHolder(Property property, float... values) { + // super(property); + // setFloatValues(values); + // if (property instanceof FloatProperty) { + // mFloatProperty = (FloatProperty) mProperty; + // } + //} + + @Override + public void setFloatValues(float... values) { + super.setFloatValues(values); + mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; + } + + @Override + void calculateValue(float fraction) { + mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction); + } + + @Override + Object getAnimatedValue() { + return mFloatAnimatedValue; + } + + @Override + public FloatPropertyValuesHolder clone() { + FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone(); + newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet; + return newPVH; + } + + /** + * Internal function to set the value on the target object, using the setter set up + * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator + * to handle turning the value calculated by ValueAnimator into a value set on the object + * according to the name of the property. + * @param target The target object on which the value is set + */ + @Override + void setAnimatedValue(Object target) { + //if (mFloatProperty != null) { + // mFloatProperty.setValue(target, mFloatAnimatedValue); + // return; + //} + //if (mProperty != null) { + // mProperty.set(target, mFloatAnimatedValue); + // return; + //} + //if (mJniSetter != 0) { + // nCallFloatMethod(target, mJniSetter, mFloatAnimatedValue); + // return; + //} + if (mSetter != null) { + try { + mTmpValueArray[0] = mFloatAnimatedValue; + mSetter.invoke(target, mTmpValueArray); + } catch (InvocationTargetException e) { + Log.e("PropertyValuesHolder", e.toString()); + } catch (IllegalAccessException e) { + Log.e("PropertyValuesHolder", e.toString()); + } + } + } + + @Override + void setupSetter(Class targetClass) { + //if (mProperty != null) { + // return; + //} + // Check new static hashmap for setter method + //try { + // mPropertyMapLock.writeLock().lock(); + // HashMap propertyMap = sJNISetterPropertyMap.get(targetClass); + // if (propertyMap != null) { + // Integer mJniSetterInteger = propertyMap.get(mPropertyName); + // if (mJniSetterInteger != null) { + // mJniSetter = mJniSetterInteger; + // } + // } + // if (mJniSetter == 0) { + // String methodName = getMethodName("set", mPropertyName); + // mJniSetter = nGetFloatMethod(targetClass, methodName); + // if (mJniSetter != 0) { + // if (propertyMap == null) { + // propertyMap = new HashMap(); + // sJNISetterPropertyMap.put(targetClass, propertyMap); + // } + // propertyMap.put(mPropertyName, mJniSetter); + // } + // } + //} catch (NoSuchMethodError e) { + // Log.d("PropertyValuesHolder", + // "Can't find native method using JNI, use reflection" + e); + //} finally { + // mPropertyMapLock.writeLock().unlock(); + //} + //if (mJniSetter == 0) { + // Couldn't find method through fast JNI approach - just use reflection + super.setupSetter(targetClass); + //} + } + + } + + //native static private int nGetIntMethod(Class targetClass, String methodName); + //native static private int nGetFloatMethod(Class targetClass, String methodName); + //native static private void nCallIntMethod(Object target, int methodID, int arg); + //native static private void nCallFloatMethod(Object target, int methodID, float arg); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java new file mode 100644 index 0000000000..65b9efc9be --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +/** + * Interface for use with the {@link ValueAnimator#setEvaluator(com.actionbarsherlock.internal.nineoldandroids.animation.TypeEvaluator)} function. Evaluators + * allow developers to create animations on arbitrary property types, by allowing them to supply + * custom evaulators for types that are not automatically understood and used by the animation + * system. + * + * @see ValueAnimator#setEvaluator(com.actionbarsherlock.internal.nineoldandroids.animation.TypeEvaluator) + */ +public interface TypeEvaluator { + + /** + * This function returns the result of linearly interpolating the start and end values, with + * fraction representing the proportion between the start and end values. The + * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), + * where x0 is startValue, x1 is endValue, + * and t is fraction. + * + * @param fraction The fraction from the starting to the ending values + * @param startValue The start value. + * @param endValue The end value. + * @return A linear interpolation between the start and end values, given the + * fraction parameter. + */ + public T evaluate(float fraction, T startValue, T endValue); + +} \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java new file mode 100644 index 0000000000..401d476be0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java @@ -0,0 +1,1265 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.nineoldandroids.animation; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.util.AndroidRuntimeException; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This class provides a simple timing engine for running animations + * which calculate animated values and set them on target objects. + * + *

There is a single timing pulse that all animations use. It runs in a + * custom handler to ensure that property changes happen on the UI thread.

+ * + *

By default, ValueAnimator uses non-linear time interpolation, via the + * {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates + * out of an animation. This behavior can be changed by calling + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.ValueAnimator#setInterpolator(TimeInterpolator)}.

+ */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class ValueAnimator extends Animator { + + /** + * Internal constants + */ + + /* + * The default amount of time in ms between animation frames + */ + private static final long DEFAULT_FRAME_DELAY = 10; + + /** + * Messages sent to timing handler: START is sent when an animation first begins, FRAME is sent + * by the handler to itself to process the next animation frame + */ + static final int ANIMATION_START = 0; + static final int ANIMATION_FRAME = 1; + + /** + * Values used with internal variable mPlayingState to indicate the current state of an + * animation. + */ + static final int STOPPED = 0; // Not yet playing + static final int RUNNING = 1; // Playing normally + static final int SEEKED = 2; // Seeked to some time value + + /** + * Internal variables + * NOTE: This object implements the clone() method, making a deep copy of any referenced + * objects. As other non-trivial fields are added to this class, make sure to add logic + * to clone() to make deep copies of them. + */ + + // The first time that the animation's animateFrame() method is called. This time is used to + // determine elapsed time (and therefore the elapsed fraction) in subsequent calls + // to animateFrame() + long mStartTime; + + /** + * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked + * to a value. + */ + long mSeekTime = -1; + + // TODO: We access the following ThreadLocal variables often, some of them on every update. + // If ThreadLocal access is significantly expensive, we may want to put all of these + // fields into a structure sot hat we just access ThreadLocal once to get the reference + // to that structure, then access the structure directly for each field. + + // The static sAnimationHandler processes the internal timing loop on which all animations + // are based + private static ThreadLocal sAnimationHandler = + new ThreadLocal(); + + // The per-thread list of all active animations + private static final ThreadLocal> sAnimations = + new ThreadLocal>() { + @Override + protected ArrayList initialValue() { + return new ArrayList(); + } + }; + + // The per-thread set of animations to be started on the next animation frame + private static final ThreadLocal> sPendingAnimations = + new ThreadLocal>() { + @Override + protected ArrayList initialValue() { + return new ArrayList(); + } + }; + + /** + * Internal per-thread collections used to avoid set collisions as animations start and end + * while being processed. + */ + private static final ThreadLocal> sDelayedAnims = + new ThreadLocal>() { + @Override + protected ArrayList initialValue() { + return new ArrayList(); + } + }; + + private static final ThreadLocal> sEndingAnims = + new ThreadLocal>() { + @Override + protected ArrayList initialValue() { + return new ArrayList(); + } + }; + + private static final ThreadLocal> sReadyAnims = + new ThreadLocal>() { + @Override + protected ArrayList initialValue() { + return new ArrayList(); + } + }; + + // The time interpolator to be used if none is set on the animation + private static final /*Time*/Interpolator sDefaultInterpolator = + new AccelerateDecelerateInterpolator(); + + // type evaluators for the primitive types handled by this implementation + //private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); + //private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); + + /** + * Used to indicate whether the animation is currently playing in reverse. This causes the + * elapsed fraction to be inverted to calculate the appropriate values. + */ + private boolean mPlayingBackwards = false; + + /** + * This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the + * repeatCount (if repeatCount!=INFINITE), the animation ends + */ + private int mCurrentIteration = 0; + + /** + * Tracks current elapsed/eased fraction, for querying in getAnimatedFraction(). + */ + private float mCurrentFraction = 0f; + + /** + * Tracks whether a startDelay'd animation has begun playing through the startDelay. + */ + private boolean mStartedDelay = false; + + /** + * Tracks the time at which the animation began playing through its startDelay. This is + * different from the mStartTime variable, which is used to track when the animation became + * active (which is when the startDelay expired and the animation was added to the active + * animations list). + */ + private long mDelayStartTime; + + /** + * Flag that represents the current state of the animation. Used to figure out when to start + * an animation (if state == STOPPED). Also used to end an animation that + * has been cancel()'d or end()'d since the last animation frame. Possible values are + * STOPPED, RUNNING, SEEKED. + */ + int mPlayingState = STOPPED; + + /** + * Additional playing state to indicate whether an animator has been start()'d. There is + * some lag between a call to start() and the first animation frame. We should still note + * that the animation has been started, even if it's first animation frame has not yet + * happened, and reflect that state in isRunning(). + * Note that delayed animations are different: they are not started until their first + * animation frame, which occurs after their delay elapses. + */ + private boolean mRunning = false; + + /** + * Additional playing state to indicate whether an animator has been start()'d, whether or + * not there is a nonzero startDelay. + */ + private boolean mStarted = false; + + /** + * Flag that denotes whether the animation is set up and ready to go. Used to + * set up animation that has not yet been started. + */ + boolean mInitialized = false; + + // + // Backing variables + // + + // How long the animation should last in ms + private long mDuration = 300; + + // The amount of time in ms to delay starting the animation after start() is called + private long mStartDelay = 0; + + // The number of milliseconds between animation frames + private static long sFrameDelay = DEFAULT_FRAME_DELAY; + + // The number of times the animation will repeat. The default is 0, which means the animation + // will play only once + private int mRepeatCount = 0; + + /** + * The type of repetition that will occur when repeatMode is nonzero. RESTART means the + * animation will start from the beginning on every new cycle. REVERSE means the animation + * will reverse directions on each iteration. + */ + private int mRepeatMode = RESTART; + + /** + * The time interpolator to be used. The elapsed fraction of the animation will be passed + * through this interpolator to calculate the interpolated fraction, which is then used to + * calculate the animated values. + */ + private /*Time*/Interpolator mInterpolator = sDefaultInterpolator; + + /** + * The set of listeners to be sent events through the life of an animation. + */ + private ArrayList mUpdateListeners = null; + + /** + * The property/value sets being animated. + */ + PropertyValuesHolder[] mValues; + + /** + * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values + * by property name during calls to getAnimatedValue(String). + */ + HashMap mValuesMap; + + /** + * Public constants + */ + + /** + * When the animation reaches the end and repeatCount is INFINITE + * or a positive value, the animation restarts from the beginning. + */ + public static final int RESTART = 1; + /** + * When the animation reaches the end and repeatCount is INFINITE + * or a positive value, the animation reverses direction on every iteration. + */ + public static final int REVERSE = 2; + /** + * This value used used with the {@link #setRepeatCount(int)} property to repeat + * the animation indefinitely. + */ + public static final int INFINITE = -1; + + /** + * Creates a new ValueAnimator object. This default constructor is primarily for + * use internally; the factory methods which take parameters are more generally + * useful. + */ + public ValueAnimator() { + } + + /** + * Constructs and returns a ValueAnimator that animates between int values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofInt(int... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setIntValues(values); + return anim; + } + + /** + * Constructs and returns a ValueAnimator that animates between float values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofFloat(float... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setFloatValues(values); + return anim; + } + + /** + * Constructs and returns a ValueAnimator that animates between the values + * specified in the PropertyValuesHolder objects. + * + * @param values A set of PropertyValuesHolder objects whose values will be animated + * between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setValues(values); + return anim; + } + /** + * Constructs and returns a ValueAnimator that animates between Object values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

Since ValueAnimator does not know how to animate between arbitrary Objects, this + * factory method also takes a TypeEvaluator object that the ValueAnimator will use + * to perform that interpolation. + * + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the ncessry interpolation between the Object values to derive the animated + * value. + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setObjectValues(values); + anim.setEvaluator(evaluator); + return anim; + } + + /** + * Sets int values that will be animated between. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

If there are already multiple sets of values defined for this ValueAnimator via more + * than one PropertyValuesHolder object, this method will set the values for the first + * of those objects.

+ * + * @param values A set of values that the animation will animate between over time. + */ + public void setIntValues(int... values) { + if (values == null || values.length == 0) { + return; + } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofInt("", values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setIntValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets float values that will be animated between. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

If there are already multiple sets of values defined for this ValueAnimator via more + * than one PropertyValuesHolder object, this method will set the values for the first + * of those objects.

+ * + * @param values A set of values that the animation will animate between over time. + */ + public void setFloatValues(float... values) { + if (values == null || values.length == 0) { + return; + } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofFloat("", values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setFloatValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets the values to animate between for this animation. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

If there are already multiple sets of values defined for this ValueAnimator via more + * than one PropertyValuesHolder object, this method will set the values for the first + * of those objects.

+ * + *

There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate + * between these value objects. ValueAnimator only knows how to interpolate between the + * primitive types specified in the other setValues() methods.

+ * + * @param values The set of values to animate between. + */ + public void setObjectValues(Object... values) { + if (values == null || values.length == 0) { + return; + } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofObject("", + (TypeEvaluator)null, values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setObjectValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets the values, per property, being animated between. This function is called internally + * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can + * be constructed without values and this method can be called to set the values manually + * instead. + * + * @param values The set of values, per property, being animated between. + */ + public void setValues(PropertyValuesHolder... values) { + int numValues = values.length; + mValues = values; + mValuesMap = new HashMap(numValues); + for (int i = 0; i < numValues; ++i) { + PropertyValuesHolder valuesHolder = values[i]; + mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Returns the values that this ValueAnimator animates between. These values are stored in + * PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list + * of value objects instead. + * + * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the + * values, per property, that define the animation. + */ + public PropertyValuesHolder[] getValues() { + return mValues; + } + + /** + * This function is called immediately before processing the first animation + * frame of an animation. If there is a nonzero startDelay, the + * function is called after that delay ends. + * It takes care of the final initialization steps for the + * animation. + * + *

Overrides of this method should call the superclass method to ensure + * that internal mechanisms for the animation are set up correctly.

+ */ + void initAnimation() { + if (!mInitialized) { + int numValues = mValues.length; + for (int i = 0; i < numValues; ++i) { + mValues[i].init(); + } + mInitialized = true; + } + } + + + /** + * Sets the length of the animation. The default duration is 300 milliseconds. + * + * @param duration The length of the animation, in milliseconds. This value cannot + * be negative. + * @return ValueAnimator The object called with setDuration(). This return + * value makes it easier to compose statements together that construct and then set the + * duration, as in ValueAnimator.ofInt(0, 10).setDuration(500).start(). + */ + public ValueAnimator setDuration(long duration) { + if (duration < 0) { + throw new IllegalArgumentException("Animators cannot have negative duration: " + + duration); + } + mDuration = duration; + return this; + } + + /** + * Gets the length of the animation. The default duration is 300 milliseconds. + * + * @return The length of the animation, in milliseconds. + */ + public long getDuration() { + return mDuration; + } + + /** + * Sets the position of the animation to the specified point in time. This time should + * be between 0 and the total duration of the animation, including any repetition. If + * the animation has not yet been started, then it will not advance forward after it is + * set to this time; it will simply set the time to this value and perform any appropriate + * actions based on that time. If the animation is already running, then setCurrentPlayTime() + * will set the current playing time to this value and continue playing from that point. + * + * @param playTime The time, in milliseconds, to which the animation is advanced or rewound. + */ + public void setCurrentPlayTime(long playTime) { + initAnimation(); + long currentTime = AnimationUtils.currentAnimationTimeMillis(); + if (mPlayingState != RUNNING) { + mSeekTime = playTime; + mPlayingState = SEEKED; + } + mStartTime = currentTime - playTime; + animationFrame(currentTime); + } + + /** + * Gets the current position of the animation in time, which is equal to the current + * time minus the time that the animation started. An animation that is not yet started will + * return a value of zero. + * + * @return The current position in time of the animation. + */ + public long getCurrentPlayTime() { + if (!mInitialized || mPlayingState == STOPPED) { + return 0; + } + return AnimationUtils.currentAnimationTimeMillis() - mStartTime; + } + + /** + * This custom, static handler handles the timing pulse that is shared by + * all active animations. This approach ensures that the setting of animation + * values will happen on the UI thread and that all animations will share + * the same times for calculating their values, which makes synchronizing + * animations possible. + * + */ + private static class AnimationHandler extends Handler { + /** + * There are only two messages that we care about: ANIMATION_START and + * ANIMATION_FRAME. The START message is sent when an animation's start() + * method is called. It cannot start synchronously when start() is called + * because the call may be on the wrong thread, and it would also not be + * synchronized with other animations because it would not start on a common + * timing pulse. So each animation sends a START message to the handler, which + * causes the handler to place the animation on the active animations queue and + * start processing frames for that animation. + * The FRAME message is the one that is sent over and over while there are any + * active animations to process. + */ + @Override + public void handleMessage(Message msg) { + boolean callAgain = true; + ArrayList animations = sAnimations.get(); + ArrayList delayedAnims = sDelayedAnims.get(); + switch (msg.what) { + // TODO: should we avoid sending frame message when starting if we + // were already running? + case ANIMATION_START: + ArrayList pendingAnimations = sPendingAnimations.get(); + if (animations.size() > 0 || delayedAnims.size() > 0) { + callAgain = false; + } + // pendingAnims holds any animations that have requested to be started + // We're going to clear sPendingAnimations, but starting animation may + // cause more to be added to the pending list (for example, if one animation + // starting triggers another starting). So we loop until sPendingAnimations + // is empty. + while (pendingAnimations.size() > 0) { + ArrayList pendingCopy = + (ArrayList) pendingAnimations.clone(); + pendingAnimations.clear(); + int count = pendingCopy.size(); + for (int i = 0; i < count; ++i) { + ValueAnimator anim = pendingCopy.get(i); + // If the animation has a startDelay, place it on the delayed list + if (anim.mStartDelay == 0) { + anim.startAnimation(); + } else { + delayedAnims.add(anim); + } + } + } + // fall through to process first frame of new animations + case ANIMATION_FRAME: + // currentTime holds the common time for all animations processed + // during this frame + long currentTime = AnimationUtils.currentAnimationTimeMillis(); + ArrayList readyAnims = sReadyAnims.get(); + ArrayList endingAnims = sEndingAnims.get(); + + // First, process animations currently sitting on the delayed queue, adding + // them to the active animations if they are ready + int numDelayedAnims = delayedAnims.size(); + for (int i = 0; i < numDelayedAnims; ++i) { + ValueAnimator anim = delayedAnims.get(i); + if (anim.delayedAnimationFrame(currentTime)) { + readyAnims.add(anim); + } + } + int numReadyAnims = readyAnims.size(); + if (numReadyAnims > 0) { + for (int i = 0; i < numReadyAnims; ++i) { + ValueAnimator anim = readyAnims.get(i); + anim.startAnimation(); + anim.mRunning = true; + delayedAnims.remove(anim); + } + readyAnims.clear(); + } + + // Now process all active animations. The return value from animationFrame() + // tells the handler whether it should now be ended + int numAnims = animations.size(); + int i = 0; + while (i < numAnims) { + ValueAnimator anim = animations.get(i); + if (anim.animationFrame(currentTime)) { + endingAnims.add(anim); + } + if (animations.size() == numAnims) { + ++i; + } else { + // An animation might be canceled or ended by client code + // during the animation frame. Check to see if this happened by + // seeing whether the current index is the same as it was before + // calling animationFrame(). Another approach would be to copy + // animations to a temporary list and process that list instead, + // but that entails garbage and processing overhead that would + // be nice to avoid. + --numAnims; + endingAnims.remove(anim); + } + } + if (endingAnims.size() > 0) { + for (i = 0; i < endingAnims.size(); ++i) { + endingAnims.get(i).endAnimation(); + } + endingAnims.clear(); + } + + // If there are still active or delayed animations, call the handler again + // after the frameDelay + if (callAgain && (!animations.isEmpty() || !delayedAnims.isEmpty())) { + sendEmptyMessageDelayed(ANIMATION_FRAME, Math.max(0, sFrameDelay - + (AnimationUtils.currentAnimationTimeMillis() - currentTime))); + } + break; + } + } + } + + /** + * The amount of time, in milliseconds, to delay starting the animation after + * {@link #start()} is called. + * + * @return the number of milliseconds to delay running the animation + */ + public long getStartDelay() { + return mStartDelay; + } + + /** + * The amount of time, in milliseconds, to delay starting the animation after + * {@link #start()} is called. + + * @param startDelay The amount of the delay, in milliseconds + */ + public void setStartDelay(long startDelay) { + this.mStartDelay = startDelay; + } + + /** + * The amount of time, in milliseconds, between each frame of the animation. This is a + * requested time that the animation will attempt to honor, but the actual delay between + * frames may be different, depending on system load and capabilities. This is a static + * function because the same delay will be applied to all animations, since they are all + * run off of a single timing loop. + * + * @return the requested time between frames, in milliseconds + */ + public static long getFrameDelay() { + return sFrameDelay; + } + + /** + * The amount of time, in milliseconds, between each frame of the animation. This is a + * requested time that the animation will attempt to honor, but the actual delay between + * frames may be different, depending on system load and capabilities. This is a static + * function because the same delay will be applied to all animations, since they are all + * run off of a single timing loop. + * + * @param frameDelay the requested time between frames, in milliseconds + */ + public static void setFrameDelay(long frameDelay) { + sFrameDelay = frameDelay; + } + + /** + * The most recent value calculated by this ValueAnimator when there is just one + * property being animated. This value is only sensible while the animation is running. The main + * purpose for this read-only property is to retrieve the value from the ValueAnimator + * during a call to {@link com.actionbarsherlock.internal.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate(com.actionbarsherlock.internal.nineoldandroids.animation.ValueAnimator)}, which + * is called during each animation frame, immediately after the value is calculated. + * + * @return animatedValue The value most recently calculated by this ValueAnimator for + * the single property being animated. If there are several properties being animated + * (specified by several PropertyValuesHolder objects in the constructor), this function + * returns the animated value for the first of those objects. + */ + public Object getAnimatedValue() { + if (mValues != null && mValues.length > 0) { + return mValues[0].getAnimatedValue(); + } + // Shouldn't get here; should always have values unless ValueAnimator was set up wrong + return null; + } + + /** + * The most recent value calculated by this ValueAnimator for propertyName. + * The main purpose for this read-only property is to retrieve the value from the + * ValueAnimator during a call to + * {@link com.actionbarsherlock.internal.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate(com.actionbarsherlock.internal.nineoldandroids.animation.ValueAnimator)}, which + * is called during each animation frame, immediately after the value is calculated. + * + * @return animatedValue The value most recently calculated for the named property + * by this ValueAnimator. + */ + public Object getAnimatedValue(String propertyName) { + PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName); + if (valuesHolder != null) { + return valuesHolder.getAnimatedValue(); + } else { + // At least avoid crashing if called with bogus propertyName + return null; + } + } + + /** + * Sets how many times the animation should be repeated. If the repeat + * count is 0, the animation is never repeated. If the repeat count is + * greater than 0 or {@link #INFINITE}, the repeat mode will be taken + * into account. The repeat count is 0 by default. + * + * @param value the number of times the animation should be repeated + */ + public void setRepeatCount(int value) { + mRepeatCount = value; + } + /** + * Defines how many times the animation should repeat. The default value + * is 0. + * + * @return the number of times the animation should repeat, or {@link #INFINITE} + */ + public int getRepeatCount() { + return mRepeatCount; + } + + /** + * 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}. Defaults to {@link #RESTART}. + * + * @param value {@link #RESTART} or {@link #REVERSE} + */ + public void setRepeatMode(int value) { + mRepeatMode = value; + } + + /** + * Defines what this animation should do when it reaches the end. + * + * @return either one of {@link #REVERSE} or {@link #RESTART} + */ + public int getRepeatMode() { + return mRepeatMode; + } + + /** + * Adds a listener to the set of listeners that are sent update events through the life of + * an animation. This method is called on all listeners for every frame of the animation, + * after the values for the animation have been calculated. + * + * @param listener the listener to be added to the current set of listeners for this animation. + */ + public void addUpdateListener(AnimatorUpdateListener listener) { + if (mUpdateListeners == null) { + mUpdateListeners = new ArrayList(); + } + mUpdateListeners.add(listener); + } + + /** + * Removes all listeners from the set listening to frame updates for this animation. + */ + public void removeAllUpdateListeners() { + if (mUpdateListeners == null) { + return; + } + mUpdateListeners.clear(); + mUpdateListeners = null; + } + + /** + * Removes a listener from the set listening to frame updates for this animation. + * + * @param listener the listener to be removed from the current set of update listeners + * for this animation. + */ + public void removeUpdateListener(AnimatorUpdateListener listener) { + if (mUpdateListeners == null) { + return; + } + mUpdateListeners.remove(listener); + if (mUpdateListeners.size() == 0) { + mUpdateListeners = null; + } + } + + + /** + * The time interpolator used in calculating the elapsed fraction of this animation. The + * interpolator determines whether the animation runs with linear or non-linear motion, + * such as acceleration and deceleration. The default value is + * {@link android.view.animation.AccelerateDecelerateInterpolator} + * + * @param value the interpolator to be used by this animation. A value of null + * will result in linear interpolation. + */ + @Override + public void setInterpolator(/*Time*/Interpolator value) { + if (value != null) { + mInterpolator = value; + } else { + mInterpolator = new LinearInterpolator(); + } + } + + /** + * Returns the timing interpolator that this ValueAnimator uses. + * + * @return The timing interpolator for this ValueAnimator. + */ + public /*Time*/Interpolator getInterpolator() { + return mInterpolator; + } + + /** + * The type evaluator to be used when calculating the animated values of this animation. + * The system will automatically assign a float or int evaluator based on the type + * of startValue and endValue in the constructor. But if these values + * are not one of these primitive types, or if different evaluation is desired (such as is + * necessary with int values that represent colors), a custom evaluator needs to be assigned. + * For example, when running an animation on color values, the {@link ArgbEvaluator} + * should be used to get correct RGB color interpolation. + * + *

If this ValueAnimator has only one set of values being animated between, this evaluator + * will be used for that set. If there are several sets of values being animated, which is + * the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator + * is assigned just to the first PropertyValuesHolder object.

+ * + * @param value the evaluator to be used this animation + */ + public void setEvaluator(TypeEvaluator value) { + if (value != null && mValues != null && mValues.length > 0) { + mValues[0].setEvaluator(value); + } + } + + /** + * Start the animation playing. This version of start() takes a boolean flag that indicates + * whether the animation should play in reverse. The flag is usually false, but may be set + * to true if called from the reverse() method. + * + *

The animation started by calling this method will be run on the thread that called + * this method. This thread should have a Looper on it (a runtime exception will be thrown if + * this is not the case). Also, if the animation will animate + * properties of objects in the view hierarchy, then the calling thread should be the UI + * thread for that view hierarchy.

+ * + * @param playBackwards Whether the ValueAnimator should start playing in reverse. + */ + private void start(boolean playBackwards) { + if (Looper.myLooper() == null) { + throw new AndroidRuntimeException("Animators may only be run on Looper threads"); + } + mPlayingBackwards = playBackwards; + mCurrentIteration = 0; + mPlayingState = STOPPED; + mStarted = true; + mStartedDelay = false; + sPendingAnimations.get().add(this); + if (mStartDelay == 0) { + // This sets the initial value of the animation, prior to actually starting it running + setCurrentPlayTime(getCurrentPlayTime()); + mPlayingState = STOPPED; + mRunning = true; + + if (mListeners != null) { + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onAnimationStart(this); + } + } + } + AnimationHandler animationHandler = sAnimationHandler.get(); + if (animationHandler == null) { + animationHandler = new AnimationHandler(); + sAnimationHandler.set(animationHandler); + } + animationHandler.sendEmptyMessage(ANIMATION_START); + } + + @Override + public void start() { + start(false); + } + + @Override + public void cancel() { + // Only cancel if the animation is actually running or has been started and is about + // to run + if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) || + sDelayedAnims.get().contains(this)) { + // Only notify listeners if the animator has actually started + if (mRunning && mListeners != null) { + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + for (AnimatorListener listener : tmpListeners) { + listener.onAnimationCancel(this); + } + } + endAnimation(); + } + } + + @Override + public void end() { + if (!sAnimations.get().contains(this) && !sPendingAnimations.get().contains(this)) { + // Special case if the animation has not yet started; get it ready for ending + mStartedDelay = false; + startAnimation(); + } else if (!mInitialized) { + initAnimation(); + } + // The final value set on the target varies, depending on whether the animation + // was supposed to repeat an odd number of times + if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) { + animateValue(0f); + } else { + animateValue(1f); + } + endAnimation(); + } + + @Override + public boolean isRunning() { + return (mPlayingState == RUNNING || mRunning); + } + + @Override + public boolean isStarted() { + return mStarted; + } + + /** + * Plays the ValueAnimator in reverse. If the animation is already running, + * it will stop itself and play backwards from the point reached when reverse was called. + * If the animation is not currently running, then it will start from the end and + * play backwards. This behavior is only set for the current animation; future playing + * of the animation will use the default behavior of playing forward. + */ + public void reverse() { + mPlayingBackwards = !mPlayingBackwards; + if (mPlayingState == RUNNING) { + long currentTime = AnimationUtils.currentAnimationTimeMillis(); + long currentPlayTime = currentTime - mStartTime; + long timeLeft = mDuration - currentPlayTime; + mStartTime = currentTime - timeLeft; + } else { + start(true); + } + } + + /** + * Called internally to end an animation by removing it from the animations list. Must be + * called on the UI thread. + */ + private void endAnimation() { + sAnimations.get().remove(this); + sPendingAnimations.get().remove(this); + sDelayedAnims.get().remove(this); + mPlayingState = STOPPED; + if (mRunning && mListeners != null) { + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onAnimationEnd(this); + } + } + mRunning = false; + mStarted = false; + } + + /** + * Called internally to start an animation by adding it to the active animations list. Must be + * called on the UI thread. + */ + private void startAnimation() { + initAnimation(); + sAnimations.get().add(this); + if (mStartDelay > 0 && mListeners != null) { + // Listeners were already notified in start() if startDelay is 0; this is + // just for delayed animations + ArrayList tmpListeners = + (ArrayList) mListeners.clone(); + int numListeners = tmpListeners.size(); + for (int i = 0; i < numListeners; ++i) { + tmpListeners.get(i).onAnimationStart(this); + } + } + } + + /** + * Internal function called to process an animation frame on an animation that is currently + * sleeping through its startDelay phase. The return value indicates whether it + * should be woken up and put on the active animations queue. + * + * @param currentTime The current animation time, used to calculate whether the animation + * has exceeded its startDelay and should be started. + * @return True if the animation's startDelay has been exceeded and the animation + * should be added to the set of active animations. + */ + private boolean delayedAnimationFrame(long currentTime) { + if (!mStartedDelay) { + mStartedDelay = true; + mDelayStartTime = currentTime; + } else { + long deltaTime = currentTime - mDelayStartTime; + if (deltaTime > mStartDelay) { + // startDelay ended - start the anim and record the + // mStartTime appropriately + mStartTime = currentTime - (deltaTime - mStartDelay); + mPlayingState = RUNNING; + return true; + } + } + return false; + } + + /** + * This internal function processes a single animation frame for a given animation. The + * currentTime parameter is the timing pulse sent by the handler, used to calculate the + * elapsed duration, and therefore + * the elapsed fraction, of the animation. The return value indicates whether the animation + * should be ended (which happens when the elapsed time of the animation exceeds the + * animation's duration, including the repeatCount). + * + * @param currentTime The current time, as tracked by the static timing handler + * @return true if the animation's duration, including any repetitions due to + * repeatCount has been exceeded and the animation should be ended. + */ + boolean animationFrame(long currentTime) { + boolean done = false; + + if (mPlayingState == STOPPED) { + mPlayingState = RUNNING; + if (mSeekTime < 0) { + mStartTime = currentTime; + } else { + mStartTime = currentTime - mSeekTime; + // Now that we're playing, reset the seek time + mSeekTime = -1; + } + } + switch (mPlayingState) { + case RUNNING: + case SEEKED: + float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f; + if (fraction >= 1f) { + if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) { + // Time to repeat + if (mListeners != null) { + int numListeners = mListeners.size(); + for (int i = 0; i < numListeners; ++i) { + mListeners.get(i).onAnimationRepeat(this); + } + } + if (mRepeatMode == REVERSE) { + mPlayingBackwards = mPlayingBackwards ? false : true; + } + mCurrentIteration += (int)fraction; + fraction = fraction % 1f; + mStartTime += mDuration; + } else { + done = true; + fraction = Math.min(fraction, 1.0f); + } + } + if (mPlayingBackwards) { + fraction = 1f - fraction; + } + animateValue(fraction); + break; + } + + return done; + } + + /** + * Returns the current animation fraction, which is the elapsed/interpolated fraction used in + * the most recent frame update on the animation. + * + * @return Elapsed/interpolated fraction of the animation. + */ + public float getAnimatedFraction() { + return mCurrentFraction; + } + + /** + * This method is called with the elapsed fraction of the animation during every + * animation frame. This function turns the elapsed fraction into an interpolated fraction + * and then into an animated value (from the evaluator. The function is called mostly during + * animation updates, but it is also called when the end() + * function is called, to set the final value on the property. + * + *

Overrides of this method must call the superclass to perform the calculation + * of the animated value.

+ * + * @param fraction The elapsed fraction of the animation. + */ + void animateValue(float fraction) { + fraction = mInterpolator.getInterpolation(fraction); + mCurrentFraction = fraction; + int numValues = mValues.length; + for (int i = 0; i < numValues; ++i) { + mValues[i].calculateValue(fraction); + } + if (mUpdateListeners != null) { + int numListeners = mUpdateListeners.size(); + for (int i = 0; i < numListeners; ++i) { + mUpdateListeners.get(i).onAnimationUpdate(this); + } + } + } + + @Override + public ValueAnimator clone() { + final ValueAnimator anim = (ValueAnimator) super.clone(); + if (mUpdateListeners != null) { + ArrayList oldListeners = mUpdateListeners; + anim.mUpdateListeners = new ArrayList(); + int numListeners = oldListeners.size(); + for (int i = 0; i < numListeners; ++i) { + anim.mUpdateListeners.add(oldListeners.get(i)); + } + } + anim.mSeekTime = -1; + anim.mPlayingBackwards = false; + anim.mCurrentIteration = 0; + anim.mInitialized = false; + anim.mPlayingState = STOPPED; + anim.mStartedDelay = false; + PropertyValuesHolder[] oldValues = mValues; + if (oldValues != null) { + int numValues = oldValues.length; + anim.mValues = new PropertyValuesHolder[numValues]; + anim.mValuesMap = new HashMap(numValues); + for (int i = 0; i < numValues; ++i) { + PropertyValuesHolder newValuesHolder = oldValues[i].clone(); + anim.mValues[i] = newValuesHolder; + anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder); + } + } + return anim; + } + + /** + * Implementors of this interface can add themselves as update listeners + * to an ValueAnimator instance to receive callbacks on every animation + * frame, after the current frame's values have been calculated for that + * ValueAnimator. + */ + public static interface AnimatorUpdateListener { + /** + *

Notifies the occurrence of another frame of the animation.

+ * + * @param animation The animation which was repeated. + */ + void onAnimationUpdate(ValueAnimator animation); + + } + + /** + * Return the number of animations currently running. + * + * Used by StrictMode internally to annotate violations. Only + * called on the main thread. + * + * @hide + */ + public static int getCurrentAnimationsCount() { + return sAnimations.get().size(); + } + + /** + * Clear all animations on this thread, without canceling or ending them. + * This should be used with caution. + * + * @hide + */ + public static void clearAllAnimations() { + sAnimations.get().clear(); + sPendingAnimations.get().clear(); + sDelayedAnims.get().clear(); + } + + @Override + public String toString() { + String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode()); + if (mValues != null) { + for (int i = 0; i < mValues.length; ++i) { + returnVal += "\n " + mValues[i].toString(); + } + } + return returnVal; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java new file mode 100644 index 0000000000..7b830b9c05 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java @@ -0,0 +1,79 @@ +package com.actionbarsherlock.internal.nineoldandroids.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.ViewGroup; + +import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; + +public abstract class NineViewGroup extends ViewGroup { + private final AnimatorProxy mProxy; + + public NineViewGroup(Context context) { + super(context); + mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; + } + public NineViewGroup(Context context, AttributeSet attrs) { + super(context, attrs); + mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; + } + public NineViewGroup(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; + } + + @Override + public void setVisibility(int visibility) { + if (mProxy != null) { + if (visibility == GONE) { + clearAnimation(); + } else if (visibility == VISIBLE) { + setAnimation(mProxy); + } + } + super.setVisibility(visibility); + } + + public float getAlpha() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getAlpha(); + } else { + return super.getAlpha(); + } + } + public void setAlpha(float alpha) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setAlpha(alpha); + } else { + super.setAlpha(alpha); + } + } + public float getTranslationX() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getTranslationX(); + } else { + return super.getTranslationX(); + } + } + public void setTranslationX(float translationX) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setTranslationX(translationX); + } else { + super.setTranslationX(translationX); + } + } + public float getTranslationY() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getTranslationY(); + } else { + return super.getTranslationY(); + } + } + public void setTranslationY(float translationY) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setTranslationY(translationY); + } else { + super.setTranslationY(translationY); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java new file mode 100644 index 0000000000..067d0494ee --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java @@ -0,0 +1,212 @@ +package com.actionbarsherlock.internal.nineoldandroids.view.animation; + +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; +import android.graphics.Matrix; +import android.graphics.RectF; +import android.os.Build; +import android.util.FloatMath; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Transformation; + +public final class AnimatorProxy extends Animation { + public static final boolean NEEDS_PROXY = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB; + + private static final WeakHashMap PROXIES = + new WeakHashMap(); + + public static AnimatorProxy wrap(View view) { + AnimatorProxy proxy = PROXIES.get(view); + if (proxy == null) { + proxy = new AnimatorProxy(view); + PROXIES.put(view, proxy); + } + return proxy; + } + + private final WeakReference mView; + + private float mAlpha = 1; + private float mScaleX = 1; + private float mScaleY = 1; + private float mTranslationX; + private float mTranslationY; + + private final RectF mBefore = new RectF(); + private final RectF mAfter = new RectF(); + private final Matrix mTempMatrix = new Matrix(); + + private AnimatorProxy(View view) { + setDuration(0); //perform transformation immediately + setFillAfter(true); //persist transformation beyond duration + view.setAnimation(this); + mView = new WeakReference(view); + } + + public float getAlpha() { + return mAlpha; + } + public void setAlpha(float alpha) { + if (mAlpha != alpha) { + mAlpha = alpha; + View view = mView.get(); + if (view != null) { + view.invalidate(); + } + } + } + public float getScaleX() { + return mScaleX; + } + public void setScaleX(float scaleX) { + if (mScaleX != scaleX) { + prepareForUpdate(); + mScaleX = scaleX; + invalidateAfterUpdate(); + } + } + public float getScaleY() { + return mScaleY; + } + public void setScaleY(float scaleY) { + if (mScaleY != scaleY) { + prepareForUpdate(); + mScaleY = scaleY; + invalidateAfterUpdate(); + } + } + public int getScrollX() { + View view = mView.get(); + if (view == null) { + return 0; + } + return view.getScrollX(); + } + public void setScrollX(int value) { + View view = mView.get(); + if (view != null) { + view.scrollTo(value, view.getScrollY()); + } + } + public int getScrollY() { + View view = mView.get(); + if (view == null) { + return 0; + } + return view.getScrollY(); + } + public void setScrollY(int value) { + View view = mView.get(); + if (view != null) { + view.scrollTo(view.getScrollY(), value); + } + } + + public float getTranslationX() { + return mTranslationX; + } + public void setTranslationX(float translationX) { + if (mTranslationX != translationX) { + prepareForUpdate(); + mTranslationX = translationX; + invalidateAfterUpdate(); + } + } + public float getTranslationY() { + return mTranslationY; + } + public void setTranslationY(float translationY) { + if (mTranslationY != translationY) { + prepareForUpdate(); + mTranslationY = translationY; + invalidateAfterUpdate(); + } + } + + private void prepareForUpdate() { + View view = mView.get(); + if (view != null) { + computeRect(mBefore, view); + } + } + private void invalidateAfterUpdate() { + View view = mView.get(); + if (view == null) { + return; + } + View parent = (View)view.getParent(); + if (parent == null) { + return; + } + + view.setAnimation(this); + + final RectF after = mAfter; + computeRect(after, view); + after.union(mBefore); + + parent.invalidate( + (int) FloatMath.floor(after.left), + (int) FloatMath.floor(after.top), + (int) FloatMath.ceil(after.right), + (int) FloatMath.ceil(after.bottom)); + } + + private void computeRect(final RectF r, View view) { + // compute current rectangle according to matrix transformation + final float w = view.getWidth(); + final float h = view.getHeight(); + + // use a rectangle at 0,0 to make sure we don't run into issues with scaling + r.set(0, 0, w, h); + + final Matrix m = mTempMatrix; + m.reset(); + transformMatrix(m, view); + mTempMatrix.mapRect(r); + + r.offset(view.getLeft(), view.getTop()); + + // Straighten coords if rotations flipped them + if (r.right < r.left) { + final float f = r.right; + r.right = r.left; + r.left = f; + } + if (r.bottom < r.top) { + final float f = r.top; + r.top = r.bottom; + r.bottom = f; + } + } + + private void transformMatrix(Matrix m, View view) { + final float w = view.getWidth(); + final float h = view.getHeight(); + + final float sX = mScaleX; + final float sY = mScaleY; + if ((sX != 1.0f) || (sY != 1.0f)) { + final float deltaSX = ((sX * w) - w) / 2f; + final float deltaSY = ((sY * h) - h) / 2f; + m.postScale(sX, sY); + m.postTranslate(-deltaSX, -deltaSY); + } + m.postTranslate(mTranslationX, mTranslationY); + } + + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + View view = mView.get(); + if (view != null) { + t.setAlpha(mAlpha); + transformMatrix(t.getMatrix(), view); + } + } + + @Override + public void reset() { + /* Do nothing. */ + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java new file mode 100644 index 0000000000..953e3e8444 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java @@ -0,0 +1,57 @@ +package com.actionbarsherlock.internal.nineoldandroids.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.FrameLayout; + +import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; + +public class NineFrameLayout extends FrameLayout { + private final AnimatorProxy mProxy; + + public NineFrameLayout(Context context, AttributeSet attrs) { + super(context, attrs); + mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; + } + + @Override + public void setVisibility(int visibility) { + if (mProxy != null) { + if (visibility == GONE) { + clearAnimation(); + } else if (visibility == VISIBLE) { + setAnimation(mProxy); + } + } + super.setVisibility(visibility); + } + + public float getAlpha() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getAlpha(); + } else { + return super.getAlpha(); + } + } + public void setAlpha(float alpha) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setAlpha(alpha); + } else { + super.setAlpha(alpha); + } + } + public float getTranslationY() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getTranslationY(); + } else { + return super.getTranslationY(); + } + } + public void setTranslationY(float translationY) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setTranslationY(translationY); + } else { + super.setTranslationY(translationY); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java new file mode 100644 index 0000000000..129b5aaaa6 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java @@ -0,0 +1,41 @@ +package com.actionbarsherlock.internal.nineoldandroids.widget; + +import android.content.Context; +import android.widget.HorizontalScrollView; +import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; + +public class NineHorizontalScrollView extends HorizontalScrollView { + private final AnimatorProxy mProxy; + + public NineHorizontalScrollView(Context context) { + super(context); + mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; + } + + @Override + public void setVisibility(int visibility) { + if (mProxy != null) { + if (visibility == GONE) { + clearAnimation(); + } else if (visibility == VISIBLE) { + setAnimation(mProxy); + } + } + super.setVisibility(visibility); + } + + public float getAlpha() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getAlpha(); + } else { + return super.getAlpha(); + } + } + public void setAlpha(float alpha) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setAlpha(alpha); + } else { + super.setAlpha(alpha); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java new file mode 100644 index 0000000000..1f381013a7 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java @@ -0,0 +1,57 @@ +package com.actionbarsherlock.internal.nineoldandroids.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; + +public class NineLinearLayout extends LinearLayout { + private final AnimatorProxy mProxy; + + public NineLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; + } + + @Override + public void setVisibility(int visibility) { + if (mProxy != null) { + if (visibility == GONE) { + clearAnimation(); + } else if (visibility == VISIBLE) { + setAnimation(mProxy); + } + } + super.setVisibility(visibility); + } + + public float getAlpha() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getAlpha(); + } else { + return super.getAlpha(); + } + } + public void setAlpha(float alpha) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setAlpha(alpha); + } else { + super.setAlpha(alpha); + } + } + public float getTranslationX() { + if (AnimatorProxy.NEEDS_PROXY) { + return mProxy.getTranslationX(); + } else { + return super.getTranslationX(); + } + } + public void setTranslationX(float translationX) { + if (AnimatorProxy.NEEDS_PROXY) { + mProxy.setTranslationX(translationX); + } else { + super.setTranslationX(translationX); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java new file mode 100644 index 0000000000..b136d50f07 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java @@ -0,0 +1,40 @@ +package com.actionbarsherlock.internal.view; + +import com.actionbarsherlock.internal.view.menu.SubMenuWrapper; +import com.actionbarsherlock.view.ActionProvider; +import android.view.View; + +public class ActionProviderWrapper extends android.view.ActionProvider { + private final ActionProvider mProvider; + + + public ActionProviderWrapper(ActionProvider provider) { + super(null/*TODO*/); //XXX this *should* be unused + mProvider = provider; + } + + + public ActionProvider unwrap() { + return mProvider; + } + + @Override + public View onCreateActionView() { + return mProvider.onCreateActionView(); + } + + @Override + public boolean hasSubMenu() { + return mProvider.hasSubMenu(); + } + + @Override + public boolean onPerformDefaultAction() { + return mProvider.onPerformDefaultAction(); + } + + @Override + public void onPrepareSubMenu(android.view.SubMenu subMenu) { + mProvider.onPrepareSubMenu(new SubMenuWrapper(subMenu)); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java new file mode 100644 index 0000000000..0a87bd3f79 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.actionbarsherlock.internal.view; + +import android.content.Context; +import android.view.View; +import android.view.accessibility.AccessibilityEvent; + +import java.lang.ref.WeakReference; + +import com.actionbarsherlock.internal.view.menu.MenuBuilder; +import com.actionbarsherlock.internal.view.menu.MenuPopupHelper; +import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; +import com.actionbarsherlock.internal.widget.ActionBarContextView; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; + +public class StandaloneActionMode extends ActionMode implements MenuBuilder.Callback { + private Context mContext; + private ActionBarContextView mContextView; + private ActionMode.Callback mCallback; + private WeakReference mCustomView; + private boolean mFinished; + private boolean mFocusable; + + private MenuBuilder mMenu; + + public StandaloneActionMode(Context context, ActionBarContextView view, + ActionMode.Callback callback, boolean isFocusable) { + mContext = context; + mContextView = view; + mCallback = callback; + + mMenu = new MenuBuilder(context).setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + mMenu.setCallback(this); + mFocusable = isFocusable; + } + + @Override + public void setTitle(CharSequence title) { + mContextView.setTitle(title); + } + + @Override + public void setSubtitle(CharSequence subtitle) { + mContextView.setSubtitle(subtitle); + } + + @Override + public void setTitle(int resId) { + setTitle(mContext.getString(resId)); + } + + @Override + public void setSubtitle(int resId) { + setSubtitle(mContext.getString(resId)); + } + + @Override + public void setCustomView(View view) { + mContextView.setCustomView(view); + mCustomView = view != null ? new WeakReference(view) : null; + } + + @Override + public void invalidate() { + mCallback.onPrepareActionMode(this, mMenu); + } + + @Override + public void finish() { + if (mFinished) { + return; + } + mFinished = true; + + mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + mCallback.onDestroyActionMode(this); + } + + @Override + public Menu getMenu() { + return mMenu; + } + + @Override + public CharSequence getTitle() { + return mContextView.getTitle(); + } + + @Override + public CharSequence getSubtitle() { + return mContextView.getSubtitle(); + } + + @Override + public View getCustomView() { + return mCustomView != null ? mCustomView.get() : null; + } + + @Override + public MenuInflater getMenuInflater() { + return new MenuInflater(mContext); + } + + public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { + return mCallback.onActionItemClicked(this, item); + } + + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + } + + public boolean onSubMenuSelected(SubMenuBuilder subMenu) { + if (!subMenu.hasVisibleItems()) { + return true; + } + + new MenuPopupHelper(mContext, subMenu).show(); + return true; + } + + public void onCloseSubMenu(SubMenuBuilder menu) { + } + + public void onMenuModeChange(MenuBuilder menu) { + invalidate(); + mContextView.showOverflowMenu(); + } + + public boolean isUiFocusable() { + return mFocusable; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java new file mode 100644 index 0000000000..7d45e81be7 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java @@ -0,0 +1,6 @@ +package com.actionbarsherlock.internal.view; + +public interface View_HasStateListenerSupport { + void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener); + void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java new file mode 100644 index 0000000000..3869d32907 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java @@ -0,0 +1,8 @@ +package com.actionbarsherlock.internal.view; + +import android.view.View; + +public interface View_OnAttachStateChangeListener { + void onViewAttachedToWindow(View v); + void onViewDetachedFromWindow(View v); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java new file mode 100644 index 0000000000..0354ad1ad1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import java.util.ArrayList; +import java.util.List; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.view.KeyEvent; + +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +/** + * @hide + */ +public class ActionMenu implements Menu { + private Context mContext; + + private boolean mIsQwerty; + + private ArrayList mItems; + + public ActionMenu(Context context) { + mContext = context; + mItems = new ArrayList(); + } + + public Context getContext() { + return mContext; + } + + public MenuItem add(CharSequence title) { + return add(0, 0, 0, title); + } + + public MenuItem add(int titleRes) { + return add(0, 0, 0, titleRes); + } + + public MenuItem add(int groupId, int itemId, int order, int titleRes) { + return add(groupId, itemId, order, mContext.getResources().getString(titleRes)); + } + + public MenuItem add(int groupId, int itemId, int order, CharSequence title) { + ActionMenuItem item = new ActionMenuItem(getContext(), + groupId, itemId, 0, order, title); + mItems.add(order, item); + return item; + } + + public int addIntentOptions(int groupId, int itemId, int order, + ComponentName caller, Intent[] specifics, Intent intent, int flags, + MenuItem[] outSpecificItems) { + PackageManager pm = mContext.getPackageManager(); + final List lri = + pm.queryIntentActivityOptions(caller, specifics, intent, 0); + final int N = lri != null ? lri.size() : 0; + + if ((flags & FLAG_APPEND_TO_GROUP) == 0) { + removeGroup(groupId); + } + + for (int i=0; i= 0) { + outSpecificItems[ri.specificIndex] = item; + } + } + + return N; + } + + public SubMenu addSubMenu(CharSequence title) { + // TODO Implement submenus + return null; + } + + public SubMenu addSubMenu(int titleRes) { + // TODO Implement submenus + return null; + } + + public SubMenu addSubMenu(int groupId, int itemId, int order, + CharSequence title) { + // TODO Implement submenus + return null; + } + + public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { + // TODO Implement submenus + return null; + } + + public void clear() { + mItems.clear(); + } + + public void close() { + } + + private int findItemIndex(int id) { + final ArrayList items = mItems; + final int itemCount = items.size(); + for (int i = 0; i < itemCount; i++) { + if (items.get(i).getItemId() == id) { + return i; + } + } + + return -1; + } + + public MenuItem findItem(int id) { + return mItems.get(findItemIndex(id)); + } + + public MenuItem getItem(int index) { + return mItems.get(index); + } + + public boolean hasVisibleItems() { + final ArrayList items = mItems; + final int itemCount = items.size(); + + for (int i = 0; i < itemCount; i++) { + if (items.get(i).isVisible()) { + return true; + } + } + + return false; + } + + private ActionMenuItem findItemWithShortcut(int keyCode, KeyEvent event) { + // TODO Make this smarter. + final boolean qwerty = mIsQwerty; + final ArrayList items = mItems; + final int itemCount = items.size(); + + for (int i = 0; i < itemCount; i++) { + ActionMenuItem item = items.get(i); + final char shortcut = qwerty ? item.getAlphabeticShortcut() : + item.getNumericShortcut(); + if (keyCode == shortcut) { + return item; + } + } + return null; + } + + public boolean isShortcutKey(int keyCode, KeyEvent event) { + return findItemWithShortcut(keyCode, event) != null; + } + + public boolean performIdentifierAction(int id, int flags) { + final int index = findItemIndex(id); + if (index < 0) { + return false; + } + + return mItems.get(index).invoke(); + } + + public boolean performShortcut(int keyCode, KeyEvent event, int flags) { + ActionMenuItem item = findItemWithShortcut(keyCode, event); + if (item == null) { + return false; + } + + return item.invoke(); + } + + public void removeGroup(int groupId) { + final ArrayList items = mItems; + int itemCount = items.size(); + int i = 0; + while (i < itemCount) { + if (items.get(i).getGroupId() == groupId) { + items.remove(i); + itemCount--; + } else { + i++; + } + } + } + + public void removeItem(int id) { + mItems.remove(findItemIndex(id)); + } + + public void setGroupCheckable(int group, boolean checkable, + boolean exclusive) { + final ArrayList items = mItems; + final int itemCount = items.size(); + + for (int i = 0; i < itemCount; i++) { + ActionMenuItem item = items.get(i); + if (item.getGroupId() == group) { + item.setCheckable(checkable); + item.setExclusiveCheckable(exclusive); + } + } + } + + public void setGroupEnabled(int group, boolean enabled) { + final ArrayList items = mItems; + final int itemCount = items.size(); + + for (int i = 0; i < itemCount; i++) { + ActionMenuItem item = items.get(i); + if (item.getGroupId() == group) { + item.setEnabled(enabled); + } + } + } + + public void setGroupVisible(int group, boolean visible) { + final ArrayList items = mItems; + final int itemCount = items.size(); + + for (int i = 0; i < itemCount; i++) { + ActionMenuItem item = items.get(i); + if (item.getGroupId() == group) { + item.setVisible(visible); + } + } + } + + public void setQwertyMode(boolean isQwerty) { + mIsQwerty = isQwerty; + } + + public int size() { + return mItems.size(); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java new file mode 100644 index 0000000000..510b974886 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import android.content.Context; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.View; + +import com.actionbarsherlock.view.ActionProvider; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +/** + * @hide + */ +public class ActionMenuItem implements MenuItem { + private final int mId; + private final int mGroup; + //UNUSED private final int mCategoryOrder; + private final int mOrdering; + + private CharSequence mTitle; + private CharSequence mTitleCondensed; + private Intent mIntent; + private char mShortcutNumericChar; + private char mShortcutAlphabeticChar; + + private Drawable mIconDrawable; + //UNUSED private int mIconResId = NO_ICON; + + private Context mContext; + + private MenuItem.OnMenuItemClickListener mClickListener; + + //UNUSED private static final int NO_ICON = 0; + + private int mFlags = ENABLED; + private static final int CHECKABLE = 0x00000001; + private static final int CHECKED = 0x00000002; + private static final int EXCLUSIVE = 0x00000004; + private static final int HIDDEN = 0x00000008; + private static final int ENABLED = 0x00000010; + + public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering, + CharSequence title) { + mContext = context; + mId = id; + mGroup = group; + //UNUSED mCategoryOrder = categoryOrder; + mOrdering = ordering; + mTitle = title; + } + + public char getAlphabeticShortcut() { + return mShortcutAlphabeticChar; + } + + public int getGroupId() { + return mGroup; + } + + public Drawable getIcon() { + return mIconDrawable; + } + + public Intent getIntent() { + return mIntent; + } + + public int getItemId() { + return mId; + } + + public ContextMenuInfo getMenuInfo() { + return null; + } + + public char getNumericShortcut() { + return mShortcutNumericChar; + } + + public int getOrder() { + return mOrdering; + } + + public SubMenu getSubMenu() { + return null; + } + + public CharSequence getTitle() { + return mTitle; + } + + public CharSequence getTitleCondensed() { + return mTitleCondensed; + } + + public boolean hasSubMenu() { + return false; + } + + public boolean isCheckable() { + return (mFlags & CHECKABLE) != 0; + } + + public boolean isChecked() { + return (mFlags & CHECKED) != 0; + } + + public boolean isEnabled() { + return (mFlags & ENABLED) != 0; + } + + public boolean isVisible() { + return (mFlags & HIDDEN) == 0; + } + + public MenuItem setAlphabeticShortcut(char alphaChar) { + mShortcutAlphabeticChar = alphaChar; + return this; + } + + public MenuItem setCheckable(boolean checkable) { + mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0); + return this; + } + + public ActionMenuItem setExclusiveCheckable(boolean exclusive) { + mFlags = (mFlags & ~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0); + return this; + } + + public MenuItem setChecked(boolean checked) { + mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0); + return this; + } + + public MenuItem setEnabled(boolean enabled) { + mFlags = (mFlags & ~ENABLED) | (enabled ? ENABLED : 0); + return this; + } + + public MenuItem setIcon(Drawable icon) { + mIconDrawable = icon; + //UNUSED mIconResId = NO_ICON; + return this; + } + + public MenuItem setIcon(int iconRes) { + //UNUSED mIconResId = iconRes; + mIconDrawable = mContext.getResources().getDrawable(iconRes); + return this; + } + + public MenuItem setIntent(Intent intent) { + mIntent = intent; + return this; + } + + public MenuItem setNumericShortcut(char numericChar) { + mShortcutNumericChar = numericChar; + return this; + } + + public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { + mClickListener = menuItemClickListener; + return this; + } + + public MenuItem setShortcut(char numericChar, char alphaChar) { + mShortcutNumericChar = numericChar; + mShortcutAlphabeticChar = alphaChar; + return this; + } + + public MenuItem setTitle(CharSequence title) { + mTitle = title; + return this; + } + + public MenuItem setTitle(int title) { + mTitle = mContext.getResources().getString(title); + return this; + } + + public MenuItem setTitleCondensed(CharSequence title) { + mTitleCondensed = title; + return this; + } + + public MenuItem setVisible(boolean visible) { + mFlags = (mFlags & HIDDEN) | (visible ? 0 : HIDDEN); + return this; + } + + public boolean invoke() { + if (mClickListener != null && mClickListener.onMenuItemClick(this)) { + return true; + } + + if (mIntent != null) { + mContext.startActivity(mIntent); + return true; + } + + return false; + } + + public void setShowAsAction(int show) { + // Do nothing. ActionMenuItems always show as action buttons. + } + + public MenuItem setActionView(View actionView) { + throw new UnsupportedOperationException(); + } + + public View getActionView() { + return null; + } + + @Override + public MenuItem setActionView(int resId) { + throw new UnsupportedOperationException(); + } + + @Override + public ActionProvider getActionProvider() { + return null; + } + + @Override + public MenuItem setActionProvider(ActionProvider actionProvider) { + throw new UnsupportedOperationException(); + } + + @Override + public MenuItem setShowAsActionFlags(int actionEnum) { + setShowAsAction(actionEnum); + return this; + } + + @Override + public boolean expandActionView() { + return false; + } + + @Override + public boolean collapseActionView() { + return false; + } + + @Override + public boolean isActionViewExpanded() { + return false; + } + + @Override + public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { + // No need to save the listener; ActionMenuItem does not support collapsing items. + return this; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java new file mode 100644 index 0000000000..dcb50f3621 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import java.util.HashSet; +import java.util.Set; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.view.accessibility.AccessibilityEvent; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.Toast; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; +import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; +import com.actionbarsherlock.internal.widget.CapitalizingButton; + +import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; + +/** + * @hide + */ +public class ActionMenuItemView extends LinearLayout + implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener, + ActionMenuView.ActionMenuChildView, View_HasStateListenerSupport { + //UNUSED private static final String TAG = "ActionMenuItemView"; + + private MenuItemImpl mItemData; + private CharSequence mTitle; + private MenuBuilder.ItemInvoker mItemInvoker; + + private ImageButton mImageButton; + private CapitalizingButton mTextButton; + private boolean mAllowTextWithIcon; + private boolean mExpandedFormat; + private int mMinWidth; + + private final Set mListeners = new HashSet(); + + public ActionMenuItemView(Context context) { + this(context, null); + } + + public ActionMenuItemView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) { + //TODO super(context, attrs, defStyle); + super(context, attrs); + mAllowTextWithIcon = getResources_getBoolean(context, + R.bool.abs__config_allowActionMenuItemTextWithIcon); + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.SherlockActionMenuItemView, 0, 0); + mMinWidth = a.getDimensionPixelSize( + R.styleable.SherlockActionMenuItemView_android_minWidth, 0); + a.recycle(); + } + + @Override + public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { + mListeners.add(listener); + } + + @Override + public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { + mListeners.remove(listener); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + for (View_OnAttachStateChangeListener listener : mListeners) { + listener.onViewAttachedToWindow(this); + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + for (View_OnAttachStateChangeListener listener : mListeners) { + listener.onViewDetachedFromWindow(this); + } + } + + @Override + public void onFinishInflate() { + + mImageButton = (ImageButton) findViewById(R.id.abs__imageButton); + mTextButton = (CapitalizingButton) findViewById(R.id.abs__textButton); + mImageButton.setOnClickListener(this); + mTextButton.setOnClickListener(this); + mImageButton.setOnLongClickListener(this); + setOnClickListener(this); + setOnLongClickListener(this); + } + + public MenuItemImpl getItemData() { + return mItemData; + } + + public void initialize(MenuItemImpl itemData, int menuType) { + mItemData = itemData; + + setIcon(itemData.getIcon()); + setTitle(itemData.getTitleForItemView(this)); // Title only takes effect if there is no icon + setId(itemData.getItemId()); + + setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); + setEnabled(itemData.isEnabled()); + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + mImageButton.setEnabled(enabled); + mTextButton.setEnabled(enabled); + } + + public void onClick(View v) { + if (mItemInvoker != null) { + mItemInvoker.invokeItem(mItemData); + } + } + + public void setItemInvoker(MenuBuilder.ItemInvoker invoker) { + mItemInvoker = invoker; + } + + public boolean prefersCondensedTitle() { + return true; + } + + public void setCheckable(boolean checkable) { + // TODO Support checkable action items + } + + public void setChecked(boolean checked) { + // TODO Support checkable action items + } + + public void setExpandedFormat(boolean expandedFormat) { + if (mExpandedFormat != expandedFormat) { + mExpandedFormat = expandedFormat; + if (mItemData != null) { + mItemData.actionFormatChanged(); + } + } + } + + private void updateTextButtonVisibility() { + boolean visible = !TextUtils.isEmpty(mTextButton.getText()); + visible &= mImageButton.getDrawable() == null || + (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat)); + + mTextButton.setVisibility(visible ? VISIBLE : GONE); + } + + public void setIcon(Drawable icon) { + mImageButton.setImageDrawable(icon); + if (icon != null) { + mImageButton.setVisibility(VISIBLE); + } else { + mImageButton.setVisibility(GONE); + } + + updateTextButtonVisibility(); + } + + public boolean hasText() { + return mTextButton.getVisibility() != GONE; + } + + public void setShortcut(boolean showShortcut, char shortcutKey) { + // Action buttons don't show text for shortcut keys. + } + + public void setTitle(CharSequence title) { + mTitle = title; + + mTextButton.setTextCompat(mTitle); + + setContentDescription(mTitle); + updateTextButtonVisibility(); + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + onPopulateAccessibilityEvent(event); + return true; + } + + @Override + public void onPopulateAccessibilityEvent(AccessibilityEvent event) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + super.onPopulateAccessibilityEvent(event); + } + final CharSequence cdesc = getContentDescription(); + if (!TextUtils.isEmpty(cdesc)) { + event.getText().add(cdesc); + } + } + + @Override + public boolean dispatchHoverEvent(MotionEvent event) { + // Don't allow children to hover; we want this to be treated as a single component. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + return onHoverEvent(event); + } + return false; + } + + public boolean showsIcon() { + return true; + } + + public boolean needsDividerBefore() { + return hasText() && mItemData.getIcon() == null; + } + + public boolean needsDividerAfter() { + return hasText(); + } + + @Override + public boolean onLongClick(View v) { + if (hasText()) { + // Don't show the cheat sheet for items that already show text. + return false; + } + + final int[] screenPos = new int[2]; + final Rect displayFrame = new Rect(); + getLocationOnScreen(screenPos); + getWindowVisibleDisplayFrame(displayFrame); + + final Context context = getContext(); + final int width = getWidth(); + final int height = getHeight(); + final int midy = screenPos[1] + height / 2; + final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; + + Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT); + if (midy < displayFrame.height()) { + // Show along the top; follow action buttons + cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT, + screenWidth - screenPos[0] - width / 2, height); + } else { + // Show along the bottom center + cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); + } + cheatSheet.show(); + return true; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final int specSize = MeasureSpec.getSize(widthMeasureSpec); + final int oldMeasuredWidth = getMeasuredWidth(); + final int targetWidth = widthMode == MeasureSpec.AT_MOST ? Math.min(specSize, mMinWidth) + : mMinWidth; + + if (widthMode != MeasureSpec.EXACTLY && mMinWidth > 0 && oldMeasuredWidth < targetWidth) { + // Remeasure at exactly the minimum width. + super.onMeasure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), + heightMeasureSpec); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java new file mode 100644 index 0000000000..876a22c589 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java @@ -0,0 +1,714 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.SparseBooleanArray; +import android.view.SoundEffectConstants; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.widget.ImageButton; +import com.actionbarsherlock.R; +import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; +import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; +import com.actionbarsherlock.internal.view.menu.ActionMenuView.ActionMenuChildView; +import com.actionbarsherlock.view.ActionProvider; +import com.actionbarsherlock.view.MenuItem; + +/** + * MenuPresenter for building action menus as seen in the action bar and action modes. + */ +public class ActionMenuPresenter extends BaseMenuPresenter + implements ActionProvider.SubUiVisibilityListener { + //UNUSED private static final String TAG = "ActionMenuPresenter"; + + private View mOverflowButton; + private boolean mReserveOverflow; + private boolean mReserveOverflowSet; + private int mWidthLimit; + private int mActionItemWidthLimit; + private int mMaxItems; + private boolean mMaxItemsSet; + private boolean mStrictWidthLimit; + private boolean mWidthLimitSet; + private boolean mExpandedActionViewsExclusive; + + private int mMinCellSize; + + // Group IDs that have been added as actions - used temporarily, allocated here for reuse. + private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); + + private View mScrapActionButtonView; + + private OverflowPopup mOverflowPopup; + private ActionButtonSubmenu mActionButtonPopup; + + private OpenOverflowRunnable mPostedOpenRunnable; + + final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); + int mOpenSubMenuId; + + public ActionMenuPresenter(Context context) { + super(context, R.layout.abs__action_menu_layout, + R.layout.abs__action_menu_item_layout); + } + + @Override + public void initForMenu(Context context, MenuBuilder menu) { + super.initForMenu(context, menu); + + final Resources res = context.getResources(); + + if (!mReserveOverflowSet) { + mReserveOverflow = reserveOverflow(mContext); + } + + if (!mWidthLimitSet) { + mWidthLimit = res.getDisplayMetrics().widthPixels / 2; + } + + // Measure for initial configuration + if (!mMaxItemsSet) { + mMaxItems = getResources_getInteger(context, R.integer.abs__max_action_buttons); + } + + int width = mWidthLimit; + if (mReserveOverflow) { + if (mOverflowButton == null) { + mOverflowButton = new OverflowMenuButton(mSystemContext); + final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + mOverflowButton.measure(spec, spec); + } + width -= mOverflowButton.getMeasuredWidth(); + } else { + mOverflowButton = null; + } + + mActionItemWidthLimit = width; + + mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density); + + // Drop a scrap view as it may no longer reflect the proper context/config. + mScrapActionButtonView = null; + } + + public static boolean reserveOverflow(Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB); + } else { + return !HasPermanentMenuKey.get(context); + } + } + + private static class HasPermanentMenuKey { + public static boolean get(Context context) { + return ViewConfiguration.get(context).hasPermanentMenuKey(); + } + } + + public void onConfigurationChanged(Configuration newConfig) { + if (!mMaxItemsSet) { + mMaxItems = getResources_getInteger(mContext, + R.integer.abs__max_action_buttons); + if (mMenu != null) { + mMenu.onItemsChanged(true); + } + } + } + + public void setWidthLimit(int width, boolean strict) { + mWidthLimit = width; + mStrictWidthLimit = strict; + mWidthLimitSet = true; + } + + public void setReserveOverflow(boolean reserveOverflow) { + mReserveOverflow = reserveOverflow; + mReserveOverflowSet = true; + } + + public void setItemLimit(int itemCount) { + mMaxItems = itemCount; + mMaxItemsSet = true; + } + + public void setExpandedActionViewsExclusive(boolean isExclusive) { + mExpandedActionViewsExclusive = isExclusive; + } + + @Override + public MenuView getMenuView(ViewGroup root) { + MenuView result = super.getMenuView(root); + ((ActionMenuView) result).setPresenter(this); + return result; + } + + @Override + public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { + View actionView = item.getActionView(); + if (actionView == null || item.hasCollapsibleActionView()) { + if (!(convertView instanceof ActionMenuItemView)) { + convertView = null; + } + actionView = super.getItemView(item, convertView, parent); + } + actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); + + final ActionMenuView menuParent = (ActionMenuView) parent; + final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); + if (!menuParent.checkLayoutParams(lp)) { + actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); + } + return actionView; + } + + @Override + public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { + itemView.initialize(item, 0); + + final ActionMenuView menuView = (ActionMenuView) mMenuView; + ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; + actionItemView.setItemInvoker(menuView); + } + + @Override + public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { + return item.isActionButton(); + } + + @Override + public void updateMenuView(boolean cleared) { + super.updateMenuView(cleared); + + if (mMenu != null) { + final ArrayList actionItems = mMenu.getActionItems(); + final int count = actionItems.size(); + for (int i = 0; i < count; i++) { + final ActionProvider provider = actionItems.get(i).getActionProvider(); + if (provider != null) { + provider.setSubUiVisibilityListener(this); + } + } + } + + final ArrayList nonActionItems = mMenu != null ? + mMenu.getNonActionItems() : null; + + boolean hasOverflow = false; + if (mReserveOverflow && nonActionItems != null) { + final int count = nonActionItems.size(); + if (count == 1) { + hasOverflow = !nonActionItems.get(0).isActionViewExpanded(); + } else { + hasOverflow = count > 0; + } + } + + if (hasOverflow) { + if (mOverflowButton == null) { + mOverflowButton = new OverflowMenuButton(mSystemContext); + } + ViewGroup parent = (ViewGroup) mOverflowButton.getParent(); + if (parent != mMenuView) { + if (parent != null) { + parent.removeView(mOverflowButton); + } + ActionMenuView menuView = (ActionMenuView) mMenuView; + menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams()); + } + } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) { + ((ViewGroup) mMenuView).removeView(mOverflowButton); + } + + ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow); + } + + @Override + public boolean filterLeftoverView(ViewGroup parent, int childIndex) { + if (parent.getChildAt(childIndex) == mOverflowButton) return false; + return super.filterLeftoverView(parent, childIndex); + } + + public boolean onSubMenuSelected(SubMenuBuilder subMenu) { + if (!subMenu.hasVisibleItems()) return false; + + SubMenuBuilder topSubMenu = subMenu; + while (topSubMenu.getParentMenu() != mMenu) { + topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu(); + } + View anchor = findViewForItem(topSubMenu.getItem()); + if (anchor == null) { + if (mOverflowButton == null) return false; + anchor = mOverflowButton; + } + + mOpenSubMenuId = subMenu.getItem().getItemId(); + mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); + mActionButtonPopup.setAnchorView(anchor); + mActionButtonPopup.show(); + super.onSubMenuSelected(subMenu); + return true; + } + + private View findViewForItem(MenuItem item) { + final ViewGroup parent = (ViewGroup) mMenuView; + if (parent == null) return null; + + final int count = parent.getChildCount(); + for (int i = 0; i < count; i++) { + final View child = parent.getChildAt(i); + if (child instanceof MenuView.ItemView && + ((MenuView.ItemView) child).getItemData() == item) { + return child; + } + } + return null; + } + + /** + * Display the overflow menu if one is present. + * @return true if the overflow menu was shown, false otherwise. + */ + public boolean showOverflowMenu() { + if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null && + mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) { + OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true); + mPostedOpenRunnable = new OpenOverflowRunnable(popup); + // Post this for later; we might still need a layout for the anchor to be right. + ((View) mMenuView).post(mPostedOpenRunnable); + + // ActionMenuPresenter uses null as a callback argument here + // to indicate overflow is opening. + super.onSubMenuSelected(null); + + return true; + } + return false; + } + + /** + * Hide the overflow menu if it is currently showing. + * + * @return true if the overflow menu was hidden, false otherwise. + */ + public boolean hideOverflowMenu() { + if (mPostedOpenRunnable != null && mMenuView != null) { + ((View) mMenuView).removeCallbacks(mPostedOpenRunnable); + mPostedOpenRunnable = null; + return true; + } + + MenuPopupHelper popup = mOverflowPopup; + if (popup != null) { + popup.dismiss(); + return true; + } + return false; + } + + /** + * Dismiss all popup menus - overflow and submenus. + * @return true if popups were dismissed, false otherwise. (This can be because none were open.) + */ + public boolean dismissPopupMenus() { + boolean result = hideOverflowMenu(); + result |= hideSubMenus(); + return result; + } + + /** + * Dismiss all submenu popups. + * + * @return true if popups were dismissed, false otherwise. (This can be because none were open.) + */ + public boolean hideSubMenus() { + if (mActionButtonPopup != null) { + mActionButtonPopup.dismiss(); + return true; + } + return false; + } + + /** + * @return true if the overflow menu is currently showing + */ + public boolean isOverflowMenuShowing() { + return mOverflowPopup != null && mOverflowPopup.isShowing(); + } + + /** + * @return true if space has been reserved in the action menu for an overflow item. + */ + public boolean isOverflowReserved() { + return mReserveOverflow; + } + + public boolean flagActionItems() { + final ArrayList visibleItems = mMenu.getVisibleItems(); + final int itemsSize = visibleItems.size(); + int maxActions = mMaxItems; + int widthLimit = mActionItemWidthLimit; + final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final ViewGroup parent = (ViewGroup) mMenuView; + + int requiredItems = 0; + int requestedItems = 0; + int firstActionWidth = 0; + boolean hasOverflow = false; + for (int i = 0; i < itemsSize; i++) { + MenuItemImpl item = visibleItems.get(i); + if (item.requiresActionButton()) { + requiredItems++; + } else if (item.requestsActionButton()) { + requestedItems++; + } else { + hasOverflow = true; + } + if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) { + // Overflow everything if we have an expanded action view and we're + // space constrained. + maxActions = 0; + } + } + + // Reserve a spot for the overflow item if needed. + if (mReserveOverflow && + (hasOverflow || requiredItems + requestedItems > maxActions)) { + maxActions--; + } + maxActions -= requiredItems; + + final SparseBooleanArray seenGroups = mActionButtonGroups; + seenGroups.clear(); + + int cellSize = 0; + int cellsRemaining = 0; + if (mStrictWidthLimit) { + cellsRemaining = widthLimit / mMinCellSize; + final int cellSizeRemaining = widthLimit % mMinCellSize; + cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining; + } + + // Flag as many more requested items as will fit. + for (int i = 0; i < itemsSize; i++) { + MenuItemImpl item = visibleItems.get(i); + + if (item.requiresActionButton()) { + View v = getItemView(item, mScrapActionButtonView, parent); + if (mScrapActionButtonView == null) { + mScrapActionButtonView = v; + } + if (mStrictWidthLimit) { + cellsRemaining -= ActionMenuView.measureChildForCells(v, + cellSize, cellsRemaining, querySpec, 0); + } else { + v.measure(querySpec, querySpec); + } + final int measuredWidth = v.getMeasuredWidth(); + widthLimit -= measuredWidth; + if (firstActionWidth == 0) { + firstActionWidth = measuredWidth; + } + final int groupId = item.getGroupId(); + if (groupId != 0) { + seenGroups.put(groupId, true); + } + item.setIsActionButton(true); + } else if (item.requestsActionButton()) { + // Items in a group with other items that already have an action slot + // can break the max actions rule, but not the width limit. + final int groupId = item.getGroupId(); + final boolean inGroup = seenGroups.get(groupId); + boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 && + (!mStrictWidthLimit || cellsRemaining > 0); + + if (isAction) { + View v = getItemView(item, mScrapActionButtonView, parent); + if (mScrapActionButtonView == null) { + mScrapActionButtonView = v; + } + if (mStrictWidthLimit) { + final int cells = ActionMenuView.measureChildForCells(v, + cellSize, cellsRemaining, querySpec, 0); + cellsRemaining -= cells; + if (cells == 0) { + isAction = false; + } + } else { + v.measure(querySpec, querySpec); + } + final int measuredWidth = v.getMeasuredWidth(); + widthLimit -= measuredWidth; + if (firstActionWidth == 0) { + firstActionWidth = measuredWidth; + } + + if (mStrictWidthLimit) { + isAction &= widthLimit >= 0; + } else { + // Did this push the entire first item past the limit? + isAction &= widthLimit + firstActionWidth > 0; + } + } + + if (isAction && groupId != 0) { + seenGroups.put(groupId, true); + } else if (inGroup) { + // We broke the width limit. Demote the whole group, they all overflow now. + seenGroups.put(groupId, false); + for (int j = 0; j < i; j++) { + MenuItemImpl areYouMyGroupie = visibleItems.get(j); + if (areYouMyGroupie.getGroupId() == groupId) { + // Give back the action slot + if (areYouMyGroupie.isActionButton()) maxActions++; + areYouMyGroupie.setIsActionButton(false); + } + } + } + + if (isAction) maxActions--; + + item.setIsActionButton(isAction); + } + } + return true; + } + + @Override + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + dismissPopupMenus(); + super.onCloseMenu(menu, allMenusAreClosing); + } + + @Override + public Parcelable onSaveInstanceState() { + SavedState state = new SavedState(); + state.openSubMenuId = mOpenSubMenuId; + return state; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState saved = (SavedState) state; + if (saved.openSubMenuId > 0) { + MenuItem item = mMenu.findItem(saved.openSubMenuId); + if (item != null) { + SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); + onSubMenuSelected(subMenu); + } + } + } + + @Override + public void onSubUiVisibilityChanged(boolean isVisible) { + if (isVisible) { + // Not a submenu, but treat it like one. + super.onSubMenuSelected(null); + } else { + mMenu.close(false); + } + } + + private static class SavedState implements Parcelable { + public int openSubMenuId; + + SavedState() { + } + + SavedState(Parcel in) { + openSubMenuId = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(openSubMenuId); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + private class OverflowMenuButton extends ImageButton implements ActionMenuChildView, View_HasStateListenerSupport { + private final Set mListeners = new HashSet(); + + public OverflowMenuButton(Context context) { + super(context, null, R.attr.actionOverflowButtonStyle); + + setClickable(true); + setFocusable(true); + setVisibility(VISIBLE); + setEnabled(true); + } + + @Override + public boolean performClick() { + if (super.performClick()) { + return true; + } + + playSoundEffect(SoundEffectConstants.CLICK); + showOverflowMenu(); + return true; + } + + public boolean needsDividerBefore() { + return false; + } + + public boolean needsDividerAfter() { + return false; + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + for (View_OnAttachStateChangeListener listener : mListeners) { + listener.onViewAttachedToWindow(this); + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + for (View_OnAttachStateChangeListener listener : mListeners) { + listener.onViewDetachedFromWindow(this); + } + + if (mOverflowPopup != null) mOverflowPopup.dismiss(); + } + + @Override + public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { + mListeners.add(listener); + } + + @Override + public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { + mListeners.remove(listener); + } + } + + private class OverflowPopup extends MenuPopupHelper { + public OverflowPopup(Context context, MenuBuilder menu, View anchorView, + boolean overflowOnly) { + super(context, menu, anchorView, overflowOnly); + setCallback(mPopupPresenterCallback); + } + + @Override + public void onDismiss() { + super.onDismiss(); + mMenu.close(); + mOverflowPopup = null; + } + } + + private class ActionButtonSubmenu extends MenuPopupHelper { + //UNUSED private SubMenuBuilder mSubMenu; + + public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { + super(context, subMenu); + //UNUSED mSubMenu = subMenu; + + MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); + if (!item.isActionButton()) { + // Give a reasonable anchor to nested submenus. + setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton); + } + + setCallback(mPopupPresenterCallback); + + boolean preserveIconSpacing = false; + final int count = subMenu.size(); + for (int i = 0; i < count; i++) { + MenuItem childItem = subMenu.getItem(i); + if (childItem.isVisible() && childItem.getIcon() != null) { + preserveIconSpacing = true; + break; + } + } + setForceShowIcon(preserveIconSpacing); + } + + @Override + public void onDismiss() { + super.onDismiss(); + mActionButtonPopup = null; + mOpenSubMenuId = 0; + } + } + + private class PopupPresenterCallback implements MenuPresenter.Callback { + + @Override + public boolean onOpenSubMenu(MenuBuilder subMenu) { + if (subMenu == null) return false; + + mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); + return false; + } + + @Override + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + if (menu instanceof SubMenuBuilder) { + ((SubMenuBuilder) menu).getRootMenu().close(false); + } + } + } + + private class OpenOverflowRunnable implements Runnable { + private OverflowPopup mPopup; + + public OpenOverflowRunnable(OverflowPopup popup) { + mPopup = popup; + } + + public void run() { + mMenu.changeMenuMode(); + final View menuView = (View) mMenuView; + if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) { + mOverflowPopup = mPopup; + } + mPostedOpenRunnable = null; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java new file mode 100644 index 0000000000..0e3b1ae0d7 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.actionbarsherlock.internal.view.menu; + +import android.content.Context; +import android.content.res.Configuration; +import android.graphics.Canvas; +import android.os.Build; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; +import android.widget.LinearLayout; +import com.actionbarsherlock.internal.widget.IcsLinearLayout; + +/** + * @hide + */ +public class ActionMenuView extends IcsLinearLayout implements MenuBuilder.ItemInvoker, MenuView { + //UNUSED private static final String TAG = "ActionMenuView"; + private static final boolean IS_FROYO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; + + static final int MIN_CELL_SIZE = 56; // dips + static final int GENERATED_ITEM_PADDING = 4; // dips + + private MenuBuilder mMenu; + + private boolean mReserveOverflow; + private ActionMenuPresenter mPresenter; + private boolean mFormatItems; + private int mFormatItemsWidth; + private int mMinCellSize; + private int mGeneratedItemPadding; + //UNUSED private int mMeasuredExtraWidth; + + private boolean mFirst = true; + + public ActionMenuView(Context context) { + this(context, null); + } + + public ActionMenuView(Context context, AttributeSet attrs) { + super(context, attrs); + setBaselineAligned(false); + final float density = context.getResources().getDisplayMetrics().density; + mMinCellSize = (int) (MIN_CELL_SIZE * density); + mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density); + } + + public void setPresenter(ActionMenuPresenter presenter) { + mPresenter = presenter; + } + + public boolean isExpandedFormat() { + return mFormatItems; + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + if (IS_FROYO) { + super.onConfigurationChanged(newConfig); + } + mPresenter.updateMenuView(false); + + if (mPresenter != null && mPresenter.isOverflowMenuShowing()) { + mPresenter.hideOverflowMenu(); + mPresenter.showOverflowMenu(); + } + } + + @Override + protected void onDraw(Canvas canvas) { + //Need to trigger a relayout since we may have been added extremely + //late in the initial rendering (e.g., when contained in a ViewPager). + //See: https://github.com/JakeWharton/ActionBarSherlock/issues/272 + if (!IS_FROYO && mFirst) { + mFirst = false; + requestLayout(); + return; + } + super.onDraw(canvas); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // If we've been given an exact size to match, apply special formatting during layout. + final boolean wasFormatted = mFormatItems; + mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; + + if (wasFormatted != mFormatItems) { + mFormatItemsWidth = 0; // Reset this when switching modes + } + + // Special formatting can change whether items can fit as action buttons. + // Kick the menu and update presenters when this changes. + final int widthSize = MeasureSpec.getMode(widthMeasureSpec); + if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) { + mFormatItemsWidth = widthSize; + mMenu.onItemsChanged(true); + } + + if (mFormatItems) { + onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec); + } else { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + + private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) { + // We already know the width mode is EXACTLY if we're here. + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + final int widthPadding = getPaddingLeft() + getPaddingRight(); + final int heightPadding = getPaddingTop() + getPaddingBottom(); + + widthSize -= widthPadding; + + // Divide the view into cells. + final int cellCount = widthSize / mMinCellSize; + final int cellSizeRemaining = widthSize % mMinCellSize; + + if (cellCount == 0) { + // Give up, nothing fits. + setMeasuredDimension(widthSize, 0); + return; + } + + final int cellSize = mMinCellSize + cellSizeRemaining / cellCount; + + int cellsRemaining = cellCount; + int maxChildHeight = 0; + int maxCellsUsed = 0; + int expandableItemCount = 0; + int visibleItemCount = 0; + boolean hasOverflow = false; + + // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64. + long smallestItemsAt = 0; + + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + if (child.getVisibility() == GONE) continue; + + final boolean isGeneratedItem = child instanceof ActionMenuItemView; + visibleItemCount++; + + if (isGeneratedItem) { + // Reset padding for generated menu item views; it may change below + // and views are recycled. + child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0); + } + + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + lp.expanded = false; + lp.extraPixels = 0; + lp.cellsUsed = 0; + lp.expandable = false; + lp.leftMargin = 0; + lp.rightMargin = 0; + lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText(); + + // Overflow always gets 1 cell. No more, no less. + final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining; + + final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable, + heightMeasureSpec, heightPadding); + + maxCellsUsed = Math.max(maxCellsUsed, cellsUsed); + if (lp.expandable) expandableItemCount++; + if (lp.isOverflowButton) hasOverflow = true; + + cellsRemaining -= cellsUsed; + maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight()); + if (cellsUsed == 1) smallestItemsAt |= (1 << i); + } + + // When we have overflow and a single expanded (text) item, we want to try centering it + // visually in the available space even though overflow consumes some of it. + final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2; + + // Divide space for remaining cells if we have items that can expand. + // Try distributing whole leftover cells to smaller items first. + + boolean needsExpansion = false; + while (expandableItemCount > 0 && cellsRemaining > 0) { + int minCells = Integer.MAX_VALUE; + long minCellsAt = 0; // Bit locations are indices of relevant child views + int minCellsItemCount = 0; + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + + // Don't try to expand items that shouldn't. + if (!lp.expandable) continue; + + // Mark indices of children that can receive an extra cell. + if (lp.cellsUsed < minCells) { + minCells = lp.cellsUsed; + minCellsAt = 1 << i; + minCellsItemCount = 1; + } else if (lp.cellsUsed == minCells) { + minCellsAt |= 1 << i; + minCellsItemCount++; + } + } + + // Items that get expanded will always be in the set of smallest items when we're done. + smallestItemsAt |= minCellsAt; + + if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop. + + // We have enough cells, all minimum size items will be incremented. + minCells++; + + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + if ((minCellsAt & (1 << i)) == 0) { + // If this item is already at our small item count, mark it for later. + if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i; + continue; + } + + if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) { + // Add padding to this item such that it centers. + child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0); + } + lp.cellsUsed++; + lp.expanded = true; + cellsRemaining--; + } + + needsExpansion = true; + } + + // Divide any space left that wouldn't divide along cell boundaries + // evenly among the smallest items + + final boolean singleItem = !hasOverflow && visibleItemCount == 1; + if (cellsRemaining > 0 && smallestItemsAt != 0 && + (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) { + float expandCount = Long.bitCount(smallestItemsAt); + + if (!singleItem) { + // The items at the far edges may only expand by half in order to pin to either side. + if ((smallestItemsAt & 1) != 0) { + LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams(); + if (!lp.preventEdgeOffset) expandCount -= 0.5f; + } + if ((smallestItemsAt & (1 << (childCount - 1))) != 0) { + LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams()); + if (!lp.preventEdgeOffset) expandCount -= 0.5f; + } + } + + final int extraPixels = expandCount > 0 ? + (int) (cellsRemaining * cellSize / expandCount) : 0; + + for (int i = 0; i < childCount; i++) { + if ((smallestItemsAt & (1 << i)) == 0) continue; + + final View child = getChildAt(i); + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + if (child instanceof ActionMenuItemView) { + // If this is one of our views, expand and measure at the larger size. + lp.extraPixels = extraPixels; + lp.expanded = true; + if (i == 0 && !lp.preventEdgeOffset) { + // First item gets part of its new padding pushed out of sight. + // The last item will get this implicitly from layout. + lp.leftMargin = -extraPixels / 2; + } + needsExpansion = true; + } else if (lp.isOverflowButton) { + lp.extraPixels = extraPixels; + lp.expanded = true; + lp.rightMargin = -extraPixels / 2; + needsExpansion = true; + } else { + // If we don't know what it is, give it some margins instead + // and let it center within its space. We still want to pin + // against the edges. + if (i != 0) { + lp.leftMargin = extraPixels / 2; + } + if (i != childCount - 1) { + lp.rightMargin = extraPixels / 2; + } + } + } + + cellsRemaining = 0; + } + + // Remeasure any items that have had extra space allocated to them. + if (needsExpansion) { + int heightSpec = MeasureSpec.makeMeasureSpec(heightSize - heightPadding, heightMode); + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + + if (!lp.expanded) continue; + + final int width = lp.cellsUsed * cellSize + lp.extraPixels; + child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec); + } + } + + if (heightMode != MeasureSpec.EXACTLY) { + heightSize = maxChildHeight; + } + + setMeasuredDimension(widthSize, heightSize); + //UNUSED mMeasuredExtraWidth = cellsRemaining * cellSize; + } + + /** + * Measure a child view to fit within cell-based formatting. The child's width + * will be measured to a whole multiple of cellSize. + * + *

Sets the expandable and cellsUsed fields of LayoutParams. + * + * @param child Child to measure + * @param cellSize Size of one cell + * @param cellsRemaining Number of cells remaining that this view can expand to fill + * @param parentHeightMeasureSpec MeasureSpec used by the parent view + * @param parentHeightPadding Padding present in the parent view + * @return Number of cells this child was measured to occupy + */ + static int measureChildForCells(View child, int cellSize, int cellsRemaining, + int parentHeightMeasureSpec, int parentHeightPadding) { + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + + final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) - + parentHeightPadding; + final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec); + final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode); + + int cellsUsed = 0; + if (cellsRemaining > 0) { + final int childWidthSpec = MeasureSpec.makeMeasureSpec( + cellSize * cellsRemaining, MeasureSpec.AT_MOST); + child.measure(childWidthSpec, childHeightSpec); + + final int measuredWidth = child.getMeasuredWidth(); + cellsUsed = measuredWidth / cellSize; + if (measuredWidth % cellSize != 0) cellsUsed++; + } + + final ActionMenuItemView itemView = child instanceof ActionMenuItemView ? + (ActionMenuItemView) child : null; + final boolean expandable = !lp.isOverflowButton && itemView != null && itemView.hasText(); + lp.expandable = expandable; + + lp.cellsUsed = cellsUsed; + final int targetWidth = cellsUsed * cellSize; + child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), + childHeightSpec); + return cellsUsed; + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (!mFormatItems) { + super.onLayout(changed, left, top, right, bottom); + return; + } + + final int childCount = getChildCount(); + final int midVertical = (top + bottom) / 2; + final int dividerWidth = 0;//getDividerWidth(); + int overflowWidth = 0; + //UNUSED int nonOverflowWidth = 0; + int nonOverflowCount = 0; + int widthRemaining = right - left - getPaddingRight() - getPaddingLeft(); + boolean hasOverflow = false; + for (int i = 0; i < childCount; i++) { + final View v = getChildAt(i); + if (v.getVisibility() == GONE) { + continue; + } + + LayoutParams p = (LayoutParams) v.getLayoutParams(); + if (p.isOverflowButton) { + overflowWidth = v.getMeasuredWidth(); + if (hasDividerBeforeChildAt(i)) { + overflowWidth += dividerWidth; + } + + int height = v.getMeasuredHeight(); + int r = getWidth() - getPaddingRight() - p.rightMargin; + int l = r - overflowWidth; + int t = midVertical - (height / 2); + int b = t + height; + v.layout(l, t, r, b); + + widthRemaining -= overflowWidth; + hasOverflow = true; + } else { + final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin; + //UNUSED nonOverflowWidth += size; + widthRemaining -= size; + //if (hasDividerBeforeChildAt(i)) { + //UNUSED nonOverflowWidth += dividerWidth; + //} + nonOverflowCount++; + } + } + + if (childCount == 1 && !hasOverflow) { + // Center a single child + final View v = getChildAt(0); + final int width = v.getMeasuredWidth(); + final int height = v.getMeasuredHeight(); + final int midHorizontal = (right - left) / 2; + final int l = midHorizontal - width / 2; + final int t = midVertical - height / 2; + v.layout(l, t, l + width, t + height); + return; + } + + final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1); + final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0); + + int startLeft = getPaddingLeft(); + for (int i = 0; i < childCount; i++) { + final View v = getChildAt(i); + final LayoutParams lp = (LayoutParams) v.getLayoutParams(); + if (v.getVisibility() == GONE || lp.isOverflowButton) { + continue; + } + + startLeft += lp.leftMargin; + int width = v.getMeasuredWidth(); + int height = v.getMeasuredHeight(); + int t = midVertical - height / 2; + v.layout(startLeft, t, startLeft + width, t + height); + startLeft += width + lp.rightMargin + spacerSize; + } + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mPresenter.dismissPopupMenus(); + } + + public boolean isOverflowReserved() { + return mReserveOverflow; + } + + public void setOverflowReserved(boolean reserveOverflow) { + mReserveOverflow = reserveOverflow; + } + + @Override + protected LayoutParams generateDefaultLayoutParams() { + LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT); + params.gravity = Gravity.CENTER_VERTICAL; + return params; + } + + @Override + public LayoutParams generateLayoutParams(AttributeSet attrs) { + return new LayoutParams(getContext(), attrs); + } + + @Override + protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { + if (p instanceof LayoutParams) { + LayoutParams result = new LayoutParams((LayoutParams) p); + if (result.gravity <= Gravity.NO_GRAVITY) { + result.gravity = Gravity.CENTER_VERTICAL; + } + return result; + } + return generateDefaultLayoutParams(); + } + + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p != null && p instanceof LayoutParams; + } + + public LayoutParams generateOverflowButtonLayoutParams() { + LayoutParams result = generateDefaultLayoutParams(); + result.isOverflowButton = true; + return result; + } + + public boolean invokeItem(MenuItemImpl item) { + return mMenu.performItemAction(item, 0); + } + + public int getWindowAnimations() { + return 0; + } + + public void initialize(MenuBuilder menu) { + mMenu = menu; + } + + //@Override + protected boolean hasDividerBeforeChildAt(int childIndex) { + if (childIndex == 0) { + return false; + } + final View childBefore = getChildAt(childIndex - 1); + final View child = getChildAt(childIndex); + boolean result = false; + if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) { + result |= ((ActionMenuChildView) childBefore).needsDividerAfter(); + } + if (childIndex > 0 && child instanceof ActionMenuChildView) { + result |= ((ActionMenuChildView) child).needsDividerBefore(); + } + return result; + } + + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + return false; + } + + public interface ActionMenuChildView { + public boolean needsDividerBefore(); + public boolean needsDividerAfter(); + } + + public static class LayoutParams extends LinearLayout.LayoutParams { + public boolean isOverflowButton; + public int cellsUsed; + public int extraPixels; + public boolean expandable; + public boolean preventEdgeOffset; + + public boolean expanded; + + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + } + + public LayoutParams(LayoutParams other) { + super((LinearLayout.LayoutParams) other); + isOverflowButton = other.isOverflowButton; + } + + public LayoutParams(int width, int height) { + super(width, height); + isOverflowButton = false; + } + + public LayoutParams(int width, int height, boolean isOverflowButton) { + super(width, height); + this.isOverflowButton = isOverflowButton; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java new file mode 100644 index 0000000000..6da26f2ae7 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import java.util.ArrayList; +import android.content.Context; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * Base class for MenuPresenters that have a consistent container view and item + * views. Behaves similarly to an AdapterView in that existing item views will + * be reused if possible when items change. + */ +public abstract class BaseMenuPresenter implements MenuPresenter { + private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; + + protected Context mSystemContext; + protected Context mContext; + protected MenuBuilder mMenu; + protected LayoutInflater mSystemInflater; + protected LayoutInflater mInflater; + private Callback mCallback; + + private int mMenuLayoutRes; + private int mItemLayoutRes; + + protected MenuView mMenuView; + + private int mId; + + /** + * Construct a new BaseMenuPresenter. + * + * @param context Context for generating system-supplied views + * @param menuLayoutRes Layout resource ID for the menu container view + * @param itemLayoutRes Layout resource ID for a single item view + */ + public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) { + mSystemContext = context; + mSystemInflater = LayoutInflater.from(context); + mMenuLayoutRes = menuLayoutRes; + mItemLayoutRes = itemLayoutRes; + } + + @Override + public void initForMenu(Context context, MenuBuilder menu) { + mContext = context; + mInflater = LayoutInflater.from(mContext); + mMenu = menu; + } + + @Override + public MenuView getMenuView(ViewGroup root) { + if (mMenuView == null) { + mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false); + mMenuView.initialize(mMenu); + updateMenuView(true); + } + + return mMenuView; + } + + /** + * Reuses item views when it can + */ + public void updateMenuView(boolean cleared) { + final ViewGroup parent = (ViewGroup) mMenuView; + if (parent == null) return; + + int childIndex = 0; + if (mMenu != null) { + mMenu.flagActionItems(); + ArrayList visibleItems = mMenu.getVisibleItems(); + final int itemCount = visibleItems.size(); + for (int i = 0; i < itemCount; i++) { + MenuItemImpl item = visibleItems.get(i); + if (shouldIncludeItem(childIndex, item)) { + final View convertView = parent.getChildAt(childIndex); + final MenuItemImpl oldItem = convertView instanceof MenuView.ItemView ? + ((MenuView.ItemView) convertView).getItemData() : null; + final View itemView = getItemView(item, convertView, parent); + if (item != oldItem) { + // Don't let old states linger with new data. + itemView.setPressed(false); + if (IS_HONEYCOMB) itemView.jumpDrawablesToCurrentState(); + } + if (itemView != convertView) { + addItemView(itemView, childIndex); + } + childIndex++; + } + } + } + + // Remove leftover views. + while (childIndex < parent.getChildCount()) { + if (!filterLeftoverView(parent, childIndex)) { + childIndex++; + } + } + } + + /** + * Add an item view at the given index. + * + * @param itemView View to add + * @param childIndex Index within the parent to insert at + */ + protected void addItemView(View itemView, int childIndex) { + final ViewGroup currentParent = (ViewGroup) itemView.getParent(); + if (currentParent != null) { + currentParent.removeView(itemView); + } + ((ViewGroup) mMenuView).addView(itemView, childIndex); + } + + /** + * Filter the child view at index and remove it if appropriate. + * @param parent Parent to filter from + * @param childIndex Index to filter + * @return true if the child view at index was removed + */ + protected boolean filterLeftoverView(ViewGroup parent, int childIndex) { + parent.removeViewAt(childIndex); + return true; + } + + public void setCallback(Callback cb) { + mCallback = cb; + } + + /** + * Create a new item view that can be re-bound to other item data later. + * + * @return The new item view + */ + public MenuView.ItemView createItemView(ViewGroup parent) { + return (MenuView.ItemView) mSystemInflater.inflate(mItemLayoutRes, parent, false); + } + + /** + * Prepare an item view for use. See AdapterView for the basic idea at work here. + * This may require creating a new item view, but well-behaved implementations will + * re-use the view passed as convertView if present. The returned view will be populated + * with data from the item parameter. + * + * @param item Item to present + * @param convertView Existing view to reuse + * @param parent Intended parent view - use for inflation. + * @return View that presents the requested menu item + */ + public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { + MenuView.ItemView itemView; + if (convertView instanceof MenuView.ItemView) { + itemView = (MenuView.ItemView) convertView; + } else { + itemView = createItemView(parent); + } + bindItemView(item, itemView); + return (View) itemView; + } + + /** + * Bind item data to an existing item view. + * + * @param item Item to bind + * @param itemView View to populate with item data + */ + public abstract void bindItemView(MenuItemImpl item, MenuView.ItemView itemView); + + /** + * Filter item by child index and item data. + * + * @param childIndex Indended presentation index of this item + * @param item Item to present + * @return true if this item should be included in this menu presentation; false otherwise + */ + public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { + return true; + } + + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + if (mCallback != null) { + mCallback.onCloseMenu(menu, allMenusAreClosing); + } + } + + public boolean onSubMenuSelected(SubMenuBuilder menu) { + if (mCallback != null) { + return mCallback.onOpenSubMenu(menu); + } + return false; + } + + public boolean flagActionItems() { + return false; + } + + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + + public int getId() { + return mId; + } + + public void setId(int id) { + mId = id; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java new file mode 100644 index 0000000000..ac25c37369 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import com.actionbarsherlock.R; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.TextView; + +/** + * The item view for each item in the ListView-based MenuViews. + */ +public class ListMenuItemView extends LinearLayout implements MenuView.ItemView { + private MenuItemImpl mItemData; + + private ImageView mIconView; + private RadioButton mRadioButton; + private TextView mTitleView; + private CheckBox mCheckBox; + private TextView mShortcutView; + + private Drawable mBackground; + private int mTextAppearance; + private Context mTextAppearanceContext; + private boolean mPreserveIconSpacing; + + //UNUSED private int mMenuType; + + private LayoutInflater mInflater; + + private boolean mForceShowIcon; + + final Context mContext; + + public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs); + mContext = context; + + TypedArray a = + context.obtainStyledAttributes( + attrs, R.styleable.SherlockMenuView, defStyle, 0); + + mBackground = a.getDrawable(R.styleable.SherlockMenuView_itemBackground); + mTextAppearance = a.getResourceId(R.styleable. + SherlockMenuView_itemTextAppearance, -1); + mPreserveIconSpacing = a.getBoolean( + R.styleable.SherlockMenuView_preserveIconSpacing, false); + mTextAppearanceContext = context; + + a.recycle(); + } + + public ListMenuItemView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + setBackgroundDrawable(mBackground); + + mTitleView = (TextView) findViewById(R.id.abs__title); + if (mTextAppearance != -1) { + mTitleView.setTextAppearance(mTextAppearanceContext, + mTextAppearance); + } + + mShortcutView = (TextView) findViewById(R.id.abs__shortcut); + } + + public void initialize(MenuItemImpl itemData, int menuType) { + mItemData = itemData; + //UNUSED mMenuType = menuType; + + setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); + + setTitle(itemData.getTitleForItemView(this)); + setCheckable(itemData.isCheckable()); + setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut()); + setIcon(itemData.getIcon()); + setEnabled(itemData.isEnabled()); + } + + public void setForceShowIcon(boolean forceShow) { + mPreserveIconSpacing = mForceShowIcon = forceShow; + } + + public void setTitle(CharSequence title) { + if (title != null) { + mTitleView.setText(title); + + if (mTitleView.getVisibility() != VISIBLE) mTitleView.setVisibility(VISIBLE); + } else { + if (mTitleView.getVisibility() != GONE) mTitleView.setVisibility(GONE); + } + } + + public MenuItemImpl getItemData() { + return mItemData; + } + + public void setCheckable(boolean checkable) { + + if (!checkable && mRadioButton == null && mCheckBox == null) { + return; + } + + if (mRadioButton == null) { + insertRadioButton(); + } + if (mCheckBox == null) { + insertCheckBox(); + } + + // Depending on whether its exclusive check or not, the checkbox or + // radio button will be the one in use (and the other will be otherCompoundButton) + final CompoundButton compoundButton; + final CompoundButton otherCompoundButton; + + if (mItemData.isExclusiveCheckable()) { + compoundButton = mRadioButton; + otherCompoundButton = mCheckBox; + } else { + compoundButton = mCheckBox; + otherCompoundButton = mRadioButton; + } + + if (checkable) { + compoundButton.setChecked(mItemData.isChecked()); + + final int newVisibility = checkable ? VISIBLE : GONE; + if (compoundButton.getVisibility() != newVisibility) { + compoundButton.setVisibility(newVisibility); + } + + // Make sure the other compound button isn't visible + if (otherCompoundButton.getVisibility() != GONE) { + otherCompoundButton.setVisibility(GONE); + } + } else { + mCheckBox.setVisibility(GONE); + mRadioButton.setVisibility(GONE); + } + } + + public void setChecked(boolean checked) { + CompoundButton compoundButton; + + if (mItemData.isExclusiveCheckable()) { + if (mRadioButton == null) { + insertRadioButton(); + } + compoundButton = mRadioButton; + } else { + if (mCheckBox == null) { + insertCheckBox(); + } + compoundButton = mCheckBox; + } + + compoundButton.setChecked(checked); + } + + public void setShortcut(boolean showShortcut, char shortcutKey) { + final int newVisibility = (showShortcut && mItemData.shouldShowShortcut()) + ? VISIBLE : GONE; + + if (newVisibility == VISIBLE) { + mShortcutView.setText(mItemData.getShortcutLabel()); + } + + if (mShortcutView.getVisibility() != newVisibility) { + mShortcutView.setVisibility(newVisibility); + } + } + + public void setIcon(Drawable icon) { + final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon; + if (!showIcon && !mPreserveIconSpacing) { + return; + } + + if (mIconView == null && icon == null && !mPreserveIconSpacing) { + return; + } + + if (mIconView == null) { + insertIconView(); + } + + if (icon != null || mPreserveIconSpacing) { + mIconView.setImageDrawable(showIcon ? icon : null); + + if (mIconView.getVisibility() != VISIBLE) { + mIconView.setVisibility(VISIBLE); + } + } else { + mIconView.setVisibility(GONE); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (mIconView != null && mPreserveIconSpacing) { + // Enforce minimum icon spacing + ViewGroup.LayoutParams lp = getLayoutParams(); + LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); + if (lp.height > 0 && iconLp.width <= 0) { + iconLp.width = lp.height; + } + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + private void insertIconView() { + LayoutInflater inflater = getInflater(); + mIconView = (ImageView) inflater.inflate(R.layout.abs__list_menu_item_icon, + this, false); + addView(mIconView, 0); + } + + private void insertRadioButton() { + LayoutInflater inflater = getInflater(); + mRadioButton = + (RadioButton) inflater.inflate(R.layout.abs__list_menu_item_radio, + this, false); + addView(mRadioButton); + } + + private void insertCheckBox() { + LayoutInflater inflater = getInflater(); + mCheckBox = + (CheckBox) inflater.inflate(R.layout.abs__list_menu_item_checkbox, + this, false); + addView(mCheckBox); + } + + public boolean prefersCondensedTitle() { + return false; + } + + public boolean showsIcon() { + return mForceShowIcon; + } + + private LayoutInflater getInflater() { + if (mInflater == null) { + mInflater = LayoutInflater.from(mContext); + } + return mInflater; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java new file mode 100644 index 0000000000..179b8f0379 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java @@ -0,0 +1,1335 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Parcelable; +import android.util.SparseArray; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.View; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.view.ActionProvider; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +/** + * Implementation of the {@link android.view.Menu} interface for creating a + * standard menu UI. + */ +public class MenuBuilder implements Menu { + //UNUSED private static final String TAG = "MenuBuilder"; + + private static final String PRESENTER_KEY = "android:menu:presenters"; + private static final String ACTION_VIEW_STATES_KEY = "android:menu:actionviewstates"; + private static final String EXPANDED_ACTION_VIEW_ID = "android:menu:expandedactionview"; + + private static final int[] sCategoryToOrder = new int[] { + 1, /* No category */ + 4, /* CONTAINER */ + 5, /* SYSTEM */ + 3, /* SECONDARY */ + 2, /* ALTERNATIVE */ + 0, /* SELECTED_ALTERNATIVE */ + }; + + private final Context mContext; + private final Resources mResources; + + /** + * Whether the shortcuts should be qwerty-accessible. Use isQwertyMode() + * instead of accessing this directly. + */ + private boolean mQwertyMode; + + /** + * Whether the shortcuts should be visible on menus. Use isShortcutsVisible() + * instead of accessing this directly. + */ + private boolean mShortcutsVisible; + + /** + * Callback that will receive the various menu-related events generated by + * this class. Use getCallback to get a reference to the callback. + */ + private Callback mCallback; + + /** Contains all of the items for this menu */ + private ArrayList mItems; + + /** Contains only the items that are currently visible. This will be created/refreshed from + * {@link #getVisibleItems()} */ + private ArrayList mVisibleItems; + /** + * Whether or not the items (or any one item's shown state) has changed since it was last + * fetched from {@link #getVisibleItems()} + */ + private boolean mIsVisibleItemsStale; + + /** + * Contains only the items that should appear in the Action Bar, if present. + */ + private ArrayList mActionItems; + /** + * Contains items that should NOT appear in the Action Bar, if present. + */ + private ArrayList mNonActionItems; + + /** + * Whether or not the items (or any one item's action state) has changed since it was + * last fetched. + */ + private boolean mIsActionItemsStale; + + /** + * Default value for how added items should show in the action list. + */ + private int mDefaultShowAsAction = MenuItem.SHOW_AS_ACTION_NEVER; + + /** + * Current use case is Context Menus: As Views populate the context menu, each one has + * extra information that should be passed along. This is the current menu info that + * should be set on all items added to this menu. + */ + private ContextMenuInfo mCurrentMenuInfo; + + /** Header title for menu types that have a header (context and submenus) */ + CharSequence mHeaderTitle; + /** Header icon for menu types that have a header and support icons (context) */ + Drawable mHeaderIcon; + /** Header custom view for menu types that have a header and support custom views (context) */ + View mHeaderView; + + /** + * Contains the state of the View hierarchy for all menu views when the menu + * was frozen. + */ + //UNUSED private SparseArray mFrozenViewStates; + + /** + * Prevents onItemsChanged from doing its junk, useful for batching commands + * that may individually call onItemsChanged. + */ + private boolean mPreventDispatchingItemsChanged = false; + private boolean mItemsChangedWhileDispatchPrevented = false; + + private boolean mOptionalIconsVisible = false; + + private boolean mIsClosing = false; + + private ArrayList mTempShortcutItemList = new ArrayList(); + + private CopyOnWriteArrayList> mPresenters = + new CopyOnWriteArrayList>(); + + /** + * Currently expanded menu item; must be collapsed when we clear. + */ + private MenuItemImpl mExpandedItem; + + /** + * Called by menu to notify of close and selection changes. + */ + public interface Callback { + /** + * Called when a menu item is selected. + * @param menu The menu that is the parent of the item + * @param item The menu item that is selected + * @return whether the menu item selection was handled + */ + public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item); + + /** + * Called when the mode of the menu changes (for example, from icon to expanded). + * + * @param menu the menu that has changed modes + */ + public void onMenuModeChange(MenuBuilder menu); + } + + /** + * Called by menu items to execute their associated action + */ + public interface ItemInvoker { + public boolean invokeItem(MenuItemImpl item); + } + + public MenuBuilder(Context context) { + mContext = context; + mResources = context.getResources(); + + mItems = new ArrayList(); + + mVisibleItems = new ArrayList(); + mIsVisibleItemsStale = true; + + mActionItems = new ArrayList(); + mNonActionItems = new ArrayList(); + mIsActionItemsStale = true; + + setShortcutsVisibleInner(true); + } + + public MenuBuilder setDefaultShowAsAction(int defaultShowAsAction) { + mDefaultShowAsAction = defaultShowAsAction; + return this; + } + + /** + * Add a presenter to this menu. This will only hold a WeakReference; + * you do not need to explicitly remove a presenter, but you can using + * {@link #removeMenuPresenter(MenuPresenter)}. + * + * @param presenter The presenter to add + */ + public void addMenuPresenter(MenuPresenter presenter) { + mPresenters.add(new WeakReference(presenter)); + presenter.initForMenu(mContext, this); + mIsActionItemsStale = true; + } + + /** + * Remove a presenter from this menu. That presenter will no longer + * receive notifications of updates to this menu's data. + * + * @param presenter The presenter to remove + */ + public void removeMenuPresenter(MenuPresenter presenter) { + for (WeakReference ref : mPresenters) { + final MenuPresenter item = ref.get(); + if (item == null || item == presenter) { + mPresenters.remove(ref); + } + } + } + + private void dispatchPresenterUpdate(boolean cleared) { + if (mPresenters.isEmpty()) return; + + stopDispatchingItemsChanged(); + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else { + presenter.updateMenuView(cleared); + } + } + startDispatchingItemsChanged(); + } + + private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) { + if (mPresenters.isEmpty()) return false; + + boolean result = false; + + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else if (!result) { + result = presenter.onSubMenuSelected(subMenu); + } + } + return result; + } + + private void dispatchSaveInstanceState(Bundle outState) { + if (mPresenters.isEmpty()) return; + + SparseArray presenterStates = new SparseArray(); + + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else { + final int id = presenter.getId(); + if (id > 0) { + final Parcelable state = presenter.onSaveInstanceState(); + if (state != null) { + presenterStates.put(id, state); + } + } + } + } + + outState.putSparseParcelableArray(PRESENTER_KEY, presenterStates); + } + + private void dispatchRestoreInstanceState(Bundle state) { + SparseArray presenterStates = state.getSparseParcelableArray(PRESENTER_KEY); + + if (presenterStates == null || mPresenters.isEmpty()) return; + + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else { + final int id = presenter.getId(); + if (id > 0) { + Parcelable parcel = presenterStates.get(id); + if (parcel != null) { + presenter.onRestoreInstanceState(parcel); + } + } + } + } + } + + public void savePresenterStates(Bundle outState) { + dispatchSaveInstanceState(outState); + } + + public void restorePresenterStates(Bundle state) { + dispatchRestoreInstanceState(state); + } + + public void saveActionViewStates(Bundle outStates) { + SparseArray viewStates = null; + + final int itemCount = size(); + for (int i = 0; i < itemCount; i++) { + final MenuItem item = getItem(i); + final View v = item.getActionView(); + if (v != null && v.getId() != View.NO_ID) { + if (viewStates == null) { + viewStates = new SparseArray(); + } + v.saveHierarchyState(viewStates); + if (item.isActionViewExpanded()) { + outStates.putInt(EXPANDED_ACTION_VIEW_ID, item.getItemId()); + } + } + if (item.hasSubMenu()) { + final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); + subMenu.saveActionViewStates(outStates); + } + } + + if (viewStates != null) { + outStates.putSparseParcelableArray(getActionViewStatesKey(), viewStates); + } + } + + public void restoreActionViewStates(Bundle states) { + if (states == null) { + return; + } + + SparseArray viewStates = states.getSparseParcelableArray( + getActionViewStatesKey()); + + final int itemCount = size(); + for (int i = 0; i < itemCount; i++) { + final MenuItem item = getItem(i); + final View v = item.getActionView(); + if (v != null && v.getId() != View.NO_ID) { + v.restoreHierarchyState(viewStates); + } + if (item.hasSubMenu()) { + final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); + subMenu.restoreActionViewStates(states); + } + } + + final int expandedId = states.getInt(EXPANDED_ACTION_VIEW_ID); + if (expandedId > 0) { + MenuItem itemToExpand = findItem(expandedId); + if (itemToExpand != null) { + itemToExpand.expandActionView(); + } + } + } + + protected String getActionViewStatesKey() { + return ACTION_VIEW_STATES_KEY; + } + + public void setCallback(Callback cb) { + mCallback = cb; + } + + /** + * Adds an item to the menu. The other add methods funnel to this. + */ + private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) { + final int ordering = getOrdering(categoryOrder); + + final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder, + ordering, title, mDefaultShowAsAction); + + if (mCurrentMenuInfo != null) { + // Pass along the current menu info + item.setMenuInfo(mCurrentMenuInfo); + } + + mItems.add(findInsertIndex(mItems, ordering), item); + onItemsChanged(true); + + return item; + } + + public MenuItem add(CharSequence title) { + return addInternal(0, 0, 0, title); + } + + public MenuItem add(int titleRes) { + return addInternal(0, 0, 0, mResources.getString(titleRes)); + } + + public MenuItem add(int group, int id, int categoryOrder, CharSequence title) { + return addInternal(group, id, categoryOrder, title); + } + + public MenuItem add(int group, int id, int categoryOrder, int title) { + return addInternal(group, id, categoryOrder, mResources.getString(title)); + } + + public SubMenu addSubMenu(CharSequence title) { + return addSubMenu(0, 0, 0, title); + } + + public SubMenu addSubMenu(int titleRes) { + return addSubMenu(0, 0, 0, mResources.getString(titleRes)); + } + + public SubMenu addSubMenu(int group, int id, int categoryOrder, CharSequence title) { + final MenuItemImpl item = (MenuItemImpl) addInternal(group, id, categoryOrder, title); + final SubMenuBuilder subMenu = new SubMenuBuilder(mContext, this, item); + item.setSubMenu(subMenu); + + return subMenu; + } + + public SubMenu addSubMenu(int group, int id, int categoryOrder, int title) { + return addSubMenu(group, id, categoryOrder, mResources.getString(title)); + } + + public int addIntentOptions(int group, int id, int categoryOrder, ComponentName caller, + Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) { + PackageManager pm = mContext.getPackageManager(); + final List lri = + pm.queryIntentActivityOptions(caller, specifics, intent, 0); + final int N = lri != null ? lri.size() : 0; + + if ((flags & FLAG_APPEND_TO_GROUP) == 0) { + removeGroup(group); + } + + for (int i=0; i= 0) { + outSpecificItems[ri.specificIndex] = item; + } + } + + return N; + } + + public void removeItem(int id) { + removeItemAtInt(findItemIndex(id), true); + } + + public void removeGroup(int group) { + final int i = findGroupIndex(group); + + if (i >= 0) { + final int maxRemovable = mItems.size() - i; + int numRemoved = 0; + while ((numRemoved++ < maxRemovable) && (mItems.get(i).getGroupId() == group)) { + // Don't force update for each one, this method will do it at the end + removeItemAtInt(i, false); + } + + // Notify menu views + onItemsChanged(true); + } + } + + /** + * Remove the item at the given index and optionally forces menu views to + * update. + * + * @param index The index of the item to be removed. If this index is + * invalid an exception is thrown. + * @param updateChildrenOnMenuViews Whether to force update on menu views. + * Please make sure you eventually call this after your batch of + * removals. + */ + private void removeItemAtInt(int index, boolean updateChildrenOnMenuViews) { + if ((index < 0) || (index >= mItems.size())) return; + + mItems.remove(index); + + if (updateChildrenOnMenuViews) onItemsChanged(true); + } + + public void removeItemAt(int index) { + removeItemAtInt(index, true); + } + + public void clearAll() { + mPreventDispatchingItemsChanged = true; + clear(); + clearHeader(); + mPreventDispatchingItemsChanged = false; + mItemsChangedWhileDispatchPrevented = false; + onItemsChanged(true); + } + + public void clear() { + if (mExpandedItem != null) { + collapseItemActionView(mExpandedItem); + } + mItems.clear(); + + onItemsChanged(true); + } + + void setExclusiveItemChecked(MenuItem item) { + final int group = item.getGroupId(); + + final int N = mItems.size(); + for (int i = 0; i < N; i++) { + MenuItemImpl curItem = mItems.get(i); + if (curItem.getGroupId() == group) { + if (!curItem.isExclusiveCheckable()) continue; + if (!curItem.isCheckable()) continue; + + // Check the item meant to be checked, uncheck the others (that are in the group) + curItem.setCheckedInt(curItem == item); + } + } + } + + public void setGroupCheckable(int group, boolean checkable, boolean exclusive) { + final int N = mItems.size(); + + for (int i = 0; i < N; i++) { + MenuItemImpl item = mItems.get(i); + if (item.getGroupId() == group) { + item.setExclusiveCheckable(exclusive); + item.setCheckable(checkable); + } + } + } + + public void setGroupVisible(int group, boolean visible) { + final int N = mItems.size(); + + // We handle the notification of items being changed ourselves, so we use setVisibleInt rather + // than setVisible and at the end notify of items being changed + + boolean changedAtLeastOneItem = false; + for (int i = 0; i < N; i++) { + MenuItemImpl item = mItems.get(i); + if (item.getGroupId() == group) { + if (item.setVisibleInt(visible)) changedAtLeastOneItem = true; + } + } + + if (changedAtLeastOneItem) onItemsChanged(true); + } + + public void setGroupEnabled(int group, boolean enabled) { + final int N = mItems.size(); + + for (int i = 0; i < N; i++) { + MenuItemImpl item = mItems.get(i); + if (item.getGroupId() == group) { + item.setEnabled(enabled); + } + } + } + + public boolean hasVisibleItems() { + final int size = size(); + + for (int i = 0; i < size; i++) { + MenuItemImpl item = mItems.get(i); + if (item.isVisible()) { + return true; + } + } + + return false; + } + + public MenuItem findItem(int id) { + final int size = size(); + for (int i = 0; i < size; i++) { + MenuItemImpl item = mItems.get(i); + if (item.getItemId() == id) { + return item; + } else if (item.hasSubMenu()) { + MenuItem possibleItem = item.getSubMenu().findItem(id); + + if (possibleItem != null) { + return possibleItem; + } + } + } + + return null; + } + + public int findItemIndex(int id) { + final int size = size(); + + for (int i = 0; i < size; i++) { + MenuItemImpl item = mItems.get(i); + if (item.getItemId() == id) { + return i; + } + } + + return -1; + } + + public int findGroupIndex(int group) { + return findGroupIndex(group, 0); + } + + public int findGroupIndex(int group, int start) { + final int size = size(); + + if (start < 0) { + start = 0; + } + + for (int i = start; i < size; i++) { + final MenuItemImpl item = mItems.get(i); + + if (item.getGroupId() == group) { + return i; + } + } + + return -1; + } + + public int size() { + return mItems.size(); + } + + /** {@inheritDoc} */ + public MenuItem getItem(int index) { + return mItems.get(index); + } + + public boolean isShortcutKey(int keyCode, KeyEvent event) { + return findItemWithShortcutForKey(keyCode, event) != null; + } + + public void setQwertyMode(boolean isQwerty) { + mQwertyMode = isQwerty; + + onItemsChanged(false); + } + + /** + * Returns the ordering across all items. This will grab the category from + * the upper bits, find out how to order the category with respect to other + * categories, and combine it with the lower bits. + * + * @param categoryOrder The category order for a particular item (if it has + * not been or/add with a category, the default category is + * assumed). + * @return An ordering integer that can be used to order this item across + * all the items (even from other categories). + */ + private static int getOrdering(int categoryOrder) { + final int index = (categoryOrder & CATEGORY_MASK) >> CATEGORY_SHIFT; + + if (index < 0 || index >= sCategoryToOrder.length) { + throw new IllegalArgumentException("order does not contain a valid category."); + } + + return (sCategoryToOrder[index] << CATEGORY_SHIFT) | (categoryOrder & USER_MASK); + } + + /** + * @return whether the menu shortcuts are in qwerty mode or not + */ + boolean isQwertyMode() { + return mQwertyMode; + } + + /** + * Sets whether the shortcuts should be visible on menus. Devices without hardware + * key input will never make shortcuts visible even if this method is passed 'true'. + * + * @param shortcutsVisible Whether shortcuts should be visible (if true and a + * menu item does not have a shortcut defined, that item will + * still NOT show a shortcut) + */ + public void setShortcutsVisible(boolean shortcutsVisible) { + if (mShortcutsVisible == shortcutsVisible) return; + + setShortcutsVisibleInner(shortcutsVisible); + onItemsChanged(false); + } + + private void setShortcutsVisibleInner(boolean shortcutsVisible) { + mShortcutsVisible = shortcutsVisible + && mResources.getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS + && mResources.getBoolean( + R.bool.abs__config_showMenuShortcutsWhenKeyboardPresent); + } + + /** + * @return Whether shortcuts should be visible on menus. + */ + public boolean isShortcutsVisible() { + return mShortcutsVisible; + } + + Resources getResources() { + return mResources; + } + + public Context getContext() { + return mContext; + } + + boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) { + return mCallback != null && mCallback.onMenuItemSelected(menu, item); + } + + /** + * Dispatch a mode change event to this menu's callback. + */ + public void changeMenuMode() { + if (mCallback != null) { + mCallback.onMenuModeChange(this); + } + } + + private static int findInsertIndex(ArrayList items, int ordering) { + for (int i = items.size() - 1; i >= 0; i--) { + MenuItemImpl item = items.get(i); + if (item.getOrdering() <= ordering) { + return i + 1; + } + } + + return 0; + } + + public boolean performShortcut(int keyCode, KeyEvent event, int flags) { + final MenuItemImpl item = findItemWithShortcutForKey(keyCode, event); + + boolean handled = false; + + if (item != null) { + handled = performItemAction(item, flags); + } + + if ((flags & FLAG_ALWAYS_PERFORM_CLOSE) != 0) { + close(true); + } + + return handled; + } + + /* + * This function will return all the menu and sub-menu items that can + * be directly (the shortcut directly corresponds) and indirectly + * (the ALT-enabled char corresponds to the shortcut) associated + * with the keyCode. + */ + @SuppressWarnings("deprecation") + void findItemsWithShortcutForKey(List items, int keyCode, KeyEvent event) { + final boolean qwerty = isQwertyMode(); + final int metaState = event.getMetaState(); + final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); + // Get the chars associated with the keyCode (i.e using any chording combo) + final boolean isKeyCodeMapped = event.getKeyData(possibleChars); + // The delete key is not mapped to '\b' so we treat it specially + if (!isKeyCodeMapped && (keyCode != KeyEvent.KEYCODE_DEL)) { + return; + } + + // Look for an item whose shortcut is this key. + final int N = mItems.size(); + for (int i = 0; i < N; i++) { + MenuItemImpl item = mItems.get(i); + if (item.hasSubMenu()) { + ((MenuBuilder)item.getSubMenu()).findItemsWithShortcutForKey(items, keyCode, event); + } + final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut(); + if (((metaState & (KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON)) == 0) && + (shortcutChar != 0) && + (shortcutChar == possibleChars.meta[0] + || shortcutChar == possibleChars.meta[2] + || (qwerty && shortcutChar == '\b' && + keyCode == KeyEvent.KEYCODE_DEL)) && + item.isEnabled()) { + items.add(item); + } + } + } + + /* + * We want to return the menu item associated with the key, but if there is no + * ambiguity (i.e. there is only one menu item corresponding to the key) we want + * to return it even if it's not an exact match; this allow the user to + * _not_ use the ALT key for example, making the use of shortcuts slightly more + * user-friendly. An example is on the G1, '!' and '1' are on the same key, and + * in Gmail, Menu+1 will trigger Menu+! (the actual shortcut). + * + * On the other hand, if two (or more) shortcuts corresponds to the same key, + * we have to only return the exact match. + */ + @SuppressWarnings("deprecation") + MenuItemImpl findItemWithShortcutForKey(int keyCode, KeyEvent event) { + // Get all items that can be associated directly or indirectly with the keyCode + ArrayList items = mTempShortcutItemList; + items.clear(); + findItemsWithShortcutForKey(items, keyCode, event); + + if (items.isEmpty()) { + return null; + } + + final int metaState = event.getMetaState(); + final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); + // Get the chars associated with the keyCode (i.e using any chording combo) + event.getKeyData(possibleChars); + + // If we have only one element, we can safely returns it + final int size = items.size(); + if (size == 1) { + return items.get(0); + } + + final boolean qwerty = isQwertyMode(); + // If we found more than one item associated with the key, + // we have to return the exact match + for (int i = 0; i < size; i++) { + final MenuItemImpl item = items.get(i); + final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : + item.getNumericShortcut(); + if ((shortcutChar == possibleChars.meta[0] && + (metaState & KeyEvent.META_ALT_ON) == 0) + || (shortcutChar == possibleChars.meta[2] && + (metaState & KeyEvent.META_ALT_ON) != 0) + || (qwerty && shortcutChar == '\b' && + keyCode == KeyEvent.KEYCODE_DEL)) { + return item; + } + } + return null; + } + + public boolean performIdentifierAction(int id, int flags) { + // Look for an item whose identifier is the id. + return performItemAction(findItem(id), flags); + } + + public boolean performItemAction(MenuItem item, int flags) { + MenuItemImpl itemImpl = (MenuItemImpl) item; + + if (itemImpl == null || !itemImpl.isEnabled()) { + return false; + } + + boolean invoked = itemImpl.invoke(); + + if (itemImpl.hasCollapsibleActionView()) { + invoked |= itemImpl.expandActionView(); + if (invoked) close(true); + } else if (item.hasSubMenu()) { + close(false); + + final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); + final ActionProvider provider = item.getActionProvider(); + if (provider != null && provider.hasSubMenu()) { + provider.onPrepareSubMenu(subMenu); + } + invoked |= dispatchSubMenuSelected(subMenu); + if (!invoked) close(true); + } else { + if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) { + close(true); + } + } + + return invoked; + } + + /** + * Closes the visible menu. + * + * @param allMenusAreClosing Whether the menus are completely closing (true), + * or whether there is another menu coming in this menu's place + * (false). For example, if the menu is closing because a + * sub menu is about to be shown, allMenusAreClosing + * is false. + */ + final void close(boolean allMenusAreClosing) { + if (mIsClosing) return; + + mIsClosing = true; + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else { + presenter.onCloseMenu(this, allMenusAreClosing); + } + } + mIsClosing = false; + } + + /** {@inheritDoc} */ + public void close() { + close(true); + } + + /** + * Called when an item is added or removed. + * + * @param structureChanged true if the menu structure changed, + * false if only item properties changed. + * (Visibility is a structural property since it affects layout.) + */ + void onItemsChanged(boolean structureChanged) { + if (!mPreventDispatchingItemsChanged) { + if (structureChanged) { + mIsVisibleItemsStale = true; + mIsActionItemsStale = true; + } + + dispatchPresenterUpdate(structureChanged); + } else { + mItemsChangedWhileDispatchPrevented = true; + } + } + + /** + * Stop dispatching item changed events to presenters until + * {@link #startDispatchingItemsChanged()} is called. Useful when + * many menu operations are going to be performed as a batch. + */ + public void stopDispatchingItemsChanged() { + if (!mPreventDispatchingItemsChanged) { + mPreventDispatchingItemsChanged = true; + mItemsChangedWhileDispatchPrevented = false; + } + } + + public void startDispatchingItemsChanged() { + mPreventDispatchingItemsChanged = false; + + if (mItemsChangedWhileDispatchPrevented) { + mItemsChangedWhileDispatchPrevented = false; + onItemsChanged(true); + } + } + + /** + * Called by {@link MenuItemImpl} when its visible flag is changed. + * @param item The item that has gone through a visibility change. + */ + void onItemVisibleChanged(MenuItemImpl item) { + // Notify of items being changed + mIsVisibleItemsStale = true; + onItemsChanged(true); + } + + /** + * Called by {@link MenuItemImpl} when its action request status is changed. + * @param item The item that has gone through a change in action request status. + */ + void onItemActionRequestChanged(MenuItemImpl item) { + // Notify of items being changed + mIsActionItemsStale = true; + onItemsChanged(true); + } + + ArrayList getVisibleItems() { + if (!mIsVisibleItemsStale) return mVisibleItems; + + // Refresh the visible items + mVisibleItems.clear(); + + final int itemsSize = mItems.size(); + MenuItemImpl item; + for (int i = 0; i < itemsSize; i++) { + item = mItems.get(i); + if (item.isVisible()) mVisibleItems.add(item); + } + + mIsVisibleItemsStale = false; + mIsActionItemsStale = true; + + return mVisibleItems; + } + + /** + * This method determines which menu items get to be 'action items' that will appear + * in an action bar and which items should be 'overflow items' in a secondary menu. + * The rules are as follows: + * + *

Items are considered for inclusion in the order specified within the menu. + * There is a limit of mMaxActionItems as a total count, optionally including the overflow + * menu button itself. This is a soft limit; if an item shares a group ID with an item + * previously included as an action item, the new item will stay with its group and become + * an action item itself even if it breaks the max item count limit. This is done to + * limit the conceptual complexity of the items presented within an action bar. Only a few + * unrelated concepts should be presented to the user in this space, and groups are treated + * as a single concept. + * + *

There is also a hard limit of consumed measurable space: mActionWidthLimit. This + * limit may be broken by a single item that exceeds the remaining space, but no further + * items may be added. If an item that is part of a group cannot fit within the remaining + * measured width, the entire group will be demoted to overflow. This is done to ensure room + * for navigation and other affordances in the action bar as well as reduce general UI clutter. + * + *

The space freed by demoting a full group cannot be consumed by future menu items. + * Once items begin to overflow, all future items become overflow items as well. This is + * to avoid inadvertent reordering that may break the app's intended design. + */ + public void flagActionItems() { + if (!mIsActionItemsStale) { + return; + } + + // Presenters flag action items as needed. + boolean flagged = false; + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else { + flagged |= presenter.flagActionItems(); + } + } + + if (flagged) { + mActionItems.clear(); + mNonActionItems.clear(); + ArrayList visibleItems = getVisibleItems(); + final int itemsSize = visibleItems.size(); + for (int i = 0; i < itemsSize; i++) { + MenuItemImpl item = visibleItems.get(i); + if (item.isActionButton()) { + mActionItems.add(item); + } else { + mNonActionItems.add(item); + } + } + } else { + // Nobody flagged anything, everything is a non-action item. + // (This happens during a first pass with no action-item presenters.) + mActionItems.clear(); + mNonActionItems.clear(); + mNonActionItems.addAll(getVisibleItems()); + } + mIsActionItemsStale = false; + } + + ArrayList getActionItems() { + flagActionItems(); + return mActionItems; + } + + ArrayList getNonActionItems() { + flagActionItems(); + return mNonActionItems; + } + + public void clearHeader() { + mHeaderIcon = null; + mHeaderTitle = null; + mHeaderView = null; + + onItemsChanged(false); + } + + private void setHeaderInternal(final int titleRes, final CharSequence title, final int iconRes, + final Drawable icon, final View view) { + final Resources r = getResources(); + + if (view != null) { + mHeaderView = view; + + // If using a custom view, then the title and icon aren't used + mHeaderTitle = null; + mHeaderIcon = null; + } else { + if (titleRes > 0) { + mHeaderTitle = r.getText(titleRes); + } else if (title != null) { + mHeaderTitle = title; + } + + if (iconRes > 0) { + mHeaderIcon = r.getDrawable(iconRes); + } else if (icon != null) { + mHeaderIcon = icon; + } + + // If using the title or icon, then a custom view isn't used + mHeaderView = null; + } + + // Notify of change + onItemsChanged(false); + } + + /** + * Sets the header's title. This replaces the header view. Called by the + * builder-style methods of subclasses. + * + * @param title The new title. + * @return This MenuBuilder so additional setters can be called. + */ + protected MenuBuilder setHeaderTitleInt(CharSequence title) { + setHeaderInternal(0, title, 0, null, null); + return this; + } + + /** + * Sets the header's title. This replaces the header view. Called by the + * builder-style methods of subclasses. + * + * @param titleRes The new title (as a resource ID). + * @return This MenuBuilder so additional setters can be called. + */ + protected MenuBuilder setHeaderTitleInt(int titleRes) { + setHeaderInternal(titleRes, null, 0, null, null); + return this; + } + + /** + * Sets the header's icon. This replaces the header view. Called by the + * builder-style methods of subclasses. + * + * @param icon The new icon. + * @return This MenuBuilder so additional setters can be called. + */ + protected MenuBuilder setHeaderIconInt(Drawable icon) { + setHeaderInternal(0, null, 0, icon, null); + return this; + } + + /** + * Sets the header's icon. This replaces the header view. Called by the + * builder-style methods of subclasses. + * + * @param iconRes The new icon (as a resource ID). + * @return This MenuBuilder so additional setters can be called. + */ + protected MenuBuilder setHeaderIconInt(int iconRes) { + setHeaderInternal(0, null, iconRes, null, null); + return this; + } + + /** + * Sets the header's view. This replaces the title and icon. Called by the + * builder-style methods of subclasses. + * + * @param view The new view. + * @return This MenuBuilder so additional setters can be called. + */ + protected MenuBuilder setHeaderViewInt(View view) { + setHeaderInternal(0, null, 0, null, view); + return this; + } + + public CharSequence getHeaderTitle() { + return mHeaderTitle; + } + + public Drawable getHeaderIcon() { + return mHeaderIcon; + } + + public View getHeaderView() { + return mHeaderView; + } + + /** + * Gets the root menu (if this is a submenu, find its root menu). + * @return The root menu. + */ + public MenuBuilder getRootMenu() { + return this; + } + + /** + * Sets the current menu info that is set on all items added to this menu + * (until this is called again with different menu info, in which case that + * one will be added to all subsequent item additions). + * + * @param menuInfo The extra menu information to add. + */ + public void setCurrentMenuInfo(ContextMenuInfo menuInfo) { + mCurrentMenuInfo = menuInfo; + } + + void setOptionalIconsVisible(boolean visible) { + mOptionalIconsVisible = visible; + } + + boolean getOptionalIconsVisible() { + return mOptionalIconsVisible; + } + + public boolean expandItemActionView(MenuItemImpl item) { + if (mPresenters.isEmpty()) return false; + + boolean expanded = false; + + stopDispatchingItemsChanged(); + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else if ((expanded = presenter.expandItemActionView(this, item))) { + break; + } + } + startDispatchingItemsChanged(); + + if (expanded) { + mExpandedItem = item; + } + return expanded; + } + + public boolean collapseItemActionView(MenuItemImpl item) { + if (mPresenters.isEmpty() || mExpandedItem != item) return false; + + boolean collapsed = false; + + stopDispatchingItemsChanged(); + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else if ((collapsed = presenter.collapseItemActionView(this, item))) { + break; + } + } + startDispatchingItemsChanged(); + + if (collapsed) { + mExpandedItem = null; + } + return collapsed; + } + + public MenuItemImpl getExpandedItem() { + return mExpandedItem; + } + + public boolean bindNativeOverflow(android.view.Menu menu, android.view.MenuItem.OnMenuItemClickListener listener, HashMap map) { + final List nonActionItems = getNonActionItems(); + if (nonActionItems == null || nonActionItems.size() == 0) { + return false; + } + + boolean visible = false; + menu.clear(); + for (MenuItemImpl nonActionItem : nonActionItems) { + if (!nonActionItem.isVisible()) { + continue; + } + visible = true; + + android.view.MenuItem nativeItem; + if (nonActionItem.hasSubMenu()) { + android.view.SubMenu nativeSub = menu.addSubMenu(nonActionItem.getGroupId(), nonActionItem.getItemId(), + nonActionItem.getOrder(), nonActionItem.getTitle()); + + SubMenuBuilder subMenu = (SubMenuBuilder)nonActionItem.getSubMenu(); + for (MenuItemImpl subItem : subMenu.getVisibleItems()) { + android.view.MenuItem nativeSubItem = nativeSub.add(subItem.getGroupId(), subItem.getItemId(), + subItem.getOrder(), subItem.getTitle()); + + nativeSubItem.setIcon(subItem.getIcon()); + nativeSubItem.setOnMenuItemClickListener(listener); + nativeSubItem.setEnabled(subItem.isEnabled()); + nativeSubItem.setIntent(subItem.getIntent()); + nativeSubItem.setNumericShortcut(subItem.getNumericShortcut()); + nativeSubItem.setAlphabeticShortcut(subItem.getAlphabeticShortcut()); + nativeSubItem.setTitleCondensed(subItem.getTitleCondensed()); + nativeSubItem.setCheckable(subItem.isCheckable()); + nativeSubItem.setChecked(subItem.isChecked()); + + if (subItem.isExclusiveCheckable()) { + nativeSub.setGroupCheckable(subItem.getGroupId(), true, true); + } + + map.put(nativeSubItem, subItem); + } + + nativeItem = nativeSub.getItem(); + } else { + nativeItem = menu.add(nonActionItem.getGroupId(), nonActionItem.getItemId(), + nonActionItem.getOrder(), nonActionItem.getTitle()); + } + nativeItem.setIcon(nonActionItem.getIcon()); + nativeItem.setOnMenuItemClickListener(listener); + nativeItem.setEnabled(nonActionItem.isEnabled()); + nativeItem.setIntent(nonActionItem.getIntent()); + nativeItem.setNumericShortcut(nonActionItem.getNumericShortcut()); + nativeItem.setAlphabeticShortcut(nonActionItem.getAlphabeticShortcut()); + nativeItem.setTitleCondensed(nonActionItem.getTitleCondensed()); + nativeItem.setCheckable(nonActionItem.isCheckable()); + nativeItem.setChecked(nonActionItem.isChecked()); + + if (nonActionItem.isExclusiveCheckable()) { + menu.setGroupCheckable(nonActionItem.getGroupId(), true, true); + } + + map.put(nativeItem, nonActionItem); + } + return visible; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java new file mode 100644 index 0000000000..f5359fb407 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java @@ -0,0 +1,647 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewDebug; +import android.widget.LinearLayout; + +import com.actionbarsherlock.view.ActionProvider; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +/** + * @hide + */ +public final class MenuItemImpl implements MenuItem { + private static final String TAG = "MenuItemImpl"; + + private static final int SHOW_AS_ACTION_MASK = SHOW_AS_ACTION_NEVER | + SHOW_AS_ACTION_IF_ROOM | + SHOW_AS_ACTION_ALWAYS; + + private final int mId; + private final int mGroup; + private final int mCategoryOrder; + private final int mOrdering; + private CharSequence mTitle; + private CharSequence mTitleCondensed; + private Intent mIntent; + private char mShortcutNumericChar; + private char mShortcutAlphabeticChar; + + /** The icon's drawable which is only created as needed */ + private Drawable mIconDrawable; + /** + * The icon's resource ID which is used to get the Drawable when it is + * needed (if the Drawable isn't already obtained--only one of the two is + * needed). + */ + private int mIconResId = NO_ICON; + + /** The menu to which this item belongs */ + private MenuBuilder mMenu; + /** If this item should launch a sub menu, this is the sub menu to launch */ + private SubMenuBuilder mSubMenu; + + private Runnable mItemCallback; + private MenuItem.OnMenuItemClickListener mClickListener; + + private int mFlags = ENABLED; + private static final int CHECKABLE = 0x00000001; + private static final int CHECKED = 0x00000002; + private static final int EXCLUSIVE = 0x00000004; + private static final int HIDDEN = 0x00000008; + private static final int ENABLED = 0x00000010; + private static final int IS_ACTION = 0x00000020; + + private int mShowAsAction = SHOW_AS_ACTION_NEVER; + + private View mActionView; + private ActionProvider mActionProvider; + private OnActionExpandListener mOnActionExpandListener; + private boolean mIsActionViewExpanded = false; + + /** Used for the icon resource ID if this item does not have an icon */ + static final int NO_ICON = 0; + + /** + * Current use case is for context menu: Extra information linked to the + * View that added this item to the context menu. + */ + private ContextMenuInfo mMenuInfo; + + private static String sPrependShortcutLabel; + private static String sEnterShortcutLabel; + private static String sDeleteShortcutLabel; + private static String sSpaceShortcutLabel; + + + /** + * Instantiates this menu item. + * + * @param menu + * @param group Item ordering grouping control. The item will be added after + * all other items whose order is <= this number, and before any + * that are larger than it. This can also be used to define + * groups of items for batch state changes. Normally use 0. + * @param id Unique item ID. Use 0 if you do not need a unique ID. + * @param categoryOrder The ordering for this item. + * @param title The text to display for the item. + */ + MenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering, + CharSequence title, int showAsAction) { + + /* TODO if (sPrependShortcutLabel == null) { + // This is instantiated from the UI thread, so no chance of sync issues + sPrependShortcutLabel = menu.getContext().getResources().getString( + com.android.internal.R.string.prepend_shortcut_label); + sEnterShortcutLabel = menu.getContext().getResources().getString( + com.android.internal.R.string.menu_enter_shortcut_label); + sDeleteShortcutLabel = menu.getContext().getResources().getString( + com.android.internal.R.string.menu_delete_shortcut_label); + sSpaceShortcutLabel = menu.getContext().getResources().getString( + com.android.internal.R.string.menu_space_shortcut_label); + }*/ + + mMenu = menu; + mId = id; + mGroup = group; + mCategoryOrder = categoryOrder; + mOrdering = ordering; + mTitle = title; + mShowAsAction = showAsAction; + } + + /** + * Invokes the item by calling various listeners or callbacks. + * + * @return true if the invocation was handled, false otherwise + */ + public boolean invoke() { + if (mClickListener != null && + mClickListener.onMenuItemClick(this)) { + return true; + } + + if (mMenu.dispatchMenuItemSelected(mMenu.getRootMenu(), this)) { + return true; + } + + if (mItemCallback != null) { + mItemCallback.run(); + return true; + } + + if (mIntent != null) { + try { + mMenu.getContext().startActivity(mIntent); + return true; + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Can't find activity to handle intent; ignoring", e); + } + } + + if (mActionProvider != null && mActionProvider.onPerformDefaultAction()) { + return true; + } + + return false; + } + + public boolean isEnabled() { + return (mFlags & ENABLED) != 0; + } + + public MenuItem setEnabled(boolean enabled) { + if (enabled) { + mFlags |= ENABLED; + } else { + mFlags &= ~ENABLED; + } + + mMenu.onItemsChanged(false); + + return this; + } + + public int getGroupId() { + return mGroup; + } + + @ViewDebug.CapturedViewProperty + public int getItemId() { + return mId; + } + + public int getOrder() { + return mCategoryOrder; + } + + public int getOrdering() { + return mOrdering; + } + + public Intent getIntent() { + return mIntent; + } + + public MenuItem setIntent(Intent intent) { + mIntent = intent; + return this; + } + + Runnable getCallback() { + return mItemCallback; + } + + public MenuItem setCallback(Runnable callback) { + mItemCallback = callback; + return this; + } + + public char getAlphabeticShortcut() { + return mShortcutAlphabeticChar; + } + + public MenuItem setAlphabeticShortcut(char alphaChar) { + if (mShortcutAlphabeticChar == alphaChar) return this; + + mShortcutAlphabeticChar = Character.toLowerCase(alphaChar); + + mMenu.onItemsChanged(false); + + return this; + } + + public char getNumericShortcut() { + return mShortcutNumericChar; + } + + public MenuItem setNumericShortcut(char numericChar) { + if (mShortcutNumericChar == numericChar) return this; + + mShortcutNumericChar = numericChar; + + mMenu.onItemsChanged(false); + + return this; + } + + public MenuItem setShortcut(char numericChar, char alphaChar) { + mShortcutNumericChar = numericChar; + mShortcutAlphabeticChar = Character.toLowerCase(alphaChar); + + mMenu.onItemsChanged(false); + + return this; + } + + /** + * @return The active shortcut (based on QWERTY-mode of the menu). + */ + char getShortcut() { + return (mMenu.isQwertyMode() ? mShortcutAlphabeticChar : mShortcutNumericChar); + } + + /** + * @return The label to show for the shortcut. This includes the chording + * key (for example 'Menu+a'). Also, any non-human readable + * characters should be human readable (for example 'Menu+enter'). + */ + String getShortcutLabel() { + + char shortcut = getShortcut(); + if (shortcut == 0) { + return ""; + } + + StringBuilder sb = new StringBuilder(sPrependShortcutLabel); + switch (shortcut) { + + case '\n': + sb.append(sEnterShortcutLabel); + break; + + case '\b': + sb.append(sDeleteShortcutLabel); + break; + + case ' ': + sb.append(sSpaceShortcutLabel); + break; + + default: + sb.append(shortcut); + break; + } + + return sb.toString(); + } + + /** + * @return Whether this menu item should be showing shortcuts (depends on + * whether the menu should show shortcuts and whether this item has + * a shortcut defined) + */ + boolean shouldShowShortcut() { + // Show shortcuts if the menu is supposed to show shortcuts AND this item has a shortcut + return mMenu.isShortcutsVisible() && (getShortcut() != 0); + } + + public SubMenu getSubMenu() { + return mSubMenu; + } + + public boolean hasSubMenu() { + return mSubMenu != null; + } + + void setSubMenu(SubMenuBuilder subMenu) { + mSubMenu = subMenu; + + subMenu.setHeaderTitle(getTitle()); + } + + @ViewDebug.CapturedViewProperty + public CharSequence getTitle() { + return mTitle; + } + + /** + * Gets the title for a particular {@link ItemView} + * + * @param itemView The ItemView that is receiving the title + * @return Either the title or condensed title based on what the ItemView + * prefers + */ + CharSequence getTitleForItemView(MenuView.ItemView itemView) { + return ((itemView != null) && itemView.prefersCondensedTitle()) + ? getTitleCondensed() + : getTitle(); + } + + public MenuItem setTitle(CharSequence title) { + mTitle = title; + + mMenu.onItemsChanged(false); + + if (mSubMenu != null) { + mSubMenu.setHeaderTitle(title); + } + + return this; + } + + public MenuItem setTitle(int title) { + return setTitle(mMenu.getContext().getString(title)); + } + + public CharSequence getTitleCondensed() { + return mTitleCondensed != null ? mTitleCondensed : mTitle; + } + + public MenuItem setTitleCondensed(CharSequence title) { + mTitleCondensed = title; + + // Could use getTitle() in the loop below, but just cache what it would do here + if (title == null) { + title = mTitle; + } + + mMenu.onItemsChanged(false); + + return this; + } + + public Drawable getIcon() { + if (mIconDrawable != null) { + return mIconDrawable; + } + + if (mIconResId != NO_ICON) { + return mMenu.getResources().getDrawable(mIconResId); + } + + return null; + } + + public MenuItem setIcon(Drawable icon) { + mIconResId = NO_ICON; + mIconDrawable = icon; + mMenu.onItemsChanged(false); + + return this; + } + + public MenuItem setIcon(int iconResId) { + mIconDrawable = null; + mIconResId = iconResId; + + // If we have a view, we need to push the Drawable to them + mMenu.onItemsChanged(false); + + return this; + } + + public boolean isCheckable() { + return (mFlags & CHECKABLE) == CHECKABLE; + } + + public MenuItem setCheckable(boolean checkable) { + final int oldFlags = mFlags; + mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0); + if (oldFlags != mFlags) { + mMenu.onItemsChanged(false); + } + + return this; + } + + public void setExclusiveCheckable(boolean exclusive) { + mFlags = (mFlags & ~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0); + } + + public boolean isExclusiveCheckable() { + return (mFlags & EXCLUSIVE) != 0; + } + + public boolean isChecked() { + return (mFlags & CHECKED) == CHECKED; + } + + public MenuItem setChecked(boolean checked) { + if ((mFlags & EXCLUSIVE) != 0) { + // Call the method on the Menu since it knows about the others in this + // exclusive checkable group + mMenu.setExclusiveItemChecked(this); + } else { + setCheckedInt(checked); + } + + return this; + } + + void setCheckedInt(boolean checked) { + final int oldFlags = mFlags; + mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0); + if (oldFlags != mFlags) { + mMenu.onItemsChanged(false); + } + } + + public boolean isVisible() { + return (mFlags & HIDDEN) == 0; + } + + /** + * Changes the visibility of the item. This method DOES NOT notify the + * parent menu of a change in this item, so this should only be called from + * methods that will eventually trigger this change. If unsure, use {@link #setVisible(boolean)} + * instead. + * + * @param shown Whether to show (true) or hide (false). + * @return Whether the item's shown state was changed + */ + boolean setVisibleInt(boolean shown) { + final int oldFlags = mFlags; + mFlags = (mFlags & ~HIDDEN) | (shown ? 0 : HIDDEN); + return oldFlags != mFlags; + } + + public MenuItem setVisible(boolean shown) { + // Try to set the shown state to the given state. If the shown state was changed + // (i.e. the previous state isn't the same as given state), notify the parent menu that + // the shown state has changed for this item + if (setVisibleInt(shown)) mMenu.onItemVisibleChanged(this); + + return this; + } + + public MenuItem setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener clickListener) { + mClickListener = clickListener; + return this; + } + + @Override + public String toString() { + return mTitle.toString(); + } + + void setMenuInfo(ContextMenuInfo menuInfo) { + mMenuInfo = menuInfo; + } + + public ContextMenuInfo getMenuInfo() { + return mMenuInfo; + } + + public void actionFormatChanged() { + mMenu.onItemActionRequestChanged(this); + } + + /** + * @return Whether the menu should show icons for menu items. + */ + public boolean shouldShowIcon() { + return mMenu.getOptionalIconsVisible(); + } + + public boolean isActionButton() { + return (mFlags & IS_ACTION) == IS_ACTION; + } + + public boolean requestsActionButton() { + return (mShowAsAction & SHOW_AS_ACTION_IF_ROOM) == SHOW_AS_ACTION_IF_ROOM; + } + + public boolean requiresActionButton() { + return (mShowAsAction & SHOW_AS_ACTION_ALWAYS) == SHOW_AS_ACTION_ALWAYS; + } + + public void setIsActionButton(boolean isActionButton) { + if (isActionButton) { + mFlags |= IS_ACTION; + } else { + mFlags &= ~IS_ACTION; + } + } + + public boolean showsTextAsAction() { + return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT; + } + + public void setShowAsAction(int actionEnum) { + switch (actionEnum & SHOW_AS_ACTION_MASK) { + case SHOW_AS_ACTION_ALWAYS: + case SHOW_AS_ACTION_IF_ROOM: + case SHOW_AS_ACTION_NEVER: + // Looks good! + break; + + default: + // Mutually exclusive options selected! + throw new IllegalArgumentException("SHOW_AS_ACTION_ALWAYS, SHOW_AS_ACTION_IF_ROOM," + + " and SHOW_AS_ACTION_NEVER are mutually exclusive."); + } + mShowAsAction = actionEnum; + mMenu.onItemActionRequestChanged(this); + } + + public MenuItem setActionView(View view) { + mActionView = view; + mActionProvider = null; + if (view != null && view.getId() == View.NO_ID && mId > 0) { + view.setId(mId); + } + mMenu.onItemActionRequestChanged(this); + return this; + } + + public MenuItem setActionView(int resId) { + final Context context = mMenu.getContext(); + final LayoutInflater inflater = LayoutInflater.from(context); + setActionView(inflater.inflate(resId, new LinearLayout(context), false)); + return this; + } + + public View getActionView() { + if (mActionView != null) { + return mActionView; + } else if (mActionProvider != null) { + mActionView = mActionProvider.onCreateActionView(); + return mActionView; + } else { + return null; + } + } + + public ActionProvider getActionProvider() { + return mActionProvider; + } + + public MenuItem setActionProvider(ActionProvider actionProvider) { + mActionView = null; + mActionProvider = actionProvider; + mMenu.onItemsChanged(true); // Measurement can be changed + return this; + } + + @Override + public MenuItem setShowAsActionFlags(int actionEnum) { + setShowAsAction(actionEnum); + return this; + } + + @Override + public boolean expandActionView() { + if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0 || mActionView == null) { + return false; + } + + if (mOnActionExpandListener == null || + mOnActionExpandListener.onMenuItemActionExpand(this)) { + return mMenu.expandItemActionView(this); + } + + return false; + } + + @Override + public boolean collapseActionView() { + if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0) { + return false; + } + if (mActionView == null) { + // We're already collapsed if we have no action view. + return true; + } + + if (mOnActionExpandListener == null || + mOnActionExpandListener.onMenuItemActionCollapse(this)) { + return mMenu.collapseItemActionView(this); + } + + return false; + } + + @Override + public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { + mOnActionExpandListener = listener; + return this; + } + + public boolean hasCollapsibleActionView() { + return (mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) != 0 && mActionView != null; + } + + public void setActionViewExpanded(boolean isExpanded) { + mIsActionViewExpanded = isExpanded; + mMenu.onItemsChanged(false); + } + + public boolean isActionViewExpanded() { + return mIsActionViewExpanded; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java new file mode 100644 index 0000000000..aaf2997b74 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java @@ -0,0 +1,310 @@ +package com.actionbarsherlock.internal.view.menu; + +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.View; +import com.actionbarsherlock.internal.view.ActionProviderWrapper; +import com.actionbarsherlock.internal.widget.CollapsibleActionViewWrapper; +import com.actionbarsherlock.view.ActionProvider; +import com.actionbarsherlock.view.CollapsibleActionView; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +public class MenuItemWrapper implements MenuItem, android.view.MenuItem.OnMenuItemClickListener { + private final android.view.MenuItem mNativeItem; + private SubMenu mSubMenu = null; + private OnMenuItemClickListener mMenuItemClickListener = null; + private OnActionExpandListener mActionExpandListener = null; + private android.view.MenuItem.OnActionExpandListener mNativeActionExpandListener = null; + + + public MenuItemWrapper(android.view.MenuItem nativeItem) { + if (nativeItem == null) { + throw new IllegalStateException("Wrapped menu item cannot be null."); + } + mNativeItem = nativeItem; + } + + + @Override + public int getItemId() { + return mNativeItem.getItemId(); + } + + @Override + public int getGroupId() { + return mNativeItem.getGroupId(); + } + + @Override + public int getOrder() { + return mNativeItem.getOrder(); + } + + @Override + public MenuItem setTitle(CharSequence title) { + mNativeItem.setTitle(title); + return this; + } + + @Override + public MenuItem setTitle(int title) { + mNativeItem.setTitle(title); + return this; + } + + @Override + public CharSequence getTitle() { + return mNativeItem.getTitle(); + } + + @Override + public MenuItem setTitleCondensed(CharSequence title) { + mNativeItem.setTitleCondensed(title); + return this; + } + + @Override + public CharSequence getTitleCondensed() { + return mNativeItem.getTitleCondensed(); + } + + @Override + public MenuItem setIcon(Drawable icon) { + mNativeItem.setIcon(icon); + return this; + } + + @Override + public MenuItem setIcon(int iconRes) { + mNativeItem.setIcon(iconRes); + return this; + } + + @Override + public Drawable getIcon() { + return mNativeItem.getIcon(); + } + + @Override + public MenuItem setIntent(Intent intent) { + mNativeItem.setIntent(intent); + return this; + } + + @Override + public Intent getIntent() { + return mNativeItem.getIntent(); + } + + @Override + public MenuItem setShortcut(char numericChar, char alphaChar) { + mNativeItem.setShortcut(numericChar, alphaChar); + return this; + } + + @Override + public MenuItem setNumericShortcut(char numericChar) { + mNativeItem.setNumericShortcut(numericChar); + return this; + } + + @Override + public char getNumericShortcut() { + return mNativeItem.getNumericShortcut(); + } + + @Override + public MenuItem setAlphabeticShortcut(char alphaChar) { + mNativeItem.setAlphabeticShortcut(alphaChar); + return this; + } + + @Override + public char getAlphabeticShortcut() { + return mNativeItem.getAlphabeticShortcut(); + } + + @Override + public MenuItem setCheckable(boolean checkable) { + mNativeItem.setCheckable(checkable); + return this; + } + + @Override + public boolean isCheckable() { + return mNativeItem.isCheckable(); + } + + @Override + public MenuItem setChecked(boolean checked) { + mNativeItem.setChecked(checked); + return this; + } + + @Override + public boolean isChecked() { + return mNativeItem.isChecked(); + } + + @Override + public MenuItem setVisible(boolean visible) { + mNativeItem.setVisible(visible); + return this; + } + + @Override + public boolean isVisible() { + return mNativeItem.isVisible(); + } + + @Override + public MenuItem setEnabled(boolean enabled) { + mNativeItem.setEnabled(enabled); + return this; + } + + @Override + public boolean isEnabled() { + return mNativeItem.isEnabled(); + } + + @Override + public boolean hasSubMenu() { + return mNativeItem.hasSubMenu(); + } + + @Override + public SubMenu getSubMenu() { + if (hasSubMenu() && (mSubMenu == null)) { + mSubMenu = new SubMenuWrapper(mNativeItem.getSubMenu()); + } + return mSubMenu; + } + + @Override + public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { + mMenuItemClickListener = menuItemClickListener; + //Register ourselves as the listener to proxy + mNativeItem.setOnMenuItemClickListener(this); + return this; + } + + @Override + public boolean onMenuItemClick(android.view.MenuItem item) { + if (mMenuItemClickListener != null) { + return mMenuItemClickListener.onMenuItemClick(this); + } + return false; + } + + @Override + public ContextMenuInfo getMenuInfo() { + return mNativeItem.getMenuInfo(); + } + + @Override + public void setShowAsAction(int actionEnum) { + mNativeItem.setShowAsAction(actionEnum); + } + + @Override + public MenuItem setShowAsActionFlags(int actionEnum) { + mNativeItem.setShowAsActionFlags(actionEnum); + return this; + } + + @Override + public MenuItem setActionView(View view) { + if (view != null && view instanceof CollapsibleActionView) { + view = new CollapsibleActionViewWrapper(view); + } + mNativeItem.setActionView(view); + return this; + } + + @Override + public MenuItem setActionView(int resId) { + //Allow the native menu to inflate the resource + mNativeItem.setActionView(resId); + if (resId != 0) { + //Get newly created view + View view = mNativeItem.getActionView(); + if (view instanceof CollapsibleActionView) { + //Wrap it and re-set it + mNativeItem.setActionView(new CollapsibleActionViewWrapper(view)); + } + } + return this; + } + + @Override + public View getActionView() { + View actionView = mNativeItem.getActionView(); + if (actionView instanceof CollapsibleActionViewWrapper) { + return ((CollapsibleActionViewWrapper)actionView).unwrap(); + } + return actionView; + } + + @Override + public MenuItem setActionProvider(ActionProvider actionProvider) { + mNativeItem.setActionProvider(new ActionProviderWrapper(actionProvider)); + return this; + } + + @Override + public ActionProvider getActionProvider() { + android.view.ActionProvider nativeProvider = mNativeItem.getActionProvider(); + if (nativeProvider != null && nativeProvider instanceof ActionProviderWrapper) { + return ((ActionProviderWrapper)nativeProvider).unwrap(); + } + return null; + } + + @Override + public boolean expandActionView() { + return mNativeItem.expandActionView(); + } + + @Override + public boolean collapseActionView() { + return mNativeItem.collapseActionView(); + } + + @Override + public boolean isActionViewExpanded() { + return mNativeItem.isActionViewExpanded(); + } + + @Override + public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { + mActionExpandListener = listener; + + if (mNativeActionExpandListener == null) { + mNativeActionExpandListener = new android.view.MenuItem.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(android.view.MenuItem menuItem) { + if (mActionExpandListener != null) { + return mActionExpandListener.onMenuItemActionExpand(MenuItemWrapper.this); + } + return false; + } + + @Override + public boolean onMenuItemActionCollapse(android.view.MenuItem menuItem) { + if (mActionExpandListener != null) { + return mActionExpandListener.onMenuItemActionCollapse(MenuItemWrapper.this); + } + return false; + } + }; + + //Register our inner-class as the listener to proxy method calls + mNativeItem.setOnActionExpandListener(mNativeActionExpandListener); + } + + return this; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java new file mode 100644 index 0000000000..f030de310a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import java.util.ArrayList; +import android.content.Context; +import android.content.res.Resources; +import android.database.DataSetObserver; +import android.os.Parcelable; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.FrameLayout; +import android.widget.ListAdapter; +import android.widget.PopupWindow; +import com.actionbarsherlock.R; +import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; +import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; +import com.actionbarsherlock.internal.widget.IcsListPopupWindow; +import com.actionbarsherlock.view.MenuItem; + +/** + * Presents a menu as a small, simple popup anchored to another view. + * @hide + */ +public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener, + ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener, + View_OnAttachStateChangeListener, MenuPresenter { + //UNUSED private static final String TAG = "MenuPopupHelper"; + + static final int ITEM_LAYOUT = R.layout.abs__popup_menu_item_layout; + + private Context mContext; + private LayoutInflater mInflater; + private IcsListPopupWindow mPopup; + private MenuBuilder mMenu; + private int mPopupMaxWidth; + private View mAnchorView; + private boolean mOverflowOnly; + private ViewTreeObserver mTreeObserver; + + private MenuAdapter mAdapter; + + private Callback mPresenterCallback; + + boolean mForceShowIcon; + + private ViewGroup mMeasureParent; + + public MenuPopupHelper(Context context, MenuBuilder menu) { + this(context, menu, null, false); + } + + public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView) { + this(context, menu, anchorView, false); + } + + public MenuPopupHelper(Context context, MenuBuilder menu, + View anchorView, boolean overflowOnly) { + mContext = context; + mInflater = LayoutInflater.from(context); + mMenu = menu; + mOverflowOnly = overflowOnly; + + final Resources res = context.getResources(); + mPopupMaxWidth = Math.max(res.getDisplayMetrics().widthPixels / 2, + res.getDimensionPixelSize(R.dimen.abs__config_prefDialogWidth)); + + mAnchorView = anchorView; + + menu.addMenuPresenter(this); + } + + public void setAnchorView(View anchor) { + mAnchorView = anchor; + } + + public void setForceShowIcon(boolean forceShow) { + mForceShowIcon = forceShow; + } + + public void show() { + if (!tryShow()) { + throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor"); + } + } + + public boolean tryShow() { + mPopup = new IcsListPopupWindow(mContext, null, R.attr.popupMenuStyle); + mPopup.setOnDismissListener(this); + mPopup.setOnItemClickListener(this); + + mAdapter = new MenuAdapter(mMenu); + mPopup.setAdapter(mAdapter); + mPopup.setModal(true); + + View anchor = mAnchorView; + if (anchor != null) { + final boolean addGlobalListener = mTreeObserver == null; + mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest + if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this); + ((View_HasStateListenerSupport)anchor).addOnAttachStateChangeListener(this); + mPopup.setAnchorView(anchor); + } else { + return false; + } + + mPopup.setContentWidth(Math.min(measureContentWidth(mAdapter), mPopupMaxWidth)); + mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); + mPopup.show(); + mPopup.getListView().setOnKeyListener(this); + return true; + } + + public void dismiss() { + if (isShowing()) { + mPopup.dismiss(); + } + } + + public void onDismiss() { + mPopup = null; + mMenu.close(); + if (mTreeObserver != null) { + if (!mTreeObserver.isAlive()) mTreeObserver = mAnchorView.getViewTreeObserver(); + mTreeObserver.removeGlobalOnLayoutListener(this); + mTreeObserver = null; + } + ((View_HasStateListenerSupport)mAnchorView).removeOnAttachStateChangeListener(this); + } + + public boolean isShowing() { + return mPopup != null && mPopup.isShowing(); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + MenuAdapter adapter = mAdapter; + adapter.mAdapterMenu.performItemAction(adapter.getItem(position), 0); + } + + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MENU) { + dismiss(); + return true; + } + return false; + } + + private int measureContentWidth(ListAdapter adapter) { + // Menus don't tend to be long, so this is more sane than it looks. + int width = 0; + View itemView = null; + int itemType = 0; + final int widthMeasureSpec = + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final int heightMeasureSpec = + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final int count = adapter.getCount(); + for (int i = 0; i < count; i++) { + final int positionType = adapter.getItemViewType(i); + if (positionType != itemType) { + itemType = positionType; + itemView = null; + } + if (mMeasureParent == null) { + mMeasureParent = new FrameLayout(mContext); + } + itemView = adapter.getView(i, itemView, mMeasureParent); + itemView.measure(widthMeasureSpec, heightMeasureSpec); + width = Math.max(width, itemView.getMeasuredWidth()); + } + return width; + } + + @Override + public void onGlobalLayout() { + if (isShowing()) { + final View anchor = mAnchorView; + if (anchor == null || !anchor.isShown()) { + dismiss(); + } else if (isShowing()) { + // Recompute window size and position + mPopup.show(); + } + } + } + + @Override + public void onViewAttachedToWindow(View v) { + } + + @Override + public void onViewDetachedFromWindow(View v) { + if (mTreeObserver != null) { + if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver(); + mTreeObserver.removeGlobalOnLayoutListener(this); + } + ((View_HasStateListenerSupport)v).removeOnAttachStateChangeListener(this); + } + + @Override + public void initForMenu(Context context, MenuBuilder menu) { + // Don't need to do anything; we added as a presenter in the constructor. + } + + @Override + public MenuView getMenuView(ViewGroup root) { + throw new UnsupportedOperationException("MenuPopupHelpers manage their own views"); + } + + @Override + public void updateMenuView(boolean cleared) { + if (mAdapter != null) mAdapter.notifyDataSetChanged(); + } + + @Override + public void setCallback(Callback cb) { + mPresenterCallback = cb; + } + + @Override + public boolean onSubMenuSelected(SubMenuBuilder subMenu) { + if (subMenu.hasVisibleItems()) { + MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu, mAnchorView, false); + subPopup.setCallback(mPresenterCallback); + + boolean preserveIconSpacing = false; + final int count = subMenu.size(); + for (int i = 0; i < count; i++) { + MenuItem childItem = subMenu.getItem(i); + if (childItem.isVisible() && childItem.getIcon() != null) { + preserveIconSpacing = true; + break; + } + } + subPopup.setForceShowIcon(preserveIconSpacing); + + if (subPopup.tryShow()) { + if (mPresenterCallback != null) { + mPresenterCallback.onOpenSubMenu(subMenu); + } + return true; + } + } + return false; + } + + @Override + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + // Only care about the (sub)menu we're presenting. + if (menu != mMenu) return; + + dismiss(); + if (mPresenterCallback != null) { + mPresenterCallback.onCloseMenu(menu, allMenusAreClosing); + } + } + + @Override + public boolean flagActionItems() { + return false; + } + + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + + @Override + public int getId() { + return 0; + } + + @Override + public Parcelable onSaveInstanceState() { + return null; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + } + + private class MenuAdapter extends BaseAdapter { + private MenuBuilder mAdapterMenu; + private int mExpandedIndex = -1; + + public MenuAdapter(MenuBuilder menu) { + mAdapterMenu = menu; + registerDataSetObserver(new ExpandedIndexObserver()); + findExpandedIndex(); + } + + public int getCount() { + ArrayList items = mOverflowOnly ? + mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); + if (mExpandedIndex < 0) { + return items.size(); + } + return items.size() - 1; + } + + public MenuItemImpl getItem(int position) { + ArrayList items = mOverflowOnly ? + mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); + if (mExpandedIndex >= 0 && position >= mExpandedIndex) { + position++; + } + return items.get(position); + } + + public long getItemId(int position) { + // Since a menu item's ID is optional, we'll use the position as an + // ID for the item in the AdapterView + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = mInflater.inflate(ITEM_LAYOUT, parent, false); + } + + MenuView.ItemView itemView = (MenuView.ItemView) convertView; + if (mForceShowIcon) { + ((ListMenuItemView) convertView).setForceShowIcon(true); + } + itemView.initialize(getItem(position), 0); + return convertView; + } + + void findExpandedIndex() { + final MenuItemImpl expandedItem = mMenu.getExpandedItem(); + if (expandedItem != null) { + final ArrayList items = mMenu.getNonActionItems(); + final int count = items.size(); + for (int i = 0; i < count; i++) { + final MenuItemImpl item = items.get(i); + if (item == expandedItem) { + mExpandedIndex = i; + return; + } + } + } + mExpandedIndex = -1; + } + } + + private class ExpandedIndexObserver extends DataSetObserver { + @Override + public void onChanged() { + mAdapter.findExpandedIndex(); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java new file mode 100644 index 0000000000..9fa9875e7e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import android.content.Context; +import android.os.Parcelable; +import android.view.ViewGroup; + +/** + * A MenuPresenter is responsible for building views for a Menu object. + * It takes over some responsibility from the old style monolithic MenuBuilder class. + */ +public interface MenuPresenter { + /** + * Called by menu implementation to notify another component of open/close events. + */ + public interface Callback { + /** + * Called when a menu is closing. + * @param menu + * @param allMenusAreClosing + */ + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing); + + /** + * Called when a submenu opens. Useful for notifying the application + * of menu state so that it does not attempt to hide the action bar + * while a submenu is open or similar. + * + * @param subMenu Submenu currently being opened + * @return true if the Callback will handle presenting the submenu, false if + * the presenter should attempt to do so. + */ + public boolean onOpenSubMenu(MenuBuilder subMenu); + } + + /** + * Initialize this presenter for the given context and menu. + * This method is called by MenuBuilder when a presenter is + * added. See {@link MenuBuilder#addMenuPresenter(com.actionbarsherlock.internal.view.menu.MenuPresenter)} + * + * @param context Context for this presenter; used for view creation and resource management + * @param menu Menu to host + */ + public void initForMenu(Context context, MenuBuilder menu); + + /** + * Retrieve a MenuView to display the menu specified in + * {@link #initForMenu(Context, Menu)}. + * + * @param root Intended parent of the MenuView. + * @return A freshly created MenuView. + */ + public MenuView getMenuView(ViewGroup root); + + /** + * Update the menu UI in response to a change. Called by + * MenuBuilder during the normal course of operation. + * + * @param cleared true if the menu was entirely cleared + */ + public void updateMenuView(boolean cleared); + + /** + * Set a callback object that will be notified of menu events + * related to this specific presentation. + * @param cb Callback that will be notified of future events + */ + public void setCallback(Callback cb); + + /** + * Called by Menu implementations to indicate that a submenu item + * has been selected. An active Callback should be notified, and + * if applicable the presenter should present the submenu. + * + * @param subMenu SubMenu being opened + * @return true if the the event was handled, false otherwise. + */ + public boolean onSubMenuSelected(SubMenuBuilder subMenu); + + /** + * Called by Menu implementations to indicate that a menu or submenu is + * closing. Presenter implementations should close the representation + * of the menu indicated as necessary and notify a registered callback. + * + * @param menu Menu or submenu that is closing. + * @param allMenusAreClosing True if all associated menus are closing. + */ + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing); + + /** + * Called by Menu implementations to flag items that will be shown as actions. + * @return true if this presenter changed the action status of any items. + */ + public boolean flagActionItems(); + + /** + * Called when a menu item with a collapsable action view should expand its action view. + * + * @param menu Menu containing the item to be expanded + * @param item Item to be expanded + * @return true if this presenter expanded the action view, false otherwise. + */ + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item); + + /** + * Called when a menu item with a collapsable action view should collapse its action view. + * + * @param menu Menu containing the item to be collapsed + * @param item Item to be collapsed + * @return true if this presenter collapsed the action view, false otherwise. + */ + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item); + + /** + * Returns an ID for determining how to save/restore instance state. + * @return a valid ID value. + */ + public int getId(); + + /** + * Returns a Parcelable describing the current state of the presenter. + * It will be passed to the {@link #onRestoreInstanceState(Parcelable)} + * method of the presenter sharing the same ID later. + * @return The saved instance state + */ + public Parcelable onSaveInstanceState(); + + /** + * Supplies the previously saved instance state to be restored. + * @param state The previously saved instance state + */ + public void onRestoreInstanceState(Parcelable state); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuView.java new file mode 100644 index 0000000000..323ba2d88d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuView.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import android.graphics.drawable.Drawable; + +/** + * Minimal interface for a menu view. {@link #initialize(MenuBuilder)} must be called for the + * menu to be functional. + * + * @hide + */ +public interface MenuView { + /** + * Initializes the menu to the given menu. This should be called after the + * view is inflated. + * + * @param menu The menu that this MenuView should display. + */ + public void initialize(MenuBuilder menu); + + /** + * Returns the default animations to be used for this menu when entering/exiting. + * @return A resource ID for the default animations to be used for this menu. + */ + public int getWindowAnimations(); + + /** + * Minimal interface for a menu item view. {@link #initialize(MenuItemImpl, int)} must be called + * for the item to be functional. + */ + public interface ItemView { + /** + * Initializes with the provided MenuItemData. This should be called after the view is + * inflated. + * @param itemData The item that this ItemView should display. + * @param menuType The type of this menu, one of + * {@link MenuBuilder#TYPE_ICON}, {@link MenuBuilder#TYPE_EXPANDED}, + * {@link MenuBuilder#TYPE_DIALOG}). + */ + public void initialize(MenuItemImpl itemData, int menuType); + + /** + * Gets the item data that this view is displaying. + * @return the item data, or null if there is not one + */ + public MenuItemImpl getItemData(); + + /** + * Sets the title of the item view. + * @param title The title to set. + */ + public void setTitle(CharSequence title); + + /** + * Sets the enabled state of the item view. + * @param enabled Whether the item view should be enabled. + */ + public void setEnabled(boolean enabled); + + /** + * Displays the checkbox for the item view. This does not ensure the item view will be + * checked, for that use {@link #setChecked}. + * @param checkable Whether to display the checkbox or to hide it + */ + public void setCheckable(boolean checkable); + + /** + * Checks the checkbox for the item view. If the checkbox is hidden, it will NOT be + * made visible, call {@link #setCheckable(boolean)} for that. + * @param checked Whether the checkbox should be checked + */ + public void setChecked(boolean checked); + + /** + * Sets the shortcut for the item. + * @param showShortcut Whether a shortcut should be shown(if false, the value of + * shortcutKey should be ignored). + * @param shortcutKey The shortcut key that should be shown on the ItemView. + */ + public void setShortcut(boolean showShortcut, char shortcutKey); + + /** + * Set the icon of this item view. + * @param icon The icon of this item. null to hide the icon. + */ + public void setIcon(Drawable icon); + + /** + * Whether this item view prefers displaying the condensed title rather + * than the normal title. If a condensed title is not available, the + * normal title will be used. + * + * @return Whether this item view prefers displaying the condensed + * title. + */ + public boolean prefersCondensedTitle(); + + /** + * Whether this item view shows an icon. + * + * @return Whether this item view shows an icon. + */ + public boolean showsIcon(); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java new file mode 100644 index 0000000000..3d4dd42fda --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java @@ -0,0 +1,185 @@ +package com.actionbarsherlock.internal.view.menu; + +import java.util.WeakHashMap; +import android.content.ComponentName; +import android.content.Intent; +import android.view.KeyEvent; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +public class MenuWrapper implements Menu { + private final android.view.Menu mNativeMenu; + + private final WeakHashMap mNativeMap = + new WeakHashMap(); + + + public MenuWrapper(android.view.Menu nativeMenu) { + mNativeMenu = nativeMenu; + } + + public android.view.Menu unwrap() { + return mNativeMenu; + } + + private MenuItem addInternal(android.view.MenuItem nativeItem) { + MenuItem item = new MenuItemWrapper(nativeItem); + mNativeMap.put(nativeItem, item); + return item; + } + + @Override + public MenuItem add(CharSequence title) { + return addInternal(mNativeMenu.add(title)); + } + + @Override + public MenuItem add(int titleRes) { + return addInternal(mNativeMenu.add(titleRes)); + } + + @Override + public MenuItem add(int groupId, int itemId, int order, CharSequence title) { + return addInternal(mNativeMenu.add(groupId, itemId, order, title)); + } + + @Override + public MenuItem add(int groupId, int itemId, int order, int titleRes) { + return addInternal(mNativeMenu.add(groupId, itemId, order, titleRes)); + } + + private SubMenu addInternal(android.view.SubMenu nativeSubMenu) { + SubMenu subMenu = new SubMenuWrapper(nativeSubMenu); + android.view.MenuItem nativeItem = nativeSubMenu.getItem(); + MenuItem item = subMenu.getItem(); + mNativeMap.put(nativeItem, item); + return subMenu; + } + + @Override + public SubMenu addSubMenu(CharSequence title) { + return addInternal(mNativeMenu.addSubMenu(title)); + } + + @Override + public SubMenu addSubMenu(int titleRes) { + return addInternal(mNativeMenu.addSubMenu(titleRes)); + } + + @Override + public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) { + return addInternal(mNativeMenu.addSubMenu(groupId, itemId, order, title)); + } + + @Override + public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { + return addInternal(mNativeMenu.addSubMenu(groupId, itemId, order, titleRes)); + } + + @Override + public int addIntentOptions(int groupId, int itemId, int order, ComponentName caller, Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) { + int result; + if (outSpecificItems != null) { + android.view.MenuItem[] nativeOutItems = new android.view.MenuItem[outSpecificItems.length]; + result = mNativeMenu.addIntentOptions(groupId, itemId, order, caller, specifics, intent, flags, nativeOutItems); + for (int i = 0, length = outSpecificItems.length; i < length; i++) { + outSpecificItems[i] = new MenuItemWrapper(nativeOutItems[i]); + } + } else { + result = mNativeMenu.addIntentOptions(groupId, itemId, order, caller, specifics, intent, flags, null); + } + return result; + } + + @Override + public void removeItem(int id) { + mNativeMenu.removeItem(id); + } + + @Override + public void removeGroup(int groupId) { + mNativeMenu.removeGroup(groupId); + } + + @Override + public void clear() { + mNativeMap.clear(); + mNativeMenu.clear(); + } + + @Override + public void setGroupCheckable(int group, boolean checkable, boolean exclusive) { + mNativeMenu.setGroupCheckable(group, checkable, exclusive); + } + + @Override + public void setGroupVisible(int group, boolean visible) { + mNativeMenu.setGroupVisible(group, visible); + } + + @Override + public void setGroupEnabled(int group, boolean enabled) { + mNativeMenu.setGroupEnabled(group, enabled); + } + + @Override + public boolean hasVisibleItems() { + return mNativeMenu.hasVisibleItems(); + } + + @Override + public MenuItem findItem(int id) { + android.view.MenuItem nativeItem = mNativeMenu.findItem(id); + return findItem(nativeItem); + } + + public MenuItem findItem(android.view.MenuItem nativeItem) { + if (nativeItem == null) { + return null; + } + + MenuItem wrapped = mNativeMap.get(nativeItem); + if (wrapped != null) { + return wrapped; + } + + return addInternal(nativeItem); + } + + @Override + public int size() { + return mNativeMenu.size(); + } + + @Override + public MenuItem getItem(int index) { + android.view.MenuItem nativeItem = mNativeMenu.getItem(index); + return findItem(nativeItem); + } + + @Override + public void close() { + mNativeMenu.close(); + } + + @Override + public boolean performShortcut(int keyCode, KeyEvent event, int flags) { + return mNativeMenu.performShortcut(keyCode, event, flags); + } + + @Override + public boolean isShortcutKey(int keyCode, KeyEvent event) { + return mNativeMenu.isShortcutKey(keyCode, event); + } + + @Override + public boolean performIdentifierAction(int id, int flags) { + return mNativeMenu.performIdentifierAction(id, flags); + } + + @Override + public void setQwertyMode(boolean isQwerty) { + mNativeMenu.setQwertyMode(isQwerty); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java new file mode 100644 index 0000000000..6679cf3860 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.view.menu; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.View; + +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +/** + * The model for a sub menu, which is an extension of the menu. Most methods are proxied to + * the parent menu. + */ +public class SubMenuBuilder extends MenuBuilder implements SubMenu { + private MenuBuilder mParentMenu; + private MenuItemImpl mItem; + + public SubMenuBuilder(Context context, MenuBuilder parentMenu, MenuItemImpl item) { + super(context); + + mParentMenu = parentMenu; + mItem = item; + } + + @Override + public void setQwertyMode(boolean isQwerty) { + mParentMenu.setQwertyMode(isQwerty); + } + + @Override + public boolean isQwertyMode() { + return mParentMenu.isQwertyMode(); + } + + @Override + public void setShortcutsVisible(boolean shortcutsVisible) { + mParentMenu.setShortcutsVisible(shortcutsVisible); + } + + @Override + public boolean isShortcutsVisible() { + return mParentMenu.isShortcutsVisible(); + } + + public Menu getParentMenu() { + return mParentMenu; + } + + public MenuItem getItem() { + return mItem; + } + + @Override + public void setCallback(Callback callback) { + mParentMenu.setCallback(callback); + } + + @Override + public MenuBuilder getRootMenu() { + return mParentMenu; + } + + @Override + boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) { + return super.dispatchMenuItemSelected(menu, item) || + mParentMenu.dispatchMenuItemSelected(menu, item); + } + + public SubMenu setIcon(Drawable icon) { + mItem.setIcon(icon); + return this; + } + + public SubMenu setIcon(int iconRes) { + mItem.setIcon(iconRes); + return this; + } + + public SubMenu setHeaderIcon(Drawable icon) { + return (SubMenu) super.setHeaderIconInt(icon); + } + + public SubMenu setHeaderIcon(int iconRes) { + return (SubMenu) super.setHeaderIconInt(iconRes); + } + + public SubMenu setHeaderTitle(CharSequence title) { + return (SubMenu) super.setHeaderTitleInt(title); + } + + public SubMenu setHeaderTitle(int titleRes) { + return (SubMenu) super.setHeaderTitleInt(titleRes); + } + + public SubMenu setHeaderView(View view) { + return (SubMenu) super.setHeaderViewInt(view); + } + + @Override + public boolean expandItemActionView(MenuItemImpl item) { + return mParentMenu.expandItemActionView(item); + } + + @Override + public boolean collapseItemActionView(MenuItemImpl item) { + return mParentMenu.collapseItemActionView(item); + } + + @Override + public String getActionViewStatesKey() { + final int itemId = mItem != null ? mItem.getItemId() : 0; + if (itemId == 0) { + return null; + } + return super.getActionViewStatesKey() + ":" + itemId; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java new file mode 100644 index 0000000000..7d307acb10 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java @@ -0,0 +1,72 @@ +package com.actionbarsherlock.internal.view.menu; + +import android.graphics.drawable.Drawable; +import android.view.View; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.SubMenu; + +public class SubMenuWrapper extends MenuWrapper implements SubMenu { + private final android.view.SubMenu mNativeSubMenu; + private MenuItem mItem = null; + + public SubMenuWrapper(android.view.SubMenu nativeSubMenu) { + super(nativeSubMenu); + mNativeSubMenu = nativeSubMenu; + } + + + @Override + public SubMenu setHeaderTitle(int titleRes) { + mNativeSubMenu.setHeaderTitle(titleRes); + return this; + } + + @Override + public SubMenu setHeaderTitle(CharSequence title) { + mNativeSubMenu.setHeaderTitle(title); + return this; + } + + @Override + public SubMenu setHeaderIcon(int iconRes) { + mNativeSubMenu.setHeaderIcon(iconRes); + return this; + } + + @Override + public SubMenu setHeaderIcon(Drawable icon) { + mNativeSubMenu.setHeaderIcon(icon); + return this; + } + + @Override + public SubMenu setHeaderView(View view) { + mNativeSubMenu.setHeaderView(view); + return this; + } + + @Override + public void clearHeader() { + mNativeSubMenu.clearHeader(); + } + + @Override + public SubMenu setIcon(int iconRes) { + mNativeSubMenu.setIcon(iconRes); + return this; + } + + @Override + public SubMenu setIcon(Drawable icon) { + mNativeSubMenu.setIcon(icon); + return this; + } + + @Override + public MenuItem getItem() { + if (mItem == null) { + mItem = new MenuItemWrapper(mNativeSubMenu.getItem()); + } + return mItem; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java new file mode 100644 index 0000000000..3a4a446756 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.os.Build; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; +import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; +import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; +import com.actionbarsherlock.internal.nineoldandroids.view.NineViewGroup; +import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; +import com.actionbarsherlock.internal.view.menu.ActionMenuView; + +import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; + +public abstract class AbsActionBarView extends NineViewGroup { + protected ActionMenuView mMenuView; + protected ActionMenuPresenter mActionMenuPresenter; + protected ActionBarContainer mSplitView; + protected boolean mSplitActionBar; + protected boolean mSplitWhenNarrow; + protected int mContentHeight; + + final Context mContext; + + protected Animator mVisibilityAnim; + protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); + + private static final /*Time*/Interpolator sAlphaInterpolator = new DecelerateInterpolator(); + + private static final int FADE_DURATION = 200; + + public AbsActionBarView(Context context) { + super(context); + mContext = context; + } + + public AbsActionBarView(Context context, AttributeSet attrs) { + super(context, attrs); + mContext = context; + } + + public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mContext = context; + } + + /* + * Must be public so we can dispatch pre-2.2 via ActionBarImpl. + */ + @Override + public void onConfigurationChanged(Configuration newConfig) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { + super.onConfigurationChanged(newConfig); + } else if (mMenuView != null) { + mMenuView.onConfigurationChanged(newConfig); + } + + // Action bar can change size on configuration changes. + // Reread the desired height from the theme-specified style. + TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, + R.attr.actionBarStyle, 0); + setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); + a.recycle(); + if (mSplitWhenNarrow) { + setSplitActionBar(getResources_getBoolean(getContext(), + R.bool.abs__split_action_bar_is_narrow)); + } + if (mActionMenuPresenter != null) { + mActionMenuPresenter.onConfigurationChanged(newConfig); + } + } + + /** + * Sets whether the bar should be split right now, no questions asked. + * @param split true if the bar should split + */ + public void setSplitActionBar(boolean split) { + mSplitActionBar = split; + } + + /** + * Sets whether the bar should split if we enter a narrow screen configuration. + * @param splitWhenNarrow true if the bar should check to split after a config change + */ + public void setSplitWhenNarrow(boolean splitWhenNarrow) { + mSplitWhenNarrow = splitWhenNarrow; + } + + public void setContentHeight(int height) { + mContentHeight = height; + requestLayout(); + } + + public int getContentHeight() { + return mContentHeight; + } + + public void setSplitView(ActionBarContainer splitView) { + mSplitView = splitView; + } + + /** + * @return Current visibility or if animating, the visibility being animated to. + */ + public int getAnimatedVisibility() { + if (mVisibilityAnim != null) { + return mVisAnimListener.mFinalVisibility; + } + return getVisibility(); + } + + public void animateToVisibility(int visibility) { + if (mVisibilityAnim != null) { + mVisibilityAnim.cancel(); + } + if (visibility == VISIBLE) { + if (getVisibility() != VISIBLE) { + setAlpha(0); + if (mSplitView != null && mMenuView != null) { + mMenuView.setAlpha(0); + } + } + ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1); + anim.setDuration(FADE_DURATION); + anim.setInterpolator(sAlphaInterpolator); + if (mSplitView != null && mMenuView != null) { + AnimatorSet set = new AnimatorSet(); + ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 1); + splitAnim.setDuration(FADE_DURATION); + set.addListener(mVisAnimListener.withFinalVisibility(visibility)); + set.play(anim).with(splitAnim); + set.start(); + } else { + anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); + anim.start(); + } + } else { + ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0); + anim.setDuration(FADE_DURATION); + anim.setInterpolator(sAlphaInterpolator); + if (mSplitView != null && mMenuView != null) { + AnimatorSet set = new AnimatorSet(); + ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 0); + splitAnim.setDuration(FADE_DURATION); + set.addListener(mVisAnimListener.withFinalVisibility(visibility)); + set.play(anim).with(splitAnim); + set.start(); + } else { + anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); + anim.start(); + } + } + } + + @Override + public void setVisibility(int visibility) { + if (mVisibilityAnim != null) { + mVisibilityAnim.end(); + } + super.setVisibility(visibility); + } + + public boolean showOverflowMenu() { + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.showOverflowMenu(); + } + return false; + } + + public void postShowOverflowMenu() { + post(new Runnable() { + public void run() { + showOverflowMenu(); + } + }); + } + + public boolean hideOverflowMenu() { + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.hideOverflowMenu(); + } + return false; + } + + public boolean isOverflowMenuShowing() { + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.isOverflowMenuShowing(); + } + return false; + } + + public boolean isOverflowReserved() { + return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved(); + } + + public void dismissPopupMenus() { + if (mActionMenuPresenter != null) { + mActionMenuPresenter.dismissPopupMenus(); + } + } + + protected int measureChildView(View child, int availableWidth, int childSpecHeight, + int spacing) { + child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), + childSpecHeight); + + availableWidth -= child.getMeasuredWidth(); + availableWidth -= spacing; + + return Math.max(0, availableWidth); + } + + protected int positionChild(View child, int x, int y, int contentHeight) { + int childWidth = child.getMeasuredWidth(); + int childHeight = child.getMeasuredHeight(); + int childTop = y + (contentHeight - childHeight) / 2; + + child.layout(x, childTop, x + childWidth, childTop + childHeight); + + return childWidth; + } + + protected int positionChildInverse(View child, int x, int y, int contentHeight) { + int childWidth = child.getMeasuredWidth(); + int childHeight = child.getMeasuredHeight(); + int childTop = y + (contentHeight - childHeight) / 2; + + child.layout(x - childWidth, childTop, x, childTop + childHeight); + + return childWidth; + } + + protected class VisibilityAnimListener implements Animator.AnimatorListener { + private boolean mCanceled = false; + int mFinalVisibility; + + public VisibilityAnimListener withFinalVisibility(int visibility) { + mFinalVisibility = visibility; + return this; + } + + @Override + public void onAnimationStart(Animator animation) { + setVisibility(VISIBLE); + mVisibilityAnim = animation; + mCanceled = false; + } + + @Override + public void onAnimationEnd(Animator animation) { + if (mCanceled) return; + + mVisibilityAnim = null; + setVisibility(mFinalVisibility); + if (mSplitView != null && mMenuView != null) { + mMenuView.setVisibility(mFinalVisibility); + } + } + + @Override + public void onAnimationCancel(Animator animation) { + mCanceled = true; + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java new file mode 100644 index 0000000000..1d9c68b37d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; + +/** + * This class acts as a container for the action bar view and action mode context views. + * It applies special styles as needed to help handle animated transitions between them. + * @hide + */ +public class ActionBarContainer extends NineFrameLayout { + private boolean mIsTransitioning; + private View mTabContainer; + private ActionBarView mActionBarView; + + private Drawable mBackground; + private Drawable mStackedBackground; + private Drawable mSplitBackground; + private boolean mIsSplit; + private boolean mIsStacked; + + public ActionBarContainer(Context context) { + this(context, null); + } + + public ActionBarContainer(Context context, AttributeSet attrs) { + super(context, attrs); + + setBackgroundDrawable(null); + + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.SherlockActionBar); + mBackground = a.getDrawable(R.styleable.SherlockActionBar_background); + mStackedBackground = a.getDrawable( + R.styleable.SherlockActionBar_backgroundStacked); + + //Fix for issue #379 + if (mStackedBackground instanceof ColorDrawable && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(bitmap); + mStackedBackground.draw(c); + int color = bitmap.getPixel(0, 0); + bitmap.recycle(); + mStackedBackground = new IcsColorDrawable(color); + } + + if (getId() == R.id.abs__split_action_bar) { + mIsSplit = true; + mSplitBackground = a.getDrawable( + R.styleable.SherlockActionBar_backgroundSplit); + } + a.recycle(); + + setWillNotDraw(mIsSplit ? mSplitBackground == null : + mBackground == null && mStackedBackground == null); + } + + @Override + public void onFinishInflate() { + super.onFinishInflate(); + mActionBarView = (ActionBarView) findViewById(R.id.abs__action_bar); + } + + public void setPrimaryBackground(Drawable bg) { + mBackground = bg; + invalidate(); + } + + public void setStackedBackground(Drawable bg) { + mStackedBackground = bg; + invalidate(); + } + + public void setSplitBackground(Drawable bg) { + mSplitBackground = bg; + invalidate(); + } + + /** + * Set the action bar into a "transitioning" state. While transitioning + * the bar will block focus and touch from all of its descendants. This + * prevents the user from interacting with the bar while it is animating + * in or out. + * + * @param isTransitioning true if the bar is currently transitioning, false otherwise. + */ + public void setTransitioning(boolean isTransitioning) { + mIsTransitioning = isTransitioning; + setDescendantFocusability(isTransitioning ? FOCUS_BLOCK_DESCENDANTS + : FOCUS_AFTER_DESCENDANTS); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return mIsTransitioning || super.onInterceptTouchEvent(ev); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + super.onTouchEvent(ev); + + // An action bar always eats touch events. + return true; + } + + @Override + public boolean onHoverEvent(MotionEvent ev) { + super.onHoverEvent(ev); + + // An action bar always eats hover events. + return true; + } + + public void setTabContainer(ScrollingTabContainerView tabView) { + if (mTabContainer != null) { + removeView(mTabContainer); + } + mTabContainer = tabView; + if (tabView != null) { + addView(tabView); + final ViewGroup.LayoutParams lp = tabView.getLayoutParams(); + lp.width = LayoutParams.MATCH_PARENT; + lp.height = LayoutParams.WRAP_CONTENT; + tabView.setAllowCollapse(false); + } + } + + public View getTabContainer() { + return mTabContainer; + } + + @Override + public void onDraw(Canvas canvas) { + if (getWidth() == 0 || getHeight() == 0) { + return; + } + + if (mIsSplit) { + if (mSplitBackground != null) mSplitBackground.draw(canvas); + } else { + if (mBackground != null) { + mBackground.draw(canvas); + } + if (mStackedBackground != null && mIsStacked) { + mStackedBackground.draw(canvas); + } + } + } + + //This causes the animation reflection to fail on pre-HC platforms + //@Override + //public android.view.ActionMode startActionModeForChild(View child, android.view.ActionMode.Callback callback) { + // // No starting an action mode for an action bar child! (Where would it go?) + // return null; + //} + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + if (mActionBarView == null) return; + + final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams(); + final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 : + mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; + + if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { + final int mode = MeasureSpec.getMode(heightMeasureSpec); + if (mode == MeasureSpec.AT_MOST) { + final int maxHeight = MeasureSpec.getSize(heightMeasureSpec); + setMeasuredDimension(getMeasuredWidth(), + Math.min(actionBarViewHeight + mTabContainer.getMeasuredHeight(), + maxHeight)); + } + } + } + + @Override + public void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + + final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE; + + if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { + final int containerHeight = getMeasuredHeight(); + final int tabHeight = mTabContainer.getMeasuredHeight(); + + if ((mActionBarView.getDisplayOptions() & ActionBar.DISPLAY_SHOW_HOME) == 0) { + // Not showing home, put tabs on top. + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + + if (child == mTabContainer) continue; + + if (!mActionBarView.isCollapsed()) { + child.offsetTopAndBottom(tabHeight); + } + } + mTabContainer.layout(l, 0, r, tabHeight); + } else { + mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight); + } + } + + boolean needsInvalidate = false; + if (mIsSplit) { + if (mSplitBackground != null) { + mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); + needsInvalidate = true; + } + } else { + if (mBackground != null) { + mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(), + mActionBarView.getRight(), mActionBarView.getBottom()); + needsInvalidate = true; + } + if ((mIsStacked = hasTabs && mStackedBackground != null)) { + mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(), + mTabContainer.getRight(), mTabContainer.getBottom()); + needsInvalidate = true; + } + } + + if (needsInvalidate) { + invalidate(); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java new file mode 100644 index 0000000000..9ec250f387 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java @@ -0,0 +1,518 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; +import android.view.animation.DecelerateInterpolator; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener; +import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; +import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; +import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; +import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; +import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; +import com.actionbarsherlock.internal.view.menu.ActionMenuView; +import com.actionbarsherlock.internal.view.menu.MenuBuilder; +import com.actionbarsherlock.view.ActionMode; + +/** + * @hide + */ +public class ActionBarContextView extends AbsActionBarView implements AnimatorListener { + //UNUSED private static final String TAG = "ActionBarContextView"; + + private CharSequence mTitle; + private CharSequence mSubtitle; + + private NineLinearLayout mClose; + private View mCustomView; + private LinearLayout mTitleLayout; + private TextView mTitleView; + private TextView mSubtitleView; + private int mTitleStyleRes; + private int mSubtitleStyleRes; + private Drawable mSplitBackground; + + private Animator mCurrentAnimation; + private boolean mAnimateInOnLayout; + private int mAnimationMode; + + private static final int ANIMATE_IDLE = 0; + private static final int ANIMATE_IN = 1; + private static final int ANIMATE_OUT = 2; + + public ActionBarContextView(Context context) { + this(context, null); + } + + public ActionBarContextView(Context context, AttributeSet attrs) { + this(context, attrs, R.attr.actionModeStyle); + } + + public ActionBarContextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockActionMode, defStyle, 0); + setBackgroundDrawable(a.getDrawable( + R.styleable.SherlockActionMode_background)); + mTitleStyleRes = a.getResourceId( + R.styleable.SherlockActionMode_titleTextStyle, 0); + mSubtitleStyleRes = a.getResourceId( + R.styleable.SherlockActionMode_subtitleTextStyle, 0); + + mContentHeight = a.getLayoutDimension( + R.styleable.SherlockActionMode_height, 0); + + mSplitBackground = a.getDrawable( + R.styleable.SherlockActionMode_backgroundSplit); + + a.recycle(); + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mActionMenuPresenter != null) { + mActionMenuPresenter.hideOverflowMenu(); + mActionMenuPresenter.hideSubMenus(); + } + } + + @Override + public void setSplitActionBar(boolean split) { + if (mSplitActionBar != split) { + if (mActionMenuPresenter != null) { + // Mode is already active; move everything over and adjust the menu itself. + final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT); + if (!split) { + mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); + mMenuView.setBackgroundDrawable(null); + final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); + if (oldParent != null) oldParent.removeView(mMenuView); + addView(mMenuView, layoutParams); + } else { + // Allow full screen width in split mode. + mActionMenuPresenter.setWidthLimit( + getContext().getResources().getDisplayMetrics().widthPixels, true); + // No limit to the item count; use whatever will fit. + mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); + // Span the whole width + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = mContentHeight; + mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); + mMenuView.setBackgroundDrawable(mSplitBackground); + final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); + if (oldParent != null) oldParent.removeView(mMenuView); + mSplitView.addView(mMenuView, layoutParams); + } + } + super.setSplitActionBar(split); + } + } + + public void setContentHeight(int height) { + mContentHeight = height; + } + + public void setCustomView(View view) { + if (mCustomView != null) { + removeView(mCustomView); + } + mCustomView = view; + if (mTitleLayout != null) { + removeView(mTitleLayout); + mTitleLayout = null; + } + if (view != null) { + addView(view); + } + requestLayout(); + } + + public void setTitle(CharSequence title) { + mTitle = title; + initTitle(); + } + + public void setSubtitle(CharSequence subtitle) { + mSubtitle = subtitle; + initTitle(); + } + + public CharSequence getTitle() { + return mTitle; + } + + public CharSequence getSubtitle() { + return mSubtitle; + } + + private void initTitle() { + if (mTitleLayout == null) { + LayoutInflater inflater = LayoutInflater.from(getContext()); + inflater.inflate(R.layout.abs__action_bar_title_item, this); + mTitleLayout = (LinearLayout) getChildAt(getChildCount() - 1); + mTitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_title); + mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_subtitle); + if (mTitleStyleRes != 0) { + mTitleView.setTextAppearance(mContext, mTitleStyleRes); + } + if (mSubtitleStyleRes != 0) { + mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); + } + } + + mTitleView.setText(mTitle); + mSubtitleView.setText(mSubtitle); + + final boolean hasTitle = !TextUtils.isEmpty(mTitle); + final boolean hasSubtitle = !TextUtils.isEmpty(mSubtitle); + mSubtitleView.setVisibility(hasSubtitle ? VISIBLE : GONE); + mTitleLayout.setVisibility(hasTitle || hasSubtitle ? VISIBLE : GONE); + if (mTitleLayout.getParent() == null) { + addView(mTitleLayout); + } + } + + public void initForMode(final ActionMode mode) { + if (mClose == null) { + LayoutInflater inflater = LayoutInflater.from(mContext); + mClose = (NineLinearLayout)inflater.inflate(R.layout.abs__action_mode_close_item, this, false); + addView(mClose); + } else if (mClose.getParent() == null) { + addView(mClose); + } + + View closeButton = mClose.findViewById(R.id.abs__action_mode_close_button); + closeButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + mode.finish(); + } + }); + + final MenuBuilder menu = (MenuBuilder) mode.getMenu(); + if (mActionMenuPresenter != null) { + mActionMenuPresenter.dismissPopupMenus(); + } + mActionMenuPresenter = new ActionMenuPresenter(mContext); + mActionMenuPresenter.setReserveOverflow(true); + + final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT); + if (!mSplitActionBar) { + menu.addMenuPresenter(mActionMenuPresenter); + mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); + mMenuView.setBackgroundDrawable(null); + addView(mMenuView, layoutParams); + } else { + // Allow full screen width in split mode. + mActionMenuPresenter.setWidthLimit( + getContext().getResources().getDisplayMetrics().widthPixels, true); + // No limit to the item count; use whatever will fit. + mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); + // Span the whole width + layoutParams.width = LayoutParams.MATCH_PARENT; + layoutParams.height = mContentHeight; + menu.addMenuPresenter(mActionMenuPresenter); + mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); + mMenuView.setBackgroundDrawable(mSplitBackground); + mSplitView.addView(mMenuView, layoutParams); + } + + mAnimateInOnLayout = true; + } + + public void closeMode() { + if (mAnimationMode == ANIMATE_OUT) { + // Called again during close; just finish what we were doing. + return; + } + if (mClose == null) { + killMode(); + return; + } + + finishAnimation(); + mAnimationMode = ANIMATE_OUT; + mCurrentAnimation = makeOutAnimation(); + mCurrentAnimation.start(); + } + + private void finishAnimation() { + final Animator a = mCurrentAnimation; + if (a != null) { + mCurrentAnimation = null; + a.end(); + } + } + + public void killMode() { + finishAnimation(); + removeAllViews(); + if (mSplitView != null) { + mSplitView.removeView(mMenuView); + } + mCustomView = null; + mMenuView = null; + mAnimateInOnLayout = false; + } + + @Override + public boolean showOverflowMenu() { + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.showOverflowMenu(); + } + return false; + } + + @Override + public boolean hideOverflowMenu() { + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.hideOverflowMenu(); + } + return false; + } + + @Override + public boolean isOverflowMenuShowing() { + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.isOverflowMenuShowing(); + } + return false; + } + + @Override + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + // Used by custom views if they don't supply layout params. Everything else + // added to an ActionBarContextView should have them already. + return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); + } + + @Override + public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { + return new MarginLayoutParams(getContext(), attrs); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + if (widthMode != MeasureSpec.EXACTLY) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with android:layout_width=\"match_parent\" (or fill_parent)"); + } + + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + if (heightMode == MeasureSpec.UNSPECIFIED) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with android:layout_height=\"wrap_content\""); + } + + final int contentWidth = MeasureSpec.getSize(widthMeasureSpec); + + int maxHeight = mContentHeight > 0 ? + mContentHeight : MeasureSpec.getSize(heightMeasureSpec); + + final int verticalPadding = getPaddingTop() + getPaddingBottom(); + int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight(); + final int height = maxHeight - verticalPadding; + final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); + + if (mClose != null) { + availableWidth = measureChildView(mClose, availableWidth, childSpecHeight, 0); + MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams(); + availableWidth -= lp.leftMargin + lp.rightMargin; + } + + if (mMenuView != null && mMenuView.getParent() == this) { + availableWidth = measureChildView(mMenuView, availableWidth, + childSpecHeight, 0); + } + + if (mTitleLayout != null && mCustomView == null) { + availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); + } + + if (mCustomView != null) { + ViewGroup.LayoutParams lp = mCustomView.getLayoutParams(); + final int customWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? + MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; + final int customWidth = lp.width >= 0 ? + Math.min(lp.width, availableWidth) : availableWidth; + final int customHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? + MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; + final int customHeight = lp.height >= 0 ? + Math.min(lp.height, height) : height; + mCustomView.measure(MeasureSpec.makeMeasureSpec(customWidth, customWidthMode), + MeasureSpec.makeMeasureSpec(customHeight, customHeightMode)); + } + + if (mContentHeight <= 0) { + int measuredHeight = 0; + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + View v = getChildAt(i); + int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; + if (paddedViewHeight > measuredHeight) { + measuredHeight = paddedViewHeight; + } + } + setMeasuredDimension(contentWidth, measuredHeight); + } else { + setMeasuredDimension(contentWidth, maxHeight); + } + } + + private Animator makeInAnimation() { + mClose.setTranslationX(-mClose.getWidth() - + ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin); + ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX", 0); + buttonAnimator.setDuration(200); + buttonAnimator.addListener(this); + buttonAnimator.setInterpolator(new DecelerateInterpolator()); + + AnimatorSet set = new AnimatorSet(); + AnimatorSet.Builder b = set.play(buttonAnimator); + + if (mMenuView != null) { + final int count = mMenuView.getChildCount(); + if (count > 0) { + for (int i = count - 1, j = 0; i >= 0; i--, j++) { + AnimatorProxy child = AnimatorProxy.wrap(mMenuView.getChildAt(i)); + child.setScaleY(0); + ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0, 1); + a.setDuration(100); + a.setStartDelay(j * 70); + b.with(a); + } + } + } + + return set; + } + + private Animator makeOutAnimation() { + ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX", + -mClose.getWidth() - ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin); + buttonAnimator.setDuration(200); + buttonAnimator.addListener(this); + buttonAnimator.setInterpolator(new DecelerateInterpolator()); + + AnimatorSet set = new AnimatorSet(); + AnimatorSet.Builder b = set.play(buttonAnimator); + + if (mMenuView != null) { + final int count = mMenuView.getChildCount(); + if (count > 0) { + for (int i = 0; i < 0; i++) { + AnimatorProxy child = AnimatorProxy.wrap(mMenuView.getChildAt(i)); + child.setScaleY(0); + ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0); + a.setDuration(100); + a.setStartDelay(i * 70); + b.with(a); + } + } + } + + return set; + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int x = getPaddingLeft(); + final int y = getPaddingTop(); + final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); + + if (mClose != null && mClose.getVisibility() != GONE) { + MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams(); + x += lp.leftMargin; + x += positionChild(mClose, x, y, contentHeight); + x += lp.rightMargin; + + if (mAnimateInOnLayout) { + mAnimationMode = ANIMATE_IN; + mCurrentAnimation = makeInAnimation(); + mCurrentAnimation.start(); + mAnimateInOnLayout = false; + } + } + + if (mTitleLayout != null && mCustomView == null) { + x += positionChild(mTitleLayout, x, y, contentHeight); + } + + if (mCustomView != null) { + x += positionChild(mCustomView, x, y, contentHeight); + } + + x = r - l - getPaddingRight(); + + if (mMenuView != null) { + x -= positionChildInverse(mMenuView, x, y, contentHeight); + } + } + + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + if (mAnimationMode == ANIMATE_OUT) { + killMode(); + } + mAnimationMode = ANIMATE_IDLE; + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public boolean shouldDelayChildPressedState() { + return false; + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { + // Action mode started + //TODO event.setSource(this); + event.setClassName(getClass().getName()); + event.setPackageName(getContext().getPackageName()); + event.setContentDescription(mTitle); + } else { + //TODO super.onInitializeAccessibilityEvent(event); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarView.java new file mode 100644 index 0000000000..4636de17f0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ActionBarView.java @@ -0,0 +1,1548 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.widget; + +import org.xmlpull.v1.XmlPullParser; +import android.app.Activity; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.AssetManager; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.view.accessibility.AccessibilityEvent; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.SpinnerAdapter; +import android.widget.TextView; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.app.ActionBar.OnNavigationListener; +import com.actionbarsherlock.internal.ActionBarSherlockCompat; +import com.actionbarsherlock.internal.view.menu.ActionMenuItem; +import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; +import com.actionbarsherlock.internal.view.menu.ActionMenuView; +import com.actionbarsherlock.internal.view.menu.MenuBuilder; +import com.actionbarsherlock.internal.view.menu.MenuItemImpl; +import com.actionbarsherlock.internal.view.menu.MenuPresenter; +import com.actionbarsherlock.internal.view.menu.MenuView; +import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; +import com.actionbarsherlock.view.CollapsibleActionView; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.Window; + +import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; + +/** + * @hide + */ +public class ActionBarView extends AbsActionBarView { + private static final String TAG = "ActionBarView"; + private static final boolean DEBUG = false; + + /** + * Display options applied by default + */ + public static final int DISPLAY_DEFAULT = 0; + + /** + * Display options that require re-layout as opposed to a simple invalidate + */ + private static final int DISPLAY_RELAYOUT_MASK = + ActionBar.DISPLAY_SHOW_HOME | + ActionBar.DISPLAY_USE_LOGO | + ActionBar.DISPLAY_HOME_AS_UP | + ActionBar.DISPLAY_SHOW_CUSTOM | + ActionBar.DISPLAY_SHOW_TITLE; + + private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL; + + private int mNavigationMode; + private int mDisplayOptions = -1; + private CharSequence mTitle; + private CharSequence mSubtitle; + private Drawable mIcon; + private Drawable mLogo; + + private HomeView mHomeLayout; + private HomeView mExpandedHomeLayout; + private LinearLayout mTitleLayout; + private TextView mTitleView; + private TextView mSubtitleView; + private View mTitleUpView; + + private IcsSpinner mSpinner; + private IcsLinearLayout mListNavLayout; + private ScrollingTabContainerView mTabScrollView; + private View mCustomNavView; + private IcsProgressBar mProgressView; + private IcsProgressBar mIndeterminateProgressView; + + private int mProgressBarPadding; + private int mItemPadding; + + private int mTitleStyleRes; + private int mSubtitleStyleRes; + private int mProgressStyle; + private int mIndeterminateProgressStyle; + + private boolean mUserTitle; + private boolean mIncludeTabs; + private boolean mIsCollapsable; + private boolean mIsCollapsed; + + private MenuBuilder mOptionsMenu; + + private ActionBarContextView mContextView; + + private ActionMenuItem mLogoNavItem; + + private SpinnerAdapter mSpinnerAdapter; + private OnNavigationListener mCallback; + + //UNUSED private Runnable mTabSelector; + + private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; + View mExpandedActionView; + + Window.Callback mWindowCallback; + + @SuppressWarnings("rawtypes") + private final IcsAdapterView.OnItemSelectedListener mNavItemSelectedListener = + new IcsAdapterView.OnItemSelectedListener() { + public void onItemSelected(IcsAdapterView parent, View view, int position, long id) { + if (mCallback != null) { + mCallback.onNavigationItemSelected(position, id); + } + } + public void onNothingSelected(IcsAdapterView parent) { + // Do nothing + } + }; + + private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() { + @Override + public void onClick(View v) { + final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem; + if (item != null) { + item.collapseActionView(); + } + } + }; + + private final OnClickListener mUpClickListener = new OnClickListener() { + public void onClick(View v) { + mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem); + } + }; + + public ActionBarView(Context context, AttributeSet attrs) { + super(context, attrs); + + // Background is always provided by the container. + setBackgroundResource(0); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockActionBar, + R.attr.actionBarStyle, 0); + + ApplicationInfo appInfo = context.getApplicationInfo(); + PackageManager pm = context.getPackageManager(); + mNavigationMode = a.getInt(R.styleable.SherlockActionBar_navigationMode, + ActionBar.NAVIGATION_MODE_STANDARD); + mTitle = a.getText(R.styleable.SherlockActionBar_title); + mSubtitle = a.getText(R.styleable.SherlockActionBar_subtitle); + + mLogo = a.getDrawable(R.styleable.SherlockActionBar_logo); + if (mLogo == null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + if (context instanceof Activity) { + //Even though native methods existed in API 9 and 10 they don't work + //so just parse the manifest to look for the logo pre-Honeycomb + final int resId = loadLogoFromManifest((Activity) context); + if (resId != 0) { + mLogo = context.getResources().getDrawable(resId); + } + } + } else { + if (context instanceof Activity) { + try { + mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); + } catch (NameNotFoundException e) { + Log.e(TAG, "Activity component name not found!", e); + } + } + if (mLogo == null) { + mLogo = appInfo.loadLogo(pm); + } + } + } + + mIcon = a.getDrawable(R.styleable.SherlockActionBar_icon); + if (mIcon == null) { + if (context instanceof Activity) { + try { + mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); + } catch (NameNotFoundException e) { + Log.e(TAG, "Activity component name not found!", e); + } + } + if (mIcon == null) { + mIcon = appInfo.loadIcon(pm); + } + } + + final LayoutInflater inflater = LayoutInflater.from(context); + + final int homeResId = a.getResourceId( + R.styleable.SherlockActionBar_homeLayout, + R.layout.abs__action_bar_home); + + mHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); + + mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); + mExpandedHomeLayout.setUp(true); + mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener); + mExpandedHomeLayout.setContentDescription(getResources().getText( + R.string.abs__action_bar_up_description)); + + mTitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_titleTextStyle, 0); + mSubtitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_subtitleTextStyle, 0); + mProgressStyle = a.getResourceId(R.styleable.SherlockActionBar_progressBarStyle, 0); + mIndeterminateProgressStyle = a.getResourceId( + R.styleable.SherlockActionBar_indeterminateProgressStyle, 0); + + mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_progressBarPadding, 0); + mItemPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_itemPadding, 0); + + setDisplayOptions(a.getInt(R.styleable.SherlockActionBar_displayOptions, DISPLAY_DEFAULT)); + + final int customNavId = a.getResourceId(R.styleable.SherlockActionBar_customNavigationLayout, 0); + if (customNavId != 0) { + mCustomNavView = inflater.inflate(customNavId, this, false); + mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD; + setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM); + } + + mContentHeight = a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0); + + a.recycle(); + + mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle); + mHomeLayout.setOnClickListener(mUpClickListener); + mHomeLayout.setClickable(true); + mHomeLayout.setFocusable(true); + } + + /** + * Attempt to programmatically load the logo from the manifest file of an + * activity by using an XML pull parser. This should allow us to read the + * logo attribute regardless of the platform it is being run on. + * + * @param activity Activity instance. + * @return Logo resource ID. + */ + private static int loadLogoFromManifest(Activity activity) { + int logo = 0; + try { + final String thisPackage = activity.getClass().getName(); + if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); + + final String packageName = activity.getApplicationInfo().packageName; + final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); + final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); + + int eventType = xml.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + String name = xml.getName(); + + if ("application".equals(name)) { + //Check if the has the attribute + if (DEBUG) Log.d(TAG, "Got "); + + for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { + if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); + + if ("logo".equals(xml.getAttributeName(i))) { + logo = xml.getAttributeResourceValue(i, 0); + break; //out of for loop + } + } + } else if ("activity".equals(name)) { + //Check if the is us and has the attribute + if (DEBUG) Log.d(TAG, "Got "); + Integer activityLogo = null; + String activityPackage = null; + boolean isOurActivity = false; + + for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { + if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); + + //We need both uiOptions and name attributes + String attrName = xml.getAttributeName(i); + if ("logo".equals(attrName)) { + activityLogo = xml.getAttributeResourceValue(i, 0); + } else if ("name".equals(attrName)) { + activityPackage = ActionBarSherlockCompat.cleanActivityName(packageName, xml.getAttributeValue(i)); + if (!thisPackage.equals(activityPackage)) { + break; //on to the next + } + isOurActivity = true; + } + + //Make sure we have both attributes before processing + if ((activityLogo != null) && (activityPackage != null)) { + //Our activity, logo specified, override with our value + logo = activityLogo.intValue(); + } + } + if (isOurActivity) { + //If we matched our activity but it had no logo don't + //do any more processing of the manifest + break; + } + } + } + eventType = xml.nextToken(); + } + } catch (Exception e) { + e.printStackTrace(); + } + if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(logo)); + return logo; + } + + /* + * Must be public so we can dispatch pre-2.2 via ActionBarImpl. + */ + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + mTitleView = null; + mSubtitleView = null; + mTitleUpView = null; + if (mTitleLayout != null && mTitleLayout.getParent() == this) { + removeView(mTitleLayout); + } + mTitleLayout = null; + if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + initTitle(); + } + + if (mTabScrollView != null && mIncludeTabs) { + ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); + if (lp != null) { + lp.width = LayoutParams.WRAP_CONTENT; + lp.height = LayoutParams.MATCH_PARENT; + } + mTabScrollView.setAllowCollapse(true); + } + } + + /** + * Set the window callback used to invoke menu items; used for dispatching home button presses. + * @param cb Window callback to dispatch to + */ + public void setWindowCallback(Window.Callback cb) { + mWindowCallback = cb; + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + //UNUSED removeCallbacks(mTabSelector); + if (mActionMenuPresenter != null) { + mActionMenuPresenter.hideOverflowMenu(); + mActionMenuPresenter.hideSubMenus(); + } + } + + @Override + public boolean shouldDelayChildPressedState() { + return false; + } + + public void initProgress() { + mProgressView = new IcsProgressBar(mContext, null, 0, mProgressStyle); + mProgressView.setId(R.id.abs__progress_horizontal); + mProgressView.setMax(10000); + addView(mProgressView); + } + + public void initIndeterminateProgress() { + mIndeterminateProgressView = new IcsProgressBar(mContext, null, 0, mIndeterminateProgressStyle); + mIndeterminateProgressView.setId(R.id.abs__progress_circular); + addView(mIndeterminateProgressView); + } + + @Override + public void setSplitActionBar(boolean splitActionBar) { + if (mSplitActionBar != splitActionBar) { + if (mMenuView != null) { + final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); + if (oldParent != null) { + oldParent.removeView(mMenuView); + } + if (splitActionBar) { + if (mSplitView != null) { + mSplitView.addView(mMenuView); + } + } else { + addView(mMenuView); + } + } + if (mSplitView != null) { + mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE); + } + super.setSplitActionBar(splitActionBar); + } + } + + public boolean isSplitActionBar() { + return mSplitActionBar; + } + + public boolean hasEmbeddedTabs() { + return mIncludeTabs; + } + + public void setEmbeddedTabView(ScrollingTabContainerView tabs) { + if (mTabScrollView != null) { + removeView(mTabScrollView); + } + mTabScrollView = tabs; + mIncludeTabs = tabs != null; + if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { + addView(mTabScrollView); + ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); + lp.width = LayoutParams.WRAP_CONTENT; + lp.height = LayoutParams.MATCH_PARENT; + tabs.setAllowCollapse(true); + } + } + + public void setCallback(OnNavigationListener callback) { + mCallback = callback; + } + + public void setMenu(Menu menu, MenuPresenter.Callback cb) { + if (menu == mOptionsMenu) return; + + if (mOptionsMenu != null) { + mOptionsMenu.removeMenuPresenter(mActionMenuPresenter); + mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter); + } + + MenuBuilder builder = (MenuBuilder) menu; + mOptionsMenu = builder; + if (mMenuView != null) { + final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); + if (oldParent != null) { + oldParent.removeView(mMenuView); + } + } + if (mActionMenuPresenter == null) { + mActionMenuPresenter = new ActionMenuPresenter(mContext); + mActionMenuPresenter.setCallback(cb); + mActionMenuPresenter.setId(R.id.abs__action_menu_presenter); + mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter(); + } + + ActionMenuView menuView; + final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.MATCH_PARENT); + if (!mSplitActionBar) { + mActionMenuPresenter.setExpandedActionViewsExclusive( + getResources_getBoolean(getContext(), + R.bool.abs__action_bar_expanded_action_views_exclusive)); + configPresenters(builder); + menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); + final ViewGroup oldParent = (ViewGroup) menuView.getParent(); + if (oldParent != null && oldParent != this) { + oldParent.removeView(menuView); + } + addView(menuView, layoutParams); + } else { + mActionMenuPresenter.setExpandedActionViewsExclusive(false); + // Allow full screen width in split mode. + mActionMenuPresenter.setWidthLimit( + getContext().getResources().getDisplayMetrics().widthPixels, true); + // No limit to the item count; use whatever will fit. + mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); + // Span the whole width + layoutParams.width = LayoutParams.MATCH_PARENT; + configPresenters(builder); + menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); + if (mSplitView != null) { + final ViewGroup oldParent = (ViewGroup) menuView.getParent(); + if (oldParent != null && oldParent != mSplitView) { + oldParent.removeView(menuView); + } + menuView.setVisibility(getAnimatedVisibility()); + mSplitView.addView(menuView, layoutParams); + } else { + // We'll add this later if we missed it this time. + menuView.setLayoutParams(layoutParams); + } + } + mMenuView = menuView; + } + + private void configPresenters(MenuBuilder builder) { + if (builder != null) { + builder.addMenuPresenter(mActionMenuPresenter); + builder.addMenuPresenter(mExpandedMenuPresenter); + } else { + mActionMenuPresenter.initForMenu(mContext, null); + mExpandedMenuPresenter.initForMenu(mContext, null); + mActionMenuPresenter.updateMenuView(true); + mExpandedMenuPresenter.updateMenuView(true); + } + } + + public boolean hasExpandedActionView() { + return mExpandedMenuPresenter != null && + mExpandedMenuPresenter.mCurrentExpandedItem != null; + } + + public void collapseActionView() { + final MenuItemImpl item = mExpandedMenuPresenter == null ? null : + mExpandedMenuPresenter.mCurrentExpandedItem; + if (item != null) { + item.collapseActionView(); + } + } + + public void setCustomNavigationView(View view) { + final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0; + if (mCustomNavView != null && showCustom) { + removeView(mCustomNavView); + } + mCustomNavView = view; + if (mCustomNavView != null && showCustom) { + addView(mCustomNavView); + } + } + + public CharSequence getTitle() { + return mTitle; + } + + /** + * Set the action bar title. This will always replace or override window titles. + * @param title Title to set + * + * @see #setWindowTitle(CharSequence) + */ + public void setTitle(CharSequence title) { + mUserTitle = true; + setTitleImpl(title); + } + + /** + * Set the window title. A window title will always be replaced or overridden by a user title. + * @param title Title to set + * + * @see #setTitle(CharSequence) + */ + public void setWindowTitle(CharSequence title) { + if (!mUserTitle) { + setTitleImpl(title); + } + } + + private void setTitleImpl(CharSequence title) { + mTitle = title; + if (mTitleView != null) { + mTitleView.setText(title); + final boolean visible = mExpandedActionView == null && + (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && + (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); + mTitleLayout.setVisibility(visible ? VISIBLE : GONE); + } + if (mLogoNavItem != null) { + mLogoNavItem.setTitle(title); + } + } + + public CharSequence getSubtitle() { + return mSubtitle; + } + + public void setSubtitle(CharSequence subtitle) { + mSubtitle = subtitle; + if (mSubtitleView != null) { + mSubtitleView.setText(subtitle); + mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE); + final boolean visible = mExpandedActionView == null && + (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && + (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); + mTitleLayout.setVisibility(visible ? VISIBLE : GONE); + } + } + + public void setHomeButtonEnabled(boolean enable) { + mHomeLayout.setEnabled(enable); + mHomeLayout.setFocusable(enable); + // Make sure the home button has an accurate content description for accessibility. + if (!enable) { + mHomeLayout.setContentDescription(null); + } else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) { + mHomeLayout.setContentDescription(mContext.getResources().getText( + R.string.abs__action_bar_up_description)); + } else { + mHomeLayout.setContentDescription(mContext.getResources().getText( + R.string.abs__action_bar_home_description)); + } + } + + public void setDisplayOptions(int options) { + final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions; + mDisplayOptions = options; + + if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) { + final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0; + final int vis = showHome && mExpandedActionView == null ? VISIBLE : GONE; + mHomeLayout.setVisibility(vis); + + if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) { + final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0; + mHomeLayout.setUp(setUp); + + // Showing home as up implicitly enables interaction with it. + // In honeycomb it was always enabled, so make this transition + // a bit easier for developers in the common case. + // (It would be silly to show it as up without responding to it.) + if (setUp) { + setHomeButtonEnabled(true); + } + } + + if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { + final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0; + mHomeLayout.setIcon(logoVis ? mLogo : mIcon); + } + + if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + initTitle(); + } else { + removeView(mTitleLayout); + } + } + + if (mTitleLayout != null && (flagsChanged & + (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) { + final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; + mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); + mTitleLayout.setEnabled(!showHome && homeAsUp); + } + + if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { + if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { + addView(mCustomNavView); + } else { + removeView(mCustomNavView); + } + } + + requestLayout(); + } else { + invalidate(); + } + + // Make sure the home button has an accurate content description for accessibility. + if (!mHomeLayout.isEnabled()) { + mHomeLayout.setContentDescription(null); + } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) { + mHomeLayout.setContentDescription(mContext.getResources().getText( + R.string.abs__action_bar_up_description)); + } else { + mHomeLayout.setContentDescription(mContext.getResources().getText( + R.string.abs__action_bar_home_description)); + } + } + + public void setIcon(Drawable icon) { + mIcon = icon; + if (icon != null && + ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) { + mHomeLayout.setIcon(icon); + } + } + + public void setIcon(int resId) { + setIcon(mContext.getResources().getDrawable(resId)); + } + + public void setLogo(Drawable logo) { + mLogo = logo; + if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { + mHomeLayout.setIcon(logo); + } + } + + public void setLogo(int resId) { + setLogo(mContext.getResources().getDrawable(resId)); + } + + public void setNavigationMode(int mode) { + final int oldMode = mNavigationMode; + if (mode != oldMode) { + switch (oldMode) { + case ActionBar.NAVIGATION_MODE_LIST: + if (mListNavLayout != null) { + removeView(mListNavLayout); + } + break; + case ActionBar.NAVIGATION_MODE_TABS: + if (mTabScrollView != null && mIncludeTabs) { + removeView(mTabScrollView); + } + } + + switch (mode) { + case ActionBar.NAVIGATION_MODE_LIST: + if (mSpinner == null) { + mSpinner = new IcsSpinner(mContext, null, + R.attr.actionDropDownStyle); + mListNavLayout = (IcsLinearLayout) LayoutInflater.from(mContext) + .inflate(R.layout.abs__action_bar_tab_bar_view, null); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( + LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); + params.gravity = Gravity.CENTER; + mListNavLayout.addView(mSpinner, params); + } + if (mSpinner.getAdapter() != mSpinnerAdapter) { + mSpinner.setAdapter(mSpinnerAdapter); + } + mSpinner.setOnItemSelectedListener(mNavItemSelectedListener); + addView(mListNavLayout); + break; + case ActionBar.NAVIGATION_MODE_TABS: + if (mTabScrollView != null && mIncludeTabs) { + addView(mTabScrollView); + } + break; + } + mNavigationMode = mode; + requestLayout(); + } + } + + public void setDropdownAdapter(SpinnerAdapter adapter) { + mSpinnerAdapter = adapter; + if (mSpinner != null) { + mSpinner.setAdapter(adapter); + } + } + + public SpinnerAdapter getDropdownAdapter() { + return mSpinnerAdapter; + } + + public void setDropdownSelectedPosition(int position) { + mSpinner.setSelection(position); + } + + public int getDropdownSelectedPosition() { + return mSpinner.getSelectedItemPosition(); + } + + public View getCustomNavigationView() { + return mCustomNavView; + } + + public int getNavigationMode() { + return mNavigationMode; + } + + public int getDisplayOptions() { + return mDisplayOptions; + } + + @Override + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + // Used by custom nav views if they don't supply layout params. Everything else + // added to an ActionBarView should have them already. + return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + addView(mHomeLayout); + + if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { + final ViewParent parent = mCustomNavView.getParent(); + if (parent != this) { + if (parent instanceof ViewGroup) { + ((ViewGroup) parent).removeView(mCustomNavView); + } + addView(mCustomNavView); + } + } + } + + private void initTitle() { + if (mTitleLayout == null) { + LayoutInflater inflater = LayoutInflater.from(getContext()); + mTitleLayout = (LinearLayout) inflater.inflate(R.layout.abs__action_bar_title_item, + this, false); + mTitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_title); + mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_subtitle); + mTitleUpView = mTitleLayout.findViewById(R.id.abs__up); + + mTitleLayout.setOnClickListener(mUpClickListener); + + if (mTitleStyleRes != 0) { + mTitleView.setTextAppearance(mContext, mTitleStyleRes); + } + if (mTitle != null) { + mTitleView.setText(mTitle); + } + + if (mSubtitleStyleRes != 0) { + mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); + } + if (mSubtitle != null) { + mSubtitleView.setText(mSubtitle); + mSubtitleView.setVisibility(VISIBLE); + } + + final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; + final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0; + mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); + mTitleLayout.setEnabled(homeAsUp && !showHome); + } + + addView(mTitleLayout); + if (mExpandedActionView != null || + (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) { + // Don't show while in expanded mode or with empty text + mTitleLayout.setVisibility(GONE); + } + } + + public void setContextView(ActionBarContextView view) { + mContextView = view; + } + + public void setCollapsable(boolean collapsable) { + mIsCollapsable = collapsable; + } + + public boolean isCollapsed() { + return mIsCollapsed; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int childCount = getChildCount(); + if (mIsCollapsable) { + int visibleChildren = 0; + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + if (child.getVisibility() != GONE && + !(child == mMenuView && mMenuView.getChildCount() == 0)) { + visibleChildren++; + } + } + + if (visibleChildren == 0) { + // No size for an empty action bar when collapsable. + setMeasuredDimension(0, 0); + mIsCollapsed = true; + return; + } + } + mIsCollapsed = false; + + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + if (widthMode != MeasureSpec.EXACTLY) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with android:layout_width=\"match_parent\" (or fill_parent)"); + } + + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + if (heightMode != MeasureSpec.AT_MOST) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with android:layout_height=\"wrap_content\""); + } + + int contentWidth = MeasureSpec.getSize(widthMeasureSpec); + + int maxHeight = mContentHeight > 0 ? + mContentHeight : MeasureSpec.getSize(heightMeasureSpec); + + final int verticalPadding = getPaddingTop() + getPaddingBottom(); + final int paddingLeft = getPaddingLeft(); + final int paddingRight = getPaddingRight(); + final int height = maxHeight - verticalPadding; + final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); + + int availableWidth = contentWidth - paddingLeft - paddingRight; + int leftOfCenter = availableWidth / 2; + int rightOfCenter = leftOfCenter; + + HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; + + if (homeLayout.getVisibility() != GONE) { + final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams(); + int homeWidthSpec; + if (lp.width < 0) { + homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); + } else { + homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); + } + homeLayout.measure(homeWidthSpec, + MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); + final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset(); + availableWidth = Math.max(0, availableWidth - homeWidth); + leftOfCenter = Math.max(0, availableWidth - homeWidth); + } + + if (mMenuView != null && mMenuView.getParent() == this) { + availableWidth = measureChildView(mMenuView, availableWidth, + childSpecHeight, 0); + rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth()); + } + + if (mIndeterminateProgressView != null && + mIndeterminateProgressView.getVisibility() != GONE) { + availableWidth = measureChildView(mIndeterminateProgressView, availableWidth, + childSpecHeight, 0); + rightOfCenter = Math.max(0, + rightOfCenter - mIndeterminateProgressView.getMeasuredWidth()); + } + + final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && + (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; + + if (mExpandedActionView == null) { + switch (mNavigationMode) { + case ActionBar.NAVIGATION_MODE_LIST: + if (mListNavLayout != null) { + final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; + availableWidth = Math.max(0, availableWidth - itemPaddingSize); + leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); + mListNavLayout.measure( + MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); + final int listNavWidth = mListNavLayout.getMeasuredWidth(); + availableWidth = Math.max(0, availableWidth - listNavWidth); + leftOfCenter = Math.max(0, leftOfCenter - listNavWidth); + } + break; + case ActionBar.NAVIGATION_MODE_TABS: + if (mTabScrollView != null) { + final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; + availableWidth = Math.max(0, availableWidth - itemPaddingSize); + leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); + mTabScrollView.measure( + MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); + final int tabWidth = mTabScrollView.getMeasuredWidth(); + availableWidth = Math.max(0, availableWidth - tabWidth); + leftOfCenter = Math.max(0, leftOfCenter - tabWidth); + } + break; + } + } + + View customView = null; + if (mExpandedActionView != null) { + customView = mExpandedActionView; + } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && + mCustomNavView != null) { + customView = mCustomNavView; + } + + if (customView != null) { + final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams()); + final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? + (ActionBar.LayoutParams) lp : null; + + int horizontalMargin = 0; + int verticalMargin = 0; + if (ablp != null) { + horizontalMargin = ablp.leftMargin + ablp.rightMargin; + verticalMargin = ablp.topMargin + ablp.bottomMargin; + } + + // If the action bar is wrapping to its content height, don't allow a custom + // view to MATCH_PARENT. + int customNavHeightMode; + if (mContentHeight <= 0) { + customNavHeightMode = MeasureSpec.AT_MOST; + } else { + customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? + MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; + } + final int customNavHeight = Math.max(0, + (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin); + + final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? + MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; + int customNavWidth = Math.max(0, + (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) + - horizontalMargin); + final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) & + Gravity.HORIZONTAL_GRAVITY_MASK; + + // Centering a custom view is treated specially; we try to center within the whole + // action bar rather than in the available space. + if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) { + customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2; + } + + customView.measure( + MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), + MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); + availableWidth -= horizontalMargin + customView.getMeasuredWidth(); + } + + if (mExpandedActionView == null && showTitle) { + availableWidth = measureChildView(mTitleLayout, availableWidth, + MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0); + leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); + } + + if (mContentHeight <= 0) { + int measuredHeight = 0; + for (int i = 0; i < childCount; i++) { + View v = getChildAt(i); + int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; + if (paddedViewHeight > measuredHeight) { + measuredHeight = paddedViewHeight; + } + } + setMeasuredDimension(contentWidth, measuredHeight); + } else { + setMeasuredDimension(contentWidth, maxHeight); + } + + if (mContextView != null) { + mContextView.setContentHeight(getMeasuredHeight()); + } + + if (mProgressView != null && mProgressView.getVisibility() != GONE) { + mProgressView.measure(MeasureSpec.makeMeasureSpec( + contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST)); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int x = getPaddingLeft(); + final int y = getPaddingTop(); + final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); + + if (contentHeight <= 0) { + // Nothing to do if we can't see anything. + return; + } + + HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; + if (homeLayout.getVisibility() != GONE) { + final int leftOffset = homeLayout.getLeftOffset(); + x += positionChild(homeLayout, x + leftOffset, y, contentHeight) + leftOffset; + } + + if (mExpandedActionView == null) { + final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && + (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; + if (showTitle) { + x += positionChild(mTitleLayout, x, y, contentHeight); + } + + switch (mNavigationMode) { + case ActionBar.NAVIGATION_MODE_STANDARD: + break; + case ActionBar.NAVIGATION_MODE_LIST: + if (mListNavLayout != null) { + if (showTitle) x += mItemPadding; + x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding; + } + break; + case ActionBar.NAVIGATION_MODE_TABS: + if (mTabScrollView != null) { + if (showTitle) x += mItemPadding; + x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding; + } + break; + } + } + + int menuLeft = r - l - getPaddingRight(); + if (mMenuView != null && mMenuView.getParent() == this) { + positionChildInverse(mMenuView, menuLeft, y, contentHeight); + menuLeft -= mMenuView.getMeasuredWidth(); + } + + if (mIndeterminateProgressView != null && + mIndeterminateProgressView.getVisibility() != GONE) { + positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight); + menuLeft -= mIndeterminateProgressView.getMeasuredWidth(); + } + + View customView = null; + if (mExpandedActionView != null) { + customView = mExpandedActionView; + } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && + mCustomNavView != null) { + customView = mCustomNavView; + } + if (customView != null) { + ViewGroup.LayoutParams lp = customView.getLayoutParams(); + final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? + (ActionBar.LayoutParams) lp : null; + + final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY; + final int navWidth = customView.getMeasuredWidth(); + + int topMargin = 0; + int bottomMargin = 0; + if (ablp != null) { + x += ablp.leftMargin; + menuLeft -= ablp.rightMargin; + topMargin = ablp.topMargin; + bottomMargin = ablp.bottomMargin; + } + + int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; + // See if we actually have room to truly center; if not push against left or right. + if (hgravity == Gravity.CENTER_HORIZONTAL) { + final int centeredLeft = ((getRight() - getLeft()) - navWidth) / 2; + if (centeredLeft < x) { + hgravity = Gravity.LEFT; + } else if (centeredLeft + navWidth > menuLeft) { + hgravity = Gravity.RIGHT; + } + } else if (gravity == -1) { + hgravity = Gravity.LEFT; + } + + int xpos = 0; + switch (hgravity) { + case Gravity.CENTER_HORIZONTAL: + xpos = ((getRight() - getLeft()) - navWidth) / 2; + break; + case Gravity.LEFT: + xpos = x; + break; + case Gravity.RIGHT: + xpos = menuLeft - navWidth; + break; + } + + int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; + + if (gravity == -1) { + vgravity = Gravity.CENTER_VERTICAL; + } + + int ypos = 0; + switch (vgravity) { + case Gravity.CENTER_VERTICAL: + final int paddedTop = getPaddingTop(); + final int paddedBottom = getBottom() - getTop() - getPaddingBottom(); + ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2; + break; + case Gravity.TOP: + ypos = getPaddingTop() + topMargin; + break; + case Gravity.BOTTOM: + ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight() + - bottomMargin; + break; + } + final int customWidth = customView.getMeasuredWidth(); + customView.layout(xpos, ypos, xpos + customWidth, + ypos + customView.getMeasuredHeight()); + x += customWidth; + } + + if (mProgressView != null) { + mProgressView.bringToFront(); + final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2; + mProgressView.layout(mProgressBarPadding, -halfProgressHeight, + mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight); + } + } + + @Override + public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { + return new ActionBar.LayoutParams(getContext(), attrs); + } + + @Override + public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { + if (lp == null) { + lp = generateDefaultLayoutParams(); + } + return lp; + } + + @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState state = new SavedState(superState); + + if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) { + state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId(); + } + + state.isOverflowOpen = isOverflowMenuShowing(); + + return state; + } + + @Override + public void onRestoreInstanceState(Parcelable p) { + SavedState state = (SavedState) p; + + super.onRestoreInstanceState(state.getSuperState()); + + if (state.expandedMenuItemId != 0 && + mExpandedMenuPresenter != null && mOptionsMenu != null) { + final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId); + if (item != null) { + item.expandActionView(); + } + } + + if (state.isOverflowOpen) { + postShowOverflowMenu(); + } + } + + static class SavedState extends BaseSavedState { + int expandedMenuItemId; + boolean isOverflowOpen; + + SavedState(Parcelable superState) { + super(superState); + } + + private SavedState(Parcel in) { + super(in); + expandedMenuItemId = in.readInt(); + isOverflowOpen = in.readInt() != 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(expandedMenuItemId); + out.writeInt(isOverflowOpen ? 1 : 0); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + public static class HomeView extends FrameLayout { + private View mUpView; + private ImageView mIconView; + private int mUpWidth; + + public HomeView(Context context) { + this(context, null); + } + + public HomeView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setUp(boolean isUp) { + mUpView.setVisibility(isUp ? VISIBLE : GONE); + } + + public void setIcon(Drawable icon) { + mIconView.setImageDrawable(icon); + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + onPopulateAccessibilityEvent(event); + return true; + } + + @Override + public void onPopulateAccessibilityEvent(AccessibilityEvent event) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + super.onPopulateAccessibilityEvent(event); + } + final CharSequence cdesc = getContentDescription(); + if (!TextUtils.isEmpty(cdesc)) { + event.getText().add(cdesc); + } + } + + @Override + public boolean dispatchHoverEvent(MotionEvent event) { + // Don't allow children to hover; we want this to be treated as a single component. + return onHoverEvent(event); + } + + @Override + protected void onFinishInflate() { + mUpView = findViewById(R.id.abs__up); + mIconView = (ImageView) findViewById(R.id.abs__home); + } + + public int getLeftOffset() { + return mUpView.getVisibility() == GONE ? mUpWidth : 0; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0); + final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); + mUpWidth = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin; + int width = mUpView.getVisibility() == GONE ? 0 : mUpWidth; + int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin; + measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0); + final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); + width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin; + height = Math.max(height, + iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin); + + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + final int widthSize = MeasureSpec.getSize(widthMeasureSpec); + final int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + switch (widthMode) { + case MeasureSpec.AT_MOST: + width = Math.min(width, widthSize); + break; + case MeasureSpec.EXACTLY: + width = widthSize; + break; + case MeasureSpec.UNSPECIFIED: + default: + break; + } + switch (heightMode) { + case MeasureSpec.AT_MOST: + height = Math.min(height, heightSize); + break; + case MeasureSpec.EXACTLY: + height = heightSize; + break; + case MeasureSpec.UNSPECIFIED: + default: + break; + } + setMeasuredDimension(width, height); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + final int vCenter = (b - t) / 2; + //UNUSED int width = r - l; + int upOffset = 0; + if (mUpView.getVisibility() != GONE) { + final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); + final int upHeight = mUpView.getMeasuredHeight(); + final int upWidth = mUpView.getMeasuredWidth(); + final int upTop = vCenter - upHeight / 2; + mUpView.layout(0, upTop, upWidth, upTop + upHeight); + upOffset = upLp.leftMargin + upWidth + upLp.rightMargin; + //UNUSED width -= upOffset; + l += upOffset; + } + final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); + final int iconHeight = mIconView.getMeasuredHeight(); + final int iconWidth = mIconView.getMeasuredWidth(); + final int hCenter = (r - l) / 2; + final int iconLeft = upOffset + Math.max(iconLp.leftMargin, hCenter - iconWidth / 2); + final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2); + mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight); + } + } + + private class ExpandedActionViewMenuPresenter implements MenuPresenter { + MenuBuilder mMenu; + MenuItemImpl mCurrentExpandedItem; + + @Override + public void initForMenu(Context context, MenuBuilder menu) { + // Clear the expanded action view when menus change. + if (mMenu != null && mCurrentExpandedItem != null) { + mMenu.collapseItemActionView(mCurrentExpandedItem); + } + mMenu = menu; + } + + @Override + public MenuView getMenuView(ViewGroup root) { + return null; + } + + @Override + public void updateMenuView(boolean cleared) { + // Make sure the expanded item we have is still there. + if (mCurrentExpandedItem != null) { + boolean found = false; + + if (mMenu != null) { + final int count = mMenu.size(); + for (int i = 0; i < count; i++) { + final MenuItem item = mMenu.getItem(i); + if (item == mCurrentExpandedItem) { + found = true; + break; + } + } + } + + if (!found) { + // The item we had expanded disappeared. Collapse. + collapseItemActionView(mMenu, mCurrentExpandedItem); + } + } + } + + @Override + public void setCallback(Callback cb) { + } + + @Override + public boolean onSubMenuSelected(SubMenuBuilder subMenu) { + return false; + } + + @Override + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + } + + @Override + public boolean flagActionItems() { + return false; + } + + @Override + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { + mExpandedActionView = item.getActionView(); + mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(/* TODO getResources() */)); + mCurrentExpandedItem = item; + if (mExpandedActionView.getParent() != ActionBarView.this) { + addView(mExpandedActionView); + } + if (mExpandedHomeLayout.getParent() != ActionBarView.this) { + addView(mExpandedHomeLayout); + } + mHomeLayout.setVisibility(GONE); + if (mTitleLayout != null) mTitleLayout.setVisibility(GONE); + if (mTabScrollView != null) mTabScrollView.setVisibility(GONE); + if (mSpinner != null) mSpinner.setVisibility(GONE); + if (mCustomNavView != null) mCustomNavView.setVisibility(GONE); + requestLayout(); + item.setActionViewExpanded(true); + + if (mExpandedActionView instanceof CollapsibleActionView) { + ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded(); + } + + return true; + } + + @Override + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { + // Do this before detaching the actionview from the hierarchy, in case + // it needs to dismiss the soft keyboard, etc. + if (mExpandedActionView instanceof CollapsibleActionView) { + ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed(); + } + + removeView(mExpandedActionView); + removeView(mExpandedHomeLayout); + mExpandedActionView = null; + if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) { + mHomeLayout.setVisibility(VISIBLE); + } + if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + if (mTitleLayout == null) { + initTitle(); + } else { + mTitleLayout.setVisibility(VISIBLE); + } + } + if (mTabScrollView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { + mTabScrollView.setVisibility(VISIBLE); + } + if (mSpinner != null && mNavigationMode == ActionBar.NAVIGATION_MODE_LIST) { + mSpinner.setVisibility(VISIBLE); + } + if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { + mCustomNavView.setVisibility(VISIBLE); + } + mExpandedHomeLayout.setIcon(null); + mCurrentExpandedItem = null; + requestLayout(); + item.setActionViewExpanded(false); + + return true; + } + + @Override + public int getId() { + return 0; + } + + @Override + public Parcelable onSaveInstanceState() { + return null; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java new file mode 100644 index 0000000000..fa3698f3b4 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java @@ -0,0 +1,40 @@ +package com.actionbarsherlock.internal.widget; + +import java.util.Locale; +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Build; +import android.util.AttributeSet; +import android.widget.Button; + +public class CapitalizingButton extends Button { + private static final boolean SANS_ICE_CREAM = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH; + private static final boolean IS_GINGERBREAD = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; + + private static final int[] R_styleable_Button = new int[] { + android.R.attr.textAllCaps + }; + private static final int R_styleable_Button_textAllCaps = 0; + + private boolean mAllCaps; + + public CapitalizingButton(Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, R_styleable_Button); + mAllCaps = a.getBoolean(R_styleable_Button_textAllCaps, true); + a.recycle(); + } + + public void setTextCompat(CharSequence text) { + if (SANS_ICE_CREAM && mAllCaps && text != null) { + if (IS_GINGERBREAD) { + setText(text.toString().toUpperCase(Locale.ROOT)); + } else { + setText(text.toString().toUpperCase()); + } + } else { + setText(text); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java new file mode 100644 index 0000000000..cae8b8aed3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java @@ -0,0 +1,50 @@ +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Build; +import android.util.AttributeSet; +import android.widget.TextView; + +import java.util.Locale; + +public class CapitalizingTextView extends TextView { + private static final boolean SANS_ICE_CREAM = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH; + private static final boolean IS_GINGERBREAD = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; + + private static final int[] R_styleable_TextView = new int[] { + android.R.attr.textAllCaps + }; + private static final int R_styleable_TextView_textAllCaps = 0; + + private boolean mAllCaps; + + public CapitalizingTextView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public CapitalizingTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R_styleable_TextView, defStyle, 0); + mAllCaps = a.getBoolean(R_styleable_TextView_textAllCaps, true); + a.recycle(); + } + + public void setTextCompat(CharSequence text) { + if (SANS_ICE_CREAM && mAllCaps && text != null) { + if (IS_GINGERBREAD) { + try { + setText(text.toString().toUpperCase(Locale.ROOT)); + } catch (NoSuchFieldError e) { + //Some manufacturer broke Locale.ROOT. See #572. + setText(text.toString().toUpperCase()); + } + } else { + setText(text.toString().toUpperCase()); + } + } else { + setText(text); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java new file mode 100644 index 0000000000..14f092c81f --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java @@ -0,0 +1,30 @@ +package com.actionbarsherlock.internal.widget; + +import android.view.View; +import android.widget.FrameLayout; +import com.actionbarsherlock.view.CollapsibleActionView; + +/** + * Wraps an ABS collapsible action view in a native container that delegates the calls. + */ +public class CollapsibleActionViewWrapper extends FrameLayout implements android.view.CollapsibleActionView { + private final CollapsibleActionView child; + + public CollapsibleActionViewWrapper(View child) { + super(child.getContext()); + this.child = (CollapsibleActionView) child; + addView(child); + } + + @Override public void onActionViewExpanded() { + child.onActionViewExpanded(); + } + + @Override public void onActionViewCollapsed() { + child.onActionViewCollapsed(); + } + + public View unwrap() { + return getChildAt(0); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java new file mode 100644 index 0000000000..ad1b4f0a85 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java @@ -0,0 +1,64 @@ +package com.actionbarsherlock.internal.widget; + +import static android.view.View.MeasureSpec.EXACTLY; +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.widget.LinearLayout; +import com.actionbarsherlock.R; + +public class FakeDialogPhoneWindow extends LinearLayout { + final TypedValue mMinWidthMajor = new TypedValue(); + final TypedValue mMinWidthMinor = new TypedValue(); + + public FakeDialogPhoneWindow(Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockTheme); + + a.getValue(R.styleable.SherlockTheme_windowMinWidthMajor, mMinWidthMajor); + a.getValue(R.styleable.SherlockTheme_windowMinWidthMinor, mMinWidthMinor); + + a.recycle(); + } + + /* Stolen from PhoneWindow */ + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); + final boolean isPortrait = metrics.widthPixels < metrics.heightPixels; + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + int width = getMeasuredWidth(); + boolean measure = false; + + widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY); + + final TypedValue tv = isPortrait ? mMinWidthMinor : mMinWidthMajor; + + if (tv.type != TypedValue.TYPE_NULL) { + final int min; + if (tv.type == TypedValue.TYPE_DIMENSION) { + min = (int)tv.getDimension(metrics); + } else if (tv.type == TypedValue.TYPE_FRACTION) { + min = (int)tv.getFraction(metrics.widthPixels, metrics.widthPixels); + } else { + min = 0; + } + + if (width < min) { + widthMeasureSpec = MeasureSpec.makeMeasureSpec(min, EXACTLY); + measure = true; + } + } + + // TODO: Support height? + + if (measure) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java new file mode 100644 index 0000000000..0531cb27e0 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.database.DataSetObserver; +import android.graphics.Rect; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.view.View; +import android.view.ViewGroup; +import android.widget.SpinnerAdapter; + +/** + * An abstract base class for spinner widgets. SDK users will probably not + * need to use this class. + * + * @attr ref android.R.styleable#AbsSpinner_entries + */ +public abstract class IcsAbsSpinner extends IcsAdapterView { + private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; + + SpinnerAdapter mAdapter; + + int mHeightMeasureSpec; + int mWidthMeasureSpec; + boolean mBlockLayoutRequests; + + int mSelectionLeftPadding = 0; + int mSelectionTopPadding = 0; + int mSelectionRightPadding = 0; + int mSelectionBottomPadding = 0; + final Rect mSpinnerPadding = new Rect(); + + final RecycleBin mRecycler = new RecycleBin(); + private DataSetObserver mDataSetObserver; + + /** Temporary frame to hold a child View's frame rectangle */ + private Rect mTouchFrame; + + public IcsAbsSpinner(Context context) { + super(context); + initAbsSpinner(); + } + + public IcsAbsSpinner(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public IcsAbsSpinner(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initAbsSpinner(); + + /* + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.AbsSpinner, defStyle, 0); + + CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries); + if (entries != null) { + ArrayAdapter adapter = + new ArrayAdapter(context, + R.layout.simple_spinner_item, entries); + adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item); + setAdapter(adapter); + } + + a.recycle(); + */ + } + + /** + * Common code for different constructor flavors + */ + private void initAbsSpinner() { + setFocusable(true); + setWillNotDraw(false); + } + + /** + * The Adapter is used to provide the data which backs this Spinner. + * It also provides methods to transform spinner items based on their position + * relative to the selected item. + * @param adapter The SpinnerAdapter to use for this Spinner + */ + @Override + public void setAdapter(SpinnerAdapter adapter) { + if (null != mAdapter) { + mAdapter.unregisterDataSetObserver(mDataSetObserver); + resetList(); + } + + mAdapter = adapter; + + mOldSelectedPosition = INVALID_POSITION; + mOldSelectedRowId = INVALID_ROW_ID; + + if (mAdapter != null) { + mOldItemCount = mItemCount; + mItemCount = mAdapter.getCount(); + checkFocus(); + + mDataSetObserver = new AdapterDataSetObserver(); + mAdapter.registerDataSetObserver(mDataSetObserver); + + int position = mItemCount > 0 ? 0 : INVALID_POSITION; + + setSelectedPositionInt(position); + setNextSelectedPositionInt(position); + + if (mItemCount == 0) { + // Nothing selected + checkSelectionChanged(); + } + + } else { + checkFocus(); + resetList(); + // Nothing selected + checkSelectionChanged(); + } + + requestLayout(); + } + + /** + * Clear out all children from the list + */ + void resetList() { + mDataChanged = false; + mNeedSync = false; + + removeAllViewsInLayout(); + mOldSelectedPosition = INVALID_POSITION; + mOldSelectedRowId = INVALID_ROW_ID; + + setSelectedPositionInt(INVALID_POSITION); + setNextSelectedPositionInt(INVALID_POSITION); + invalidate(); + } + + /** + * @see android.view.View#measure(int, int) + * + * Figure out the dimensions of this Spinner. The width comes from + * the widthMeasureSpec as Spinnners can't have their width set to + * UNSPECIFIED. The height is based on the height of the selected item + * plus padding. + */ + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int widthSize; + int heightSize; + + final int mPaddingLeft = getPaddingLeft(); + final int mPaddingTop = getPaddingTop(); + final int mPaddingRight = getPaddingRight(); + final int mPaddingBottom = getPaddingBottom(); + + mSpinnerPadding.left = mPaddingLeft > mSelectionLeftPadding ? mPaddingLeft + : mSelectionLeftPadding; + mSpinnerPadding.top = mPaddingTop > mSelectionTopPadding ? mPaddingTop + : mSelectionTopPadding; + mSpinnerPadding.right = mPaddingRight > mSelectionRightPadding ? mPaddingRight + : mSelectionRightPadding; + mSpinnerPadding.bottom = mPaddingBottom > mSelectionBottomPadding ? mPaddingBottom + : mSelectionBottomPadding; + + if (mDataChanged) { + handleDataChanged(); + } + + int preferredHeight = 0; + int preferredWidth = 0; + boolean needsMeasuring = true; + + int selectedPosition = getSelectedItemPosition(); + if (selectedPosition >= 0 && mAdapter != null && selectedPosition < mAdapter.getCount()) { + // Try looking in the recycler. (Maybe we were measured once already) + View view = mRecycler.get(selectedPosition); + if (view == null) { + // Make a new one + view = mAdapter.getView(selectedPosition, null, this); + } + + if (view != null) { + // Put in recycler for re-measuring and/or layout + mRecycler.put(selectedPosition, view); + } + + if (view != null) { + if (view.getLayoutParams() == null) { + mBlockLayoutRequests = true; + view.setLayoutParams(generateDefaultLayoutParams()); + mBlockLayoutRequests = false; + } + measureChild(view, widthMeasureSpec, heightMeasureSpec); + + preferredHeight = getChildHeight(view) + mSpinnerPadding.top + mSpinnerPadding.bottom; + preferredWidth = getChildWidth(view) + mSpinnerPadding.left + mSpinnerPadding.right; + + needsMeasuring = false; + } + } + + if (needsMeasuring) { + // No views -- just use padding + preferredHeight = mSpinnerPadding.top + mSpinnerPadding.bottom; + if (widthMode == MeasureSpec.UNSPECIFIED) { + preferredWidth = mSpinnerPadding.left + mSpinnerPadding.right; + } + } + + preferredHeight = Math.max(preferredHeight, getSuggestedMinimumHeight()); + preferredWidth = Math.max(preferredWidth, getSuggestedMinimumWidth()); + + if (IS_HONEYCOMB) { + heightSize = resolveSizeAndState(preferredHeight, heightMeasureSpec, 0); + widthSize = resolveSizeAndState(preferredWidth, widthMeasureSpec, 0); + } else { + heightSize = resolveSize(preferredHeight, heightMeasureSpec); + widthSize = resolveSize(preferredWidth, widthMeasureSpec); + } + + setMeasuredDimension(widthSize, heightSize); + mHeightMeasureSpec = heightMeasureSpec; + mWidthMeasureSpec = widthMeasureSpec; + } + + int getChildHeight(View child) { + return child.getMeasuredHeight(); + } + + int getChildWidth(View child) { + return child.getMeasuredWidth(); + } + + @Override + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + return new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + } + + void recycleAllViews() { + final int childCount = getChildCount(); + final RecycleBin recycleBin = mRecycler; + final int position = mFirstPosition; + + // All views go in recycler + for (int i = 0; i < childCount; i++) { + View v = getChildAt(i); + int index = position + i; + recycleBin.put(index, v); + } + } + + /** + * Jump directly to a specific item in the adapter data. + */ + public void setSelection(int position, boolean animate) { + // Animate only if requested position is already on screen somewhere + boolean shouldAnimate = animate && mFirstPosition <= position && + position <= mFirstPosition + getChildCount() - 1; + setSelectionInt(position, shouldAnimate); + } + + @Override + public void setSelection(int position) { + setNextSelectedPositionInt(position); + requestLayout(); + invalidate(); + } + + + /** + * Makes the item at the supplied position selected. + * + * @param position Position to select + * @param animate Should the transition be animated + * + */ + void setSelectionInt(int position, boolean animate) { + if (position != mOldSelectedPosition) { + mBlockLayoutRequests = true; + int delta = position - mSelectedPosition; + setNextSelectedPositionInt(position); + layout(delta, animate); + mBlockLayoutRequests = false; + } + } + + abstract void layout(int delta, boolean animate); + + @Override + public View getSelectedView() { + if (mItemCount > 0 && mSelectedPosition >= 0) { + return getChildAt(mSelectedPosition - mFirstPosition); + } else { + return null; + } + } + + /** + * Override to prevent spamming ourselves with layout requests + * as we place views + * + * @see android.view.View#requestLayout() + */ + @Override + public void requestLayout() { + if (!mBlockLayoutRequests) { + super.requestLayout(); + } + } + + @Override + public SpinnerAdapter getAdapter() { + return mAdapter; + } + + @Override + public int getCount() { + return mItemCount; + } + + /** + * Maps a point to a position in the list. + * + * @param x X in local coordinate + * @param y Y in local coordinate + * @return The position of the item which contains the specified point, or + * {@link #INVALID_POSITION} if the point does not intersect an item. + */ + public int pointToPosition(int x, int y) { + Rect frame = mTouchFrame; + if (frame == null) { + mTouchFrame = new Rect(); + frame = mTouchFrame; + } + + final int count = getChildCount(); + for (int i = count - 1; i >= 0; i--) { + View child = getChildAt(i); + if (child.getVisibility() == View.VISIBLE) { + child.getHitRect(frame); + if (frame.contains(x, y)) { + return mFirstPosition + i; + } + } + } + return INVALID_POSITION; + } + + static class SavedState extends BaseSavedState { + long selectedId; + int position; + + /** + * Constructor called from {@link AbsSpinner#onSaveInstanceState()} + */ + SavedState(Parcelable superState) { + super(superState); + } + + /** + * Constructor called from {@link #CREATOR} + */ + private SavedState(Parcel in) { + super(in); + selectedId = in.readLong(); + position = in.readInt(); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeLong(selectedId); + out.writeInt(position); + } + + @Override + public String toString() { + return "AbsSpinner.SavedState{" + + Integer.toHexString(System.identityHashCode(this)) + + " selectedId=" + selectedId + + " position=" + position + "}"; + } + + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.selectedId = getSelectedItemId(); + if (ss.selectedId >= 0) { + ss.position = getSelectedItemPosition(); + } else { + ss.position = INVALID_POSITION; + } + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + + super.onRestoreInstanceState(ss.getSuperState()); + + if (ss.selectedId >= 0) { + mDataChanged = true; + mNeedSync = true; + mSyncRowId = ss.selectedId; + mSyncPosition = ss.position; + mSyncMode = SYNC_SELECTED_POSITION; + requestLayout(); + } + } + + class RecycleBin { + private final SparseArray mScrapHeap = new SparseArray(); + + public void put(int position, View v) { + mScrapHeap.put(position, v); + } + + View get(int position) { + // System.out.print("Looking for " + position); + View result = mScrapHeap.get(position); + if (result != null) { + // System.out.println(" HIT"); + mScrapHeap.delete(position); + } else { + // System.out.println(" MISS"); + } + return result; + } + + void clear() { + final SparseArray scrapHeap = mScrapHeap; + final int count = scrapHeap.size(); + for (int i = 0; i < count; i++) { + final View view = scrapHeap.valueAt(i); + if (view != null) { + removeDetachedView(view, true); + } + } + scrapHeap.clear(); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java new file mode 100644 index 0000000000..c786dc5c19 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java @@ -0,0 +1,1160 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.database.DataSetObserver; +import android.os.Parcelable; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.view.ContextMenu; +import android.view.SoundEffectConstants; +import android.view.View; +import android.view.ViewDebug; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.Adapter; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ListView; + + +/** + * An AdapterView is a view whose children are determined by an {@link Adapter}. + * + *

+ * See {@link ListView}, {@link GridView}, {@link Spinner} and + * {@link Gallery} for commonly used subclasses of AdapterView. + * + *

+ *

Developer Guides

+ *

For more information about using AdapterView, read the + * Binding to Data with AdapterView + * developer guide.

+ */ +public abstract class IcsAdapterView extends ViewGroup { + + /** + * The item view type returned by {@link Adapter#getItemViewType(int)} when + * the adapter does not want the item's view recycled. + */ + public static final int ITEM_VIEW_TYPE_IGNORE = -1; + + /** + * The item view type returned by {@link Adapter#getItemViewType(int)} when + * the item is a header or footer. + */ + public static final int ITEM_VIEW_TYPE_HEADER_OR_FOOTER = -2; + + /** + * The position of the first child displayed + */ + @ViewDebug.ExportedProperty(category = "scrolling") + int mFirstPosition = 0; + + /** + * The offset in pixels from the top of the AdapterView to the top + * of the view to select during the next layout. + */ + int mSpecificTop; + + /** + * Position from which to start looking for mSyncRowId + */ + int mSyncPosition; + + /** + * Row id to look for when data has changed + */ + long mSyncRowId = INVALID_ROW_ID; + + /** + * Height of the view when mSyncPosition and mSyncRowId where set + */ + long mSyncHeight; + + /** + * True if we need to sync to mSyncRowId + */ + boolean mNeedSync = false; + + /** + * Indicates whether to sync based on the selection or position. Possible + * values are {@link #SYNC_SELECTED_POSITION} or + * {@link #SYNC_FIRST_POSITION}. + */ + int mSyncMode; + + /** + * Our height after the last layout + */ + private int mLayoutHeight; + + /** + * Sync based on the selected child + */ + static final int SYNC_SELECTED_POSITION = 0; + + /** + * Sync based on the first child displayed + */ + static final int SYNC_FIRST_POSITION = 1; + + /** + * Maximum amount of time to spend in {@link #findSyncPosition()} + */ + static final int SYNC_MAX_DURATION_MILLIS = 100; + + /** + * Indicates that this view is currently being laid out. + */ + boolean mInLayout = false; + + /** + * The listener that receives notifications when an item is selected. + */ + OnItemSelectedListener mOnItemSelectedListener; + + /** + * The listener that receives notifications when an item is clicked. + */ + OnItemClickListener mOnItemClickListener; + + /** + * The listener that receives notifications when an item is long clicked. + */ + OnItemLongClickListener mOnItemLongClickListener; + + /** + * True if the data has changed since the last layout + */ + boolean mDataChanged; + + /** + * The position within the adapter's data set of the item to select + * during the next layout. + */ + @ViewDebug.ExportedProperty(category = "list") + int mNextSelectedPosition = INVALID_POSITION; + + /** + * The item id of the item to select during the next layout. + */ + long mNextSelectedRowId = INVALID_ROW_ID; + + /** + * The position within the adapter's data set of the currently selected item. + */ + @ViewDebug.ExportedProperty(category = "list") + int mSelectedPosition = INVALID_POSITION; + + /** + * The item id of the currently selected item. + */ + long mSelectedRowId = INVALID_ROW_ID; + + /** + * View to show if there are no items to show. + */ + private View mEmptyView; + + /** + * The number of items in the current adapter. + */ + @ViewDebug.ExportedProperty(category = "list") + int mItemCount; + + /** + * The number of items in the adapter before a data changed event occurred. + */ + int mOldItemCount; + + /** + * Represents an invalid position. All valid positions are in the range 0 to 1 less than the + * number of items in the current adapter. + */ + public static final int INVALID_POSITION = -1; + + /** + * Represents an empty or invalid row id + */ + public static final long INVALID_ROW_ID = Long.MIN_VALUE; + + /** + * The last selected position we used when notifying + */ + int mOldSelectedPosition = INVALID_POSITION; + + /** + * The id of the last selected position we used when notifying + */ + long mOldSelectedRowId = INVALID_ROW_ID; + + /** + * Indicates what focusable state is requested when calling setFocusable(). + * In addition to this, this view has other criteria for actually + * determining the focusable state (such as whether its empty or the text + * filter is shown). + * + * @see #setFocusable(boolean) + * @see #checkFocus() + */ + private boolean mDesiredFocusableState; + private boolean mDesiredFocusableInTouchModeState; + + private SelectionNotifier mSelectionNotifier; + /** + * When set to true, calls to requestLayout() will not propagate up the parent hierarchy. + * This is used to layout the children during a layout pass. + */ + boolean mBlockLayoutRequests = false; + + public IcsAdapterView(Context context) { + super(context); + } + + public IcsAdapterView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public IcsAdapterView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + /** + * Register a callback to be invoked when an item in this AdapterView has + * been clicked. + * + * @param listener The callback that will be invoked. + */ + public void setOnItemClickListener(OnItemClickListener listener) { + mOnItemClickListener = listener; + } + + /** + * @return The callback to be invoked with an item in this AdapterView has + * been clicked, or null id no callback has been set. + */ + public final OnItemClickListener getOnItemClickListener() { + return mOnItemClickListener; + } + + /** + * Call the OnItemClickListener, if it is defined. + * + * @param view The view within the AdapterView that was clicked. + * @param position The position of the view in the adapter. + * @param id The row id of the item that was clicked. + * @return True if there was an assigned OnItemClickListener that was + * called, false otherwise is returned. + */ + public boolean performItemClick(View view, int position, long id) { + if (mOnItemClickListener != null) { + playSoundEffect(SoundEffectConstants.CLICK); + if (view != null) { + view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); + } + mOnItemClickListener.onItemClick(/*this*/null, view, position, id); + return true; + } + + return false; + } + + /** + * Interface definition for a callback to be invoked when an item in this + * view has been clicked and held. + */ + public interface OnItemLongClickListener { + /** + * Callback method to be invoked when an item in this view has been + * clicked and held. + * + * Implementers can call getItemAtPosition(position) if they need to access + * the data associated with the selected item. + * + * @param parent The AbsListView where the click happened + * @param view The view within the AbsListView that was clicked + * @param position The position of the view in the list + * @param id The row id of the item that was clicked + * + * @return true if the callback consumed the long click, false otherwise + */ + boolean onItemLongClick(IcsAdapterView parent, View view, int position, long id); + } + + + /** + * Register a callback to be invoked when an item in this AdapterView has + * been clicked and held + * + * @param listener The callback that will run + */ + public void setOnItemLongClickListener(OnItemLongClickListener listener) { + if (!isLongClickable()) { + setLongClickable(true); + } + mOnItemLongClickListener = listener; + } + + /** + * @return The callback to be invoked with an item in this AdapterView has + * been clicked and held, or null id no callback as been set. + */ + public final OnItemLongClickListener getOnItemLongClickListener() { + return mOnItemLongClickListener; + } + + /** + * Interface definition for a callback to be invoked when + * an item in this view has been selected. + */ + public interface OnItemSelectedListener { + /** + *

Callback method to be invoked when an item in this view has been + * selected. This callback is invoked only when the newly selected + * position is different from the previously selected position or if + * there was no selected item.

+ * + * Impelmenters can call getItemAtPosition(position) if they need to access the + * data associated with the selected item. + * + * @param parent The AdapterView where the selection happened + * @param view The view within the AdapterView that was clicked + * @param position The position of the view in the adapter + * @param id The row id of the item that is selected + */ + void onItemSelected(IcsAdapterView parent, View view, int position, long id); + + /** + * Callback method to be invoked when the selection disappears from this + * view. The selection can disappear for instance when touch is activated + * or when the adapter becomes empty. + * + * @param parent The AdapterView that now contains no selected item. + */ + void onNothingSelected(IcsAdapterView parent); + } + + + /** + * Register a callback to be invoked when an item in this AdapterView has + * been selected. + * + * @param listener The callback that will run + */ + public void setOnItemSelectedListener(OnItemSelectedListener listener) { + mOnItemSelectedListener = listener; + } + + public final OnItemSelectedListener getOnItemSelectedListener() { + return mOnItemSelectedListener; + } + + /** + * Extra menu information provided to the + * {@link android.view.View.OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo) } + * callback when a context menu is brought up for this AdapterView. + * + */ + public static class AdapterContextMenuInfo implements ContextMenu.ContextMenuInfo { + + public AdapterContextMenuInfo(View targetView, int position, long id) { + this.targetView = targetView; + this.position = position; + this.id = id; + } + + /** + * The child view for which the context menu is being displayed. This + * will be one of the children of this AdapterView. + */ + public View targetView; + + /** + * The position in the adapter for which the context menu is being + * displayed. + */ + public int position; + + /** + * The row id of the item for which the context menu is being displayed. + */ + public long id; + } + + /** + * Returns the adapter currently associated with this widget. + * + * @return The adapter used to provide this view's content. + */ + public abstract T getAdapter(); + + /** + * Sets the adapter that provides the data and the views to represent the data + * in this widget. + * + * @param adapter The adapter to use to create this view's content. + */ + public abstract void setAdapter(T adapter); + + /** + * This method is not supported and throws an UnsupportedOperationException when called. + * + * @param child Ignored. + * + * @throws UnsupportedOperationException Every time this method is invoked. + */ + @Override + public void addView(View child) { + throw new UnsupportedOperationException("addView(View) is not supported in AdapterView"); + } + + /** + * This method is not supported and throws an UnsupportedOperationException when called. + * + * @param child Ignored. + * @param index Ignored. + * + * @throws UnsupportedOperationException Every time this method is invoked. + */ + @Override + public void addView(View child, int index) { + throw new UnsupportedOperationException("addView(View, int) is not supported in AdapterView"); + } + + /** + * This method is not supported and throws an UnsupportedOperationException when called. + * + * @param child Ignored. + * @param params Ignored. + * + * @throws UnsupportedOperationException Every time this method is invoked. + */ + @Override + public void addView(View child, LayoutParams params) { + throw new UnsupportedOperationException("addView(View, LayoutParams) " + + "is not supported in AdapterView"); + } + + /** + * This method is not supported and throws an UnsupportedOperationException when called. + * + * @param child Ignored. + * @param index Ignored. + * @param params Ignored. + * + * @throws UnsupportedOperationException Every time this method is invoked. + */ + @Override + public void addView(View child, int index, LayoutParams params) { + throw new UnsupportedOperationException("addView(View, int, LayoutParams) " + + "is not supported in AdapterView"); + } + + /** + * This method is not supported and throws an UnsupportedOperationException when called. + * + * @param child Ignored. + * + * @throws UnsupportedOperationException Every time this method is invoked. + */ + @Override + public void removeView(View child) { + throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView"); + } + + /** + * This method is not supported and throws an UnsupportedOperationException when called. + * + * @param index Ignored. + * + * @throws UnsupportedOperationException Every time this method is invoked. + */ + @Override + public void removeViewAt(int index) { + throw new UnsupportedOperationException("removeViewAt(int) is not supported in AdapterView"); + } + + /** + * This method is not supported and throws an UnsupportedOperationException when called. + * + * @throws UnsupportedOperationException Every time this method is invoked. + */ + @Override + public void removeAllViews() { + throw new UnsupportedOperationException("removeAllViews() is not supported in AdapterView"); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + mLayoutHeight = getHeight(); + } + + /** + * Return the position of the currently selected item within the adapter's data set + * + * @return int Position (starting at 0), or {@link #INVALID_POSITION} if there is nothing selected. + */ + @ViewDebug.CapturedViewProperty + public int getSelectedItemPosition() { + return mNextSelectedPosition; + } + + /** + * @return The id corresponding to the currently selected item, or {@link #INVALID_ROW_ID} + * if nothing is selected. + */ + @ViewDebug.CapturedViewProperty + public long getSelectedItemId() { + return mNextSelectedRowId; + } + + /** + * @return The view corresponding to the currently selected item, or null + * if nothing is selected + */ + public abstract View getSelectedView(); + + /** + * @return The data corresponding to the currently selected item, or + * null if there is nothing selected. + */ + public Object getSelectedItem() { + T adapter = getAdapter(); + int selection = getSelectedItemPosition(); + if (adapter != null && adapter.getCount() > 0 && selection >= 0) { + return adapter.getItem(selection); + } else { + return null; + } + } + + /** + * @return The number of items owned by the Adapter associated with this + * AdapterView. (This is the number of data items, which may be + * larger than the number of visible views.) + */ + @ViewDebug.CapturedViewProperty + public int getCount() { + return mItemCount; + } + + /** + * Get the position within the adapter's data set for the view, where view is a an adapter item + * or a descendant of an adapter item. + * + * @param view an adapter item, or a descendant of an adapter item. This must be visible in this + * AdapterView at the time of the call. + * @return the position within the adapter's data set of the view, or {@link #INVALID_POSITION} + * if the view does not correspond to a list item (or it is not currently visible). + */ + public int getPositionForView(View view) { + View listItem = view; + try { + View v; + while (!(v = (View) listItem.getParent()).equals(this)) { + listItem = v; + } + } catch (ClassCastException e) { + // We made it up to the window without find this list view + return INVALID_POSITION; + } + + // Search the children for the list item + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + if (getChildAt(i).equals(listItem)) { + return mFirstPosition + i; + } + } + + // Child not found! + return INVALID_POSITION; + } + + /** + * Returns the position within the adapter's data set for the first item + * displayed on screen. + * + * @return The position within the adapter's data set + */ + public int getFirstVisiblePosition() { + return mFirstPosition; + } + + /** + * Returns the position within the adapter's data set for the last item + * displayed on screen. + * + * @return The position within the adapter's data set + */ + public int getLastVisiblePosition() { + return mFirstPosition + getChildCount() - 1; + } + + /** + * Sets the currently selected item. To support accessibility subclasses that + * override this method must invoke the overriden super method first. + * + * @param position Index (starting at 0) of the data item to be selected. + */ + public abstract void setSelection(int position); + + /** + * Sets the view to show if the adapter is empty + */ + public void setEmptyView(View emptyView) { + mEmptyView = emptyView; + + final T adapter = getAdapter(); + final boolean empty = ((adapter == null) || adapter.isEmpty()); + updateEmptyStatus(empty); + } + + /** + * When the current adapter is empty, the AdapterView can display a special view + * call the empty view. The empty view is used to provide feedback to the user + * that no data is available in this AdapterView. + * + * @return The view to show if the adapter is empty. + */ + public View getEmptyView() { + return mEmptyView; + } + + /** + * Indicates whether this view is in filter mode. Filter mode can for instance + * be enabled by a user when typing on the keyboard. + * + * @return True if the view is in filter mode, false otherwise. + */ + boolean isInFilterMode() { + return false; + } + + @Override + public void setFocusable(boolean focusable) { + final T adapter = getAdapter(); + final boolean empty = adapter == null || adapter.getCount() == 0; + + mDesiredFocusableState = focusable; + if (!focusable) { + mDesiredFocusableInTouchModeState = false; + } + + super.setFocusable(focusable && (!empty || isInFilterMode())); + } + + @Override + public void setFocusableInTouchMode(boolean focusable) { + final T adapter = getAdapter(); + final boolean empty = adapter == null || adapter.getCount() == 0; + + mDesiredFocusableInTouchModeState = focusable; + if (focusable) { + mDesiredFocusableState = true; + } + + super.setFocusableInTouchMode(focusable && (!empty || isInFilterMode())); + } + + void checkFocus() { + final T adapter = getAdapter(); + final boolean empty = adapter == null || adapter.getCount() == 0; + final boolean focusable = !empty || isInFilterMode(); + // The order in which we set focusable in touch mode/focusable may matter + // for the client, see View.setFocusableInTouchMode() comments for more + // details + super.setFocusableInTouchMode(focusable && mDesiredFocusableInTouchModeState); + super.setFocusable(focusable && mDesiredFocusableState); + if (mEmptyView != null) { + updateEmptyStatus((adapter == null) || adapter.isEmpty()); + } + } + + /** + * Update the status of the list based on the empty parameter. If empty is true and + * we have an empty view, display it. In all the other cases, make sure that the listview + * is VISIBLE and that the empty view is GONE (if it's not null). + */ + private void updateEmptyStatus(boolean empty) { + if (isInFilterMode()) { + empty = false; + } + + if (empty) { + if (mEmptyView != null) { + mEmptyView.setVisibility(View.VISIBLE); + setVisibility(View.GONE); + } else { + // If the caller just removed our empty view, make sure the list view is visible + setVisibility(View.VISIBLE); + } + + // We are now GONE, so pending layouts will not be dispatched. + // Force one here to make sure that the state of the list matches + // the state of the adapter. + if (mDataChanged) { + this.onLayout(false, getLeft(), getTop(), getRight(), getBottom()); + } + } else { + if (mEmptyView != null) mEmptyView.setVisibility(View.GONE); + setVisibility(View.VISIBLE); + } + } + + /** + * Gets the data associated with the specified position in the list. + * + * @param position Which data to get + * @return The data associated with the specified position in the list + */ + public Object getItemAtPosition(int position) { + T adapter = getAdapter(); + return (adapter == null || position < 0) ? null : adapter.getItem(position); + } + + public long getItemIdAtPosition(int position) { + T adapter = getAdapter(); + return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position); + } + + @Override + public void setOnClickListener(OnClickListener l) { + throw new RuntimeException("Don't call setOnClickListener for an AdapterView. " + + "You probably want setOnItemClickListener instead"); + } + + /** + * Override to prevent freezing of any views created by the adapter. + */ + @Override + protected void dispatchSaveInstanceState(SparseArray container) { + dispatchFreezeSelfOnly(container); + } + + /** + * Override to prevent thawing of any views created by the adapter. + */ + @Override + protected void dispatchRestoreInstanceState(SparseArray container) { + dispatchThawSelfOnly(container); + } + + class AdapterDataSetObserver extends DataSetObserver { + + private Parcelable mInstanceState = null; + + @Override + public void onChanged() { + mDataChanged = true; + mOldItemCount = mItemCount; + mItemCount = getAdapter().getCount(); + + // Detect the case where a cursor that was previously invalidated has + // been repopulated with new data. + if (IcsAdapterView.this.getAdapter().hasStableIds() && mInstanceState != null + && mOldItemCount == 0 && mItemCount > 0) { + IcsAdapterView.this.onRestoreInstanceState(mInstanceState); + mInstanceState = null; + } else { + rememberSyncState(); + } + checkFocus(); + requestLayout(); + } + + @Override + public void onInvalidated() { + mDataChanged = true; + + if (IcsAdapterView.this.getAdapter().hasStableIds()) { + // Remember the current state for the case where our hosting activity is being + // stopped and later restarted + mInstanceState = IcsAdapterView.this.onSaveInstanceState(); + } + + // Data is invalid so we should reset our state + mOldItemCount = mItemCount; + mItemCount = 0; + mSelectedPosition = INVALID_POSITION; + mSelectedRowId = INVALID_ROW_ID; + mNextSelectedPosition = INVALID_POSITION; + mNextSelectedRowId = INVALID_ROW_ID; + mNeedSync = false; + + checkFocus(); + requestLayout(); + } + + public void clearSavedState() { + mInstanceState = null; + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + removeCallbacks(mSelectionNotifier); + } + + private class SelectionNotifier implements Runnable { + public void run() { + if (mDataChanged) { + // Data has changed between when this SelectionNotifier + // was posted and now. We need to wait until the AdapterView + // has been synched to the new data. + if (getAdapter() != null) { + post(this); + } + } else { + fireOnSelected(); + } + } + } + + void selectionChanged() { + if (mOnItemSelectedListener != null) { + if (mInLayout || mBlockLayoutRequests) { + // If we are in a layout traversal, defer notification + // by posting. This ensures that the view tree is + // in a consistent state and is able to accomodate + // new layout or invalidate requests. + if (mSelectionNotifier == null) { + mSelectionNotifier = new SelectionNotifier(); + } + post(mSelectionNotifier); + } else { + fireOnSelected(); + } + } + + // we fire selection events here not in View + if (mSelectedPosition != ListView.INVALID_POSITION && isShown() && !isInTouchMode()) { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + } + } + + private void fireOnSelected() { + if (mOnItemSelectedListener == null) + return; + + int selection = this.getSelectedItemPosition(); + if (selection >= 0) { + View v = getSelectedView(); + mOnItemSelectedListener.onItemSelected(this, v, selection, + getAdapter().getItemId(selection)); + } else { + mOnItemSelectedListener.onNothingSelected(this); + } + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + View selectedView = getSelectedView(); + if (selectedView != null && selectedView.getVisibility() == VISIBLE + && selectedView.dispatchPopulateAccessibilityEvent(event)) { + return true; + } + return false; + } + + @Override + public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { + if (super.onRequestSendAccessibilityEvent(child, event)) { + // Add a record for ourselves as well. + AccessibilityEvent record = AccessibilityEvent.obtain(); + onInitializeAccessibilityEvent(record); + // Populate with the text of the requesting child. + child.dispatchPopulateAccessibilityEvent(record); + event.appendRecord(record); + return true; + } + return false; + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setScrollable(isScrollableForAccessibility()); + View selectedView = getSelectedView(); + if (selectedView != null) { + info.setEnabled(selectedView.isEnabled()); + } + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setScrollable(isScrollableForAccessibility()); + View selectedView = getSelectedView(); + if (selectedView != null) { + event.setEnabled(selectedView.isEnabled()); + } + event.setCurrentItemIndex(getSelectedItemPosition()); + event.setFromIndex(getFirstVisiblePosition()); + event.setToIndex(getLastVisiblePosition()); + event.setItemCount(getCount()); + } + + private boolean isScrollableForAccessibility() { + T adapter = getAdapter(); + if (adapter != null) { + final int itemCount = adapter.getCount(); + return itemCount > 0 + && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1); + } + return false; + } + + @Override + protected boolean canAnimate() { + return super.canAnimate() && mItemCount > 0; + } + + void handleDataChanged() { + final int count = mItemCount; + boolean found = false; + + if (count > 0) { + + int newPos; + + // Find the row we are supposed to sync to + if (mNeedSync) { + // Update this first, since setNextSelectedPositionInt inspects + // it + mNeedSync = false; + + // See if we can find a position in the new data with the same + // id as the old selection + newPos = findSyncPosition(); + if (newPos >= 0) { + // Verify that new selection is selectable + int selectablePos = lookForSelectablePosition(newPos, true); + if (selectablePos == newPos) { + // Same row id is selected + setNextSelectedPositionInt(newPos); + found = true; + } + } + } + if (!found) { + // Try to use the same position if we can't find matching data + newPos = getSelectedItemPosition(); + + // Pin position to the available range + if (newPos >= count) { + newPos = count - 1; + } + if (newPos < 0) { + newPos = 0; + } + + // Make sure we select something selectable -- first look down + int selectablePos = lookForSelectablePosition(newPos, true); + if (selectablePos < 0) { + // Looking down didn't work -- try looking up + selectablePos = lookForSelectablePosition(newPos, false); + } + if (selectablePos >= 0) { + setNextSelectedPositionInt(selectablePos); + checkSelectionChanged(); + found = true; + } + } + } + if (!found) { + // Nothing is selected + mSelectedPosition = INVALID_POSITION; + mSelectedRowId = INVALID_ROW_ID; + mNextSelectedPosition = INVALID_POSITION; + mNextSelectedRowId = INVALID_ROW_ID; + mNeedSync = false; + checkSelectionChanged(); + } + } + + void checkSelectionChanged() { + if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) { + selectionChanged(); + mOldSelectedPosition = mSelectedPosition; + mOldSelectedRowId = mSelectedRowId; + } + } + + /** + * Searches the adapter for a position matching mSyncRowId. The search starts at mSyncPosition + * and then alternates between moving up and moving down until 1) we find the right position, or + * 2) we run out of time, or 3) we have looked at every position + * + * @return Position of the row that matches mSyncRowId, or {@link #INVALID_POSITION} if it can't + * be found + */ + int findSyncPosition() { + int count = mItemCount; + + if (count == 0) { + return INVALID_POSITION; + } + + long idToMatch = mSyncRowId; + int seed = mSyncPosition; + + // If there isn't a selection don't hunt for it + if (idToMatch == INVALID_ROW_ID) { + return INVALID_POSITION; + } + + // Pin seed to reasonable values + seed = Math.max(0, seed); + seed = Math.min(count - 1, seed); + + long endTime = SystemClock.uptimeMillis() + SYNC_MAX_DURATION_MILLIS; + + long rowId; + + // first position scanned so far + int first = seed; + + // last position scanned so far + int last = seed; + + // True if we should move down on the next iteration + boolean next = false; + + // True when we have looked at the first item in the data + boolean hitFirst; + + // True when we have looked at the last item in the data + boolean hitLast; + + // Get the item ID locally (instead of getItemIdAtPosition), so + // we need the adapter + T adapter = getAdapter(); + if (adapter == null) { + return INVALID_POSITION; + } + + while (SystemClock.uptimeMillis() <= endTime) { + rowId = adapter.getItemId(seed); + if (rowId == idToMatch) { + // Found it! + return seed; + } + + hitLast = last == count - 1; + hitFirst = first == 0; + + if (hitLast && hitFirst) { + // Looked at everything + break; + } + + if (hitFirst || (next && !hitLast)) { + // Either we hit the top, or we are trying to move down + last++; + seed = last; + // Try going up next time + next = false; + } else if (hitLast || (!next && !hitFirst)) { + // Either we hit the bottom, or we are trying to move up + first--; + seed = first; + // Try going down next time + next = true; + } + + } + + return INVALID_POSITION; + } + + /** + * Find a position that can be selected (i.e., is not a separator). + * + * @param position The starting position to look at. + * @param lookDown Whether to look down for other positions. + * @return The next selectable position starting at position and then searching either up or + * down. Returns {@link #INVALID_POSITION} if nothing can be found. + */ + int lookForSelectablePosition(int position, boolean lookDown) { + return position; + } + + /** + * Utility to keep mSelectedPosition and mSelectedRowId in sync + * @param position Our current position + */ + void setSelectedPositionInt(int position) { + mSelectedPosition = position; + mSelectedRowId = getItemIdAtPosition(position); + } + + /** + * Utility to keep mNextSelectedPosition and mNextSelectedRowId in sync + * @param position Intended value for mSelectedPosition the next time we go + * through layout + */ + void setNextSelectedPositionInt(int position) { + mNextSelectedPosition = position; + mNextSelectedRowId = getItemIdAtPosition(position); + // If we are trying to sync to the selection, update that too + if (mNeedSync && mSyncMode == SYNC_SELECTED_POSITION && position >= 0) { + mSyncPosition = position; + mSyncRowId = mNextSelectedRowId; + } + } + + /** + * Remember enough information to restore the screen state when the data has + * changed. + * + */ + void rememberSyncState() { + if (getChildCount() > 0) { + mNeedSync = true; + mSyncHeight = mLayoutHeight; + if (mSelectedPosition >= 0) { + // Sync the selection state + View v = getChildAt(mSelectedPosition - mFirstPosition); + mSyncRowId = mNextSelectedRowId; + mSyncPosition = mNextSelectedPosition; + if (v != null) { + mSpecificTop = v.getTop(); + } + mSyncMode = SYNC_SELECTED_POSITION; + } else { + // Sync the based on the offset of the first view + View v = getChildAt(0); + T adapter = getAdapter(); + if (mFirstPosition >= 0 && mFirstPosition < adapter.getCount()) { + mSyncRowId = adapter.getItemId(mFirstPosition); + } else { + mSyncRowId = NO_ID; + } + mSyncPosition = mFirstPosition; + if (v != null) { + mSpecificTop = v.getTop(); + } + mSyncMode = SYNC_FIRST_POSITION; + } + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java new file mode 100644 index 0000000000..a78b3f71b3 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java @@ -0,0 +1,41 @@ +package com.actionbarsherlock.internal.widget; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; + +/** + * A version of {@link android.graphics.drawable.ColorDrawable} that respects bounds. + */ +public class IcsColorDrawable extends Drawable { + private int color; + private final Paint paint = new Paint(); + + public IcsColorDrawable(int color) { + this.color = color; + } + + @Override public void draw(Canvas canvas) { + if ((color >>> 24) != 0) { + paint.setColor(color); + canvas.drawRect(getBounds(), paint); + } + } + + @Override + public void setAlpha(int alpha) { + if (alpha != (color >>> 24)) { + color = (color & 0x00FFFFFF) & (alpha << 24); + invalidateSelf(); + } + } + + @Override public void setColorFilter(ColorFilter colorFilter) { + //Ignored + } + + @Override public int getOpacity() { + return color >>> 24; + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java new file mode 100644 index 0000000000..4947c41df5 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java @@ -0,0 +1,410 @@ +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; + +import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; + +/** + * A simple extension of a regular linear layout that supports the divider API + * of Android 4.0+. The dividers are added adjacent to the children by changing + * their layout params. If you need to rely on the margins which fall in the + * same orientation as the layout you should wrap the child in a simple + * {@link android.widget.FrameLayout} so it can receive the margin. + */ +public class IcsLinearLayout extends NineLinearLayout { + private static final int[] R_styleable_LinearLayout = new int[] { + /* 0 */ android.R.attr.divider, + /* 1 */ android.R.attr.measureWithLargestChild, + /* 2 */ android.R.attr.showDividers, + /* 3 */ android.R.attr.dividerPadding, + }; + private static final int LinearLayout_divider = 0; + private static final int LinearLayout_measureWithLargestChild = 1; + private static final int LinearLayout_showDividers = 2; + private static final int LinearLayout_dividerPadding = 3; + + /** + * Don't show any dividers. + */ + public static final int SHOW_DIVIDER_NONE = 0; + /** + * Show a divider at the beginning of the group. + */ + public static final int SHOW_DIVIDER_BEGINNING = 1; + /** + * Show dividers between each item in the group. + */ + public static final int SHOW_DIVIDER_MIDDLE = 2; + /** + * Show a divider at the end of the group. + */ + public static final int SHOW_DIVIDER_END = 4; + + + private Drawable mDivider; + private int mDividerWidth; + private int mDividerHeight; + private int mShowDividers; + private int mDividerPadding; + + private boolean mUseLargestChild; + + public IcsLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/R_styleable_LinearLayout); + + setDividerDrawable(a.getDrawable(/*com.android.internal.R.styleable.*/LinearLayout_divider)); + mShowDividers = a.getInt(/*com.android.internal.R.styleable.*/LinearLayout_showDividers, SHOW_DIVIDER_NONE); + mDividerPadding = a.getDimensionPixelSize(/*com.android.internal.R.styleable.*/LinearLayout_dividerPadding, 0); + mUseLargestChild = a.getBoolean(/*com.android.internal.R.styleable.*/LinearLayout_measureWithLargestChild, false); + + a.recycle(); + } + + /** + * Set how dividers should be shown between items in this layout + * + * @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING}, + * {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END}, + * or {@link #SHOW_DIVIDER_NONE} to show no dividers. + */ + public void setShowDividers(int showDividers) { + if (showDividers != mShowDividers) { + requestLayout(); + invalidate(); //XXX This is required if you are toggling a divider off + } + mShowDividers = showDividers; + } + + /** + * @return A flag set indicating how dividers should be shown around items. + * @see #setShowDividers(int) + */ + public int getShowDividers() { + return mShowDividers; + } + + /** + * Set a drawable to be used as a divider between items. + * @param divider Drawable that will divide each item. + * @see #setShowDividers(int) + */ + public void setDividerDrawable(Drawable divider) { + if (divider == mDivider) { + return; + } + mDivider = divider; + if (divider != null) { + mDividerWidth = divider.getIntrinsicWidth(); + mDividerHeight = divider.getIntrinsicHeight(); + } else { + mDividerWidth = 0; + mDividerHeight = 0; + } + setWillNotDraw(divider == null); + requestLayout(); + } + + /** + * Set padding displayed on both ends of dividers. + * + * @param padding Padding value in pixels that will be applied to each end + * + * @see #setShowDividers(int) + * @see #setDividerDrawable(Drawable) + * @see #getDividerPadding() + */ + public void setDividerPadding(int padding) { + mDividerPadding = padding; + } + + /** + * Get the padding size used to inset dividers in pixels + * + * @see #setShowDividers(int) + * @see #setDividerDrawable(Drawable) + * @see #setDividerPadding(int) + */ + public int getDividerPadding() { + return mDividerPadding; + } + + /** + * Get the width of the current divider drawable. + * + * @hide Used internally by framework. + */ + public int getDividerWidth() { + return mDividerWidth; + } + + @Override + protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { + final int index = indexOfChild(child); + final int orientation = getOrientation(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); + if (hasDividerBeforeChildAt(index)) { + if (orientation == VERTICAL) { + //Account for the divider by pushing everything up + params.topMargin = mDividerHeight; + } else { + //Account for the divider by pushing everything left + params.leftMargin = mDividerWidth; + } + } + + final int count = getChildCount(); + if (index == count - 1) { + if (hasDividerBeforeChildAt(count)) { + if (orientation == VERTICAL) { + params.bottomMargin = mDividerHeight; + } else { + params.rightMargin = mDividerWidth; + } + } + } + super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed); + } + + @Override + protected void onDraw(Canvas canvas) { + if (mDivider != null) { + if (getOrientation() == VERTICAL) { + drawDividersVertical(canvas); + } else { + drawDividersHorizontal(canvas); + } + } + super.onDraw(canvas); + } + + void drawDividersVertical(Canvas canvas) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + + if (child != null && child.getVisibility() != GONE) { + if (hasDividerBeforeChildAt(i)) { + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + final int top = child.getTop() - lp.topMargin/* - mDividerHeight*/; + drawHorizontalDivider(canvas, top); + } + } + } + + if (hasDividerBeforeChildAt(count)) { + final View child = getChildAt(count - 1); + int bottom = 0; + if (child == null) { + bottom = getHeight() - getPaddingBottom() - mDividerHeight; + } else { + //final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + bottom = child.getBottom()/* + lp.bottomMargin*/; + } + drawHorizontalDivider(canvas, bottom); + } + } + + void drawDividersHorizontal(Canvas canvas) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + + if (child != null && child.getVisibility() != GONE) { + if (hasDividerBeforeChildAt(i)) { + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + final int left = child.getLeft() - lp.leftMargin/* - mDividerWidth*/; + drawVerticalDivider(canvas, left); + } + } + } + + if (hasDividerBeforeChildAt(count)) { + final View child = getChildAt(count - 1); + int right = 0; + if (child == null) { + right = getWidth() - getPaddingRight() - mDividerWidth; + } else { + //final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + right = child.getRight()/* + lp.rightMargin*/; + } + drawVerticalDivider(canvas, right); + } + } + + void drawHorizontalDivider(Canvas canvas, int top) { + mDivider.setBounds(getPaddingLeft() + mDividerPadding, top, + getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight); + mDivider.draw(canvas); + } + + void drawVerticalDivider(Canvas canvas, int left) { + mDivider.setBounds(left, getPaddingTop() + mDividerPadding, + left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding); + mDivider.draw(canvas); + } + + /** + * Determines where to position dividers between children. + * + * @param childIndex Index of child to check for preceding divider + * @return true if there should be a divider before the child at childIndex + * @hide Pending API consideration. Currently only used internally by the system. + */ + protected boolean hasDividerBeforeChildAt(int childIndex) { + if (childIndex == 0) { + return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0; + } else if (childIndex == getChildCount()) { + return (mShowDividers & SHOW_DIVIDER_END) != 0; + } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) { + boolean hasVisibleViewBefore = false; + for (int i = childIndex - 1; i >= 0; i--) { + if (getChildAt(i).getVisibility() != GONE) { + hasVisibleViewBefore = true; + break; + } + } + return hasVisibleViewBefore; + } + return false; + } + + /** + * When true, all children with a weight will be considered having + * the minimum size of the largest child. If false, all children are + * measured normally. + * + * @return True to measure children with a weight using the minimum + * size of the largest child, false otherwise. + * + * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild + */ + public boolean isMeasureWithLargestChildEnabled() { + return mUseLargestChild; + } + + /** + * When set to true, all children with a weight will be considered having + * the minimum size of the largest child. If false, all children are + * measured normally. + * + * Disabled by default. + * + * @param enabled True to measure children with a weight using the + * minimum size of the largest child, false otherwise. + * + * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild + */ + public void setMeasureWithLargestChildEnabled(boolean enabled) { + mUseLargestChild = enabled; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + if (mUseLargestChild) { + final int orientation = getOrientation(); + switch (orientation) { + case HORIZONTAL: + useLargestChildHorizontal(); + break; + + case VERTICAL: + useLargestChildVertical(); + break; + } + } + } + + private void useLargestChildHorizontal() { + final int childCount = getChildCount(); + + // Find largest child width + int largestChildWidth = 0; + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + largestChildWidth = Math.max(child.getMeasuredWidth(), largestChildWidth); + } + + int totalWidth = 0; + // Re-measure childs + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + + if (child == null || child.getVisibility() == View.GONE) { + continue; + } + + final LinearLayout.LayoutParams lp = + (LinearLayout.LayoutParams) child.getLayoutParams(); + + float childExtra = lp.weight; + if (childExtra > 0) { + child.measure( + MeasureSpec.makeMeasureSpec(largestChildWidth, + MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), + MeasureSpec.EXACTLY)); + totalWidth += largestChildWidth; + + } else { + totalWidth += child.getMeasuredWidth(); + } + + totalWidth += lp.leftMargin + lp.rightMargin; + } + + totalWidth += getPaddingLeft() + getPaddingRight(); + setMeasuredDimension(totalWidth, getMeasuredHeight()); + } + + private void useLargestChildVertical() { + final int childCount = getChildCount(); + + // Find largest child width + int largestChildHeight = 0; + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + largestChildHeight = Math.max(child.getMeasuredHeight(), largestChildHeight); + } + + int totalHeight = 0; + // Re-measure childs + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + + if (child == null || child.getVisibility() == View.GONE) { + continue; + } + + final LinearLayout.LayoutParams lp = + (LinearLayout.LayoutParams) child.getLayoutParams(); + + float childExtra = lp.weight; + if (childExtra > 0) { + child.measure( + MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), + MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(largestChildHeight, + MeasureSpec.EXACTLY)); + totalHeight += largestChildHeight; + + } else { + totalHeight += child.getMeasuredHeight(); + } + + totalHeight += lp.leftMargin + lp.rightMargin; + } + + totalHeight += getPaddingLeft() + getPaddingRight(); + setMeasuredDimension(getMeasuredWidth(), totalHeight); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java new file mode 100644 index 0000000000..d13c6cea97 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java @@ -0,0 +1,644 @@ +package com.actionbarsherlock.internal.widget; + +import com.actionbarsherlock.R; + +import android.content.Context; +import android.content.res.Resources; +import android.database.DataSetObserver; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Handler; +import android.util.AttributeSet; +import android.view.ContextThemeWrapper; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.View.OnTouchListener; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.LinearLayout; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.PopupWindow; + +/** + * A proxy between pre- and post-Honeycomb implementations of this class. + */ +public class IcsListPopupWindow { + /** + * This value controls the length of time that the user + * must leave a pointer down without scrolling to expand + * the autocomplete dropdown list to cover the IME. + */ + private static final int EXPAND_LIST_TIMEOUT = 250; + + private Context mContext; + private PopupWindow mPopup; + private ListAdapter mAdapter; + private DropDownListView mDropDownList; + + private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT; + private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT; + private int mDropDownHorizontalOffset; + private int mDropDownVerticalOffset; + private boolean mDropDownVerticalOffsetSet; + + private int mListItemExpandMaximum = Integer.MAX_VALUE; + + private View mPromptView; + private int mPromptPosition = POSITION_PROMPT_ABOVE; + + private DataSetObserver mObserver; + + private View mDropDownAnchorView; + + private Drawable mDropDownListHighlight; + + private AdapterView.OnItemClickListener mItemClickListener; + private AdapterView.OnItemSelectedListener mItemSelectedListener; + + private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable(); + private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor(); + private final PopupScrollListener mScrollListener = new PopupScrollListener(); + private final ListSelectorHider mHideSelector = new ListSelectorHider(); + + private Handler mHandler = new Handler(); + + private Rect mTempRect = new Rect(); + + private boolean mModal; + + public static final int POSITION_PROMPT_ABOVE = 0; + public static final int POSITION_PROMPT_BELOW = 1; + + public IcsListPopupWindow(Context context) { + this(context, null, R.attr.listPopupWindowStyle); + } + + public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { + mContext = context; + mPopup = new PopupWindow(context, attrs, defStyleAttr); + mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); + } + + public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + mContext = context; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + Context wrapped = new ContextThemeWrapper(context, defStyleRes); + mPopup = new PopupWindow(wrapped, attrs, defStyleAttr); + } else { + mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); + } + mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); + } + + public void setAdapter(ListAdapter adapter) { + if (mObserver == null) { + mObserver = new PopupDataSetObserver(); + } else if (mAdapter != null) { + mAdapter.unregisterDataSetObserver(mObserver); + } + mAdapter = adapter; + if (mAdapter != null) { + adapter.registerDataSetObserver(mObserver); + } + + if (mDropDownList != null) { + mDropDownList.setAdapter(mAdapter); + } + } + + public void setPromptPosition(int position) { + mPromptPosition = position; + } + + public void setModal(boolean modal) { + mModal = true; + mPopup.setFocusable(modal); + } + + public void setBackgroundDrawable(Drawable d) { + mPopup.setBackgroundDrawable(d); + } + + public void setAnchorView(View anchor) { + mDropDownAnchorView = anchor; + } + + public void setHorizontalOffset(int offset) { + mDropDownHorizontalOffset = offset; + } + + public void setVerticalOffset(int offset) { + mDropDownVerticalOffset = offset; + mDropDownVerticalOffsetSet = true; + } + + public void setContentWidth(int width) { + Drawable popupBackground = mPopup.getBackground(); + if (popupBackground != null) { + popupBackground.getPadding(mTempRect); + mDropDownWidth = mTempRect.left + mTempRect.right + width; + } else { + mDropDownWidth = width; + } + } + + public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) { + mItemClickListener = clickListener; + } + + public void show() { + int height = buildDropDown(); + + int widthSpec = 0; + int heightSpec = 0; + + boolean noInputMethod = isInputMethodNotNeeded(); + //XXX mPopup.setAllowScrollingAnchorParent(!noInputMethod); + + if (mPopup.isShowing()) { + if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { + // The call to PopupWindow's update method below can accept -1 for any + // value you do not want to update. + widthSpec = -1; + } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { + widthSpec = mDropDownAnchorView.getWidth(); + } else { + widthSpec = mDropDownWidth; + } + + if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { + // The call to PopupWindow's update method below can accept -1 for any + // value you do not want to update. + heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT; + if (noInputMethod) { + mPopup.setWindowLayoutMode( + mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? + ViewGroup.LayoutParams.MATCH_PARENT : 0, 0); + } else { + mPopup.setWindowLayoutMode( + mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? + ViewGroup.LayoutParams.MATCH_PARENT : 0, + ViewGroup.LayoutParams.MATCH_PARENT); + } + } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { + heightSpec = height; + } else { + heightSpec = mDropDownHeight; + } + + mPopup.setOutsideTouchable(true); + + mPopup.update(mDropDownAnchorView, mDropDownHorizontalOffset, + mDropDownVerticalOffset, widthSpec, heightSpec); + } else { + if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { + widthSpec = ViewGroup.LayoutParams.MATCH_PARENT; + } else { + if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { + mPopup.setWidth(mDropDownAnchorView.getWidth()); + } else { + mPopup.setWidth(mDropDownWidth); + } + } + + if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { + heightSpec = ViewGroup.LayoutParams.MATCH_PARENT; + } else { + if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { + mPopup.setHeight(height); + } else { + mPopup.setHeight(mDropDownHeight); + } + } + + mPopup.setWindowLayoutMode(widthSpec, heightSpec); + //XXX mPopup.setClipToScreenEnabled(true); + + // use outside touchable to dismiss drop down when touching outside of it, so + // only set this if the dropdown is not always visible + mPopup.setOutsideTouchable(true); + mPopup.setTouchInterceptor(mTouchInterceptor); + mPopup.showAsDropDown(mDropDownAnchorView, + mDropDownHorizontalOffset, mDropDownVerticalOffset); + mDropDownList.setSelection(ListView.INVALID_POSITION); + + if (!mModal || mDropDownList.isInTouchMode()) { + clearListSelection(); + } + if (!mModal) { + mHandler.post(mHideSelector); + } + } + } + + public void dismiss() { + mPopup.dismiss(); + if (mPromptView != null) { + final ViewParent parent = mPromptView.getParent(); + if (parent instanceof ViewGroup) { + final ViewGroup group = (ViewGroup) parent; + group.removeView(mPromptView); + } + } + mPopup.setContentView(null); + mDropDownList = null; + mHandler.removeCallbacks(mResizePopupRunnable); + } + + public void setOnDismissListener(PopupWindow.OnDismissListener listener) { + mPopup.setOnDismissListener(listener); + } + + public void setInputMethodMode(int mode) { + mPopup.setInputMethodMode(mode); + } + + public void clearListSelection() { + final DropDownListView list = mDropDownList; + if (list != null) { + // WARNING: Please read the comment where mListSelectionHidden is declared + list.mListSelectionHidden = true; + //XXX list.hideSelector(); + list.requestLayout(); + } + } + + public boolean isShowing() { + return mPopup.isShowing(); + } + + private boolean isInputMethodNotNeeded() { + return mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; + } + + public ListView getListView() { + return mDropDownList; + } + + private int buildDropDown() { + ViewGroup dropDownView; + int otherHeights = 0; + + if (mDropDownList == null) { + Context context = mContext; + + mDropDownList = new DropDownListView(context, !mModal); + if (mDropDownListHighlight != null) { + mDropDownList.setSelector(mDropDownListHighlight); + } + mDropDownList.setAdapter(mAdapter); + mDropDownList.setOnItemClickListener(mItemClickListener); + mDropDownList.setFocusable(true); + mDropDownList.setFocusableInTouchMode(true); + mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + public void onItemSelected(AdapterView parent, View view, + int position, long id) { + + if (position != -1) { + DropDownListView dropDownList = mDropDownList; + + if (dropDownList != null) { + dropDownList.mListSelectionHidden = false; + } + } + } + + public void onNothingSelected(AdapterView parent) { + } + }); + mDropDownList.setOnScrollListener(mScrollListener); + + if (mItemSelectedListener != null) { + mDropDownList.setOnItemSelectedListener(mItemSelectedListener); + } + + dropDownView = mDropDownList; + + View hintView = mPromptView; + if (hintView != null) { + // if an hint has been specified, we accomodate more space for it and + // add a text view in the drop down menu, at the bottom of the list + LinearLayout hintContainer = new LinearLayout(context); + hintContainer.setOrientation(LinearLayout.VERTICAL); + + LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f + ); + + switch (mPromptPosition) { + case POSITION_PROMPT_BELOW: + hintContainer.addView(dropDownView, hintParams); + hintContainer.addView(hintView); + break; + + case POSITION_PROMPT_ABOVE: + hintContainer.addView(hintView); + hintContainer.addView(dropDownView, hintParams); + break; + + default: + break; + } + + // measure the hint's height to find how much more vertical space + // we need to add to the drop down's height + int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST); + int heightSpec = MeasureSpec.UNSPECIFIED; + hintView.measure(widthSpec, heightSpec); + + hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); + otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin + + hintParams.bottomMargin; + + dropDownView = hintContainer; + } + + mPopup.setContentView(dropDownView); + } else { + dropDownView = (ViewGroup) mPopup.getContentView(); + final View view = mPromptView; + if (view != null) { + LinearLayout.LayoutParams hintParams = + (LinearLayout.LayoutParams) view.getLayoutParams(); + otherHeights = view.getMeasuredHeight() + hintParams.topMargin + + hintParams.bottomMargin; + } + } + + // getMaxAvailableHeight() subtracts the padding, so we put it back + // to get the available height for the whole window + int padding = 0; + Drawable background = mPopup.getBackground(); + if (background != null) { + background.getPadding(mTempRect); + padding = mTempRect.top + mTempRect.bottom; + + // If we don't have an explicit vertical offset, determine one from the window + // background so that content will line up. + if (!mDropDownVerticalOffsetSet) { + mDropDownVerticalOffset = -mTempRect.top; + } + } + + // Max height available on the screen for a popup. + boolean ignoreBottomDecorations = + mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; + final int maxHeight = /*mPopup.*/getMaxAvailableHeight( + mDropDownAnchorView, mDropDownVerticalOffset, ignoreBottomDecorations); + + if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { + return maxHeight + padding; + } + + final int listContent = /*mDropDownList.*/measureHeightOfChildren(MeasureSpec.UNSPECIFIED, + 0, -1/*ListView.NO_POSITION*/, maxHeight - otherHeights, -1); + // add padding only if the list has items in it, that way we don't show + // the popup if it is not needed + if (listContent > 0) otherHeights += padding; + + return listContent + otherHeights; + } + + private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) { + final Rect displayFrame = new Rect(); + anchor.getWindowVisibleDisplayFrame(displayFrame); + + final int[] anchorPos = new int[2]; + anchor.getLocationOnScreen(anchorPos); + + int bottomEdge = displayFrame.bottom; + if (ignoreBottomDecorations) { + Resources res = anchor.getContext().getResources(); + bottomEdge = res.getDisplayMetrics().heightPixels; + } + final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; + final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; + + // anchorPos[1] is distance from anchor to top of screen + int returnedHeight = Math.max(distanceToBottom, distanceToTop); + if (mPopup.getBackground() != null) { + mPopup.getBackground().getPadding(mTempRect); + returnedHeight -= mTempRect.top + mTempRect.bottom; + } + + return returnedHeight; + } + + private int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition, + final int maxHeight, int disallowPartialChildPosition) { + + final ListAdapter adapter = mAdapter; + if (adapter == null) { + return mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom(); + } + + // Include the padding of the list + int returnedHeight = mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom(); + final int dividerHeight = ((mDropDownList.getDividerHeight() > 0) && mDropDownList.getDivider() != null) ? mDropDownList.getDividerHeight() : 0; + // The previous height value that was less than maxHeight and contained + // no partial children + int prevHeightWithoutPartialChild = 0; + int i; + View child; + + // mItemCount - 1 since endPosition parameter is inclusive + endPosition = (endPosition == -1/*NO_POSITION*/) ? adapter.getCount() - 1 : endPosition; + + for (i = startPosition; i <= endPosition; ++i) { + child = mAdapter.getView(i, null, mDropDownList); + if (mDropDownList.getCacheColorHint() != 0) { + child.setDrawingCacheBackgroundColor(mDropDownList.getCacheColorHint()); + } + + measureScrapChild(child, i, widthMeasureSpec); + + if (i > 0) { + // Count the divider for all but one child + returnedHeight += dividerHeight; + } + + returnedHeight += child.getMeasuredHeight(); + + if (returnedHeight >= maxHeight) { + // We went over, figure out which height to return. If returnedHeight > maxHeight, + // then the i'th position did not fit completely. + return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1) + && (i > disallowPartialChildPosition) // We've past the min pos + && (prevHeightWithoutPartialChild > 0) // We have a prev height + && (returnedHeight != maxHeight) // i'th child did not fit completely + ? prevHeightWithoutPartialChild + : maxHeight; + } + + if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) { + prevHeightWithoutPartialChild = returnedHeight; + } + } + + // At this point, we went through the range of children, and they each + // completely fit, so return the returnedHeight + return returnedHeight; + } + private void measureScrapChild(View child, int position, int widthMeasureSpec) { + ListView.LayoutParams p = (ListView.LayoutParams) child.getLayoutParams(); + if (p == null) { + p = new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT, 0); + child.setLayoutParams(p); + } + //XXX p.viewType = mAdapter.getItemViewType(position); + //XXX p.forceAdd = true; + + int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, + mDropDownList.getPaddingLeft() + mDropDownList.getPaddingRight(), p.width); + int lpHeight = p.height; + int childHeightSpec; + if (lpHeight > 0) { + childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); + } else { + childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + } + child.measure(childWidthSpec, childHeightSpec); + } + + private static class DropDownListView extends ListView { + /* + * WARNING: This is a workaround for a touch mode issue. + * + * Touch mode is propagated lazily to windows. This causes problems in + * the following scenario: + * - Type something in the AutoCompleteTextView and get some results + * - Move down with the d-pad to select an item in the list + * - Move up with the d-pad until the selection disappears + * - Type more text in the AutoCompleteTextView *using the soft keyboard* + * and get new results; you are now in touch mode + * - The selection comes back on the first item in the list, even though + * the list is supposed to be in touch mode + * + * Using the soft keyboard triggers the touch mode change but that change + * is propagated to our window only after the first list layout, therefore + * after the list attempts to resurrect the selection. + * + * The trick to work around this issue is to pretend the list is in touch + * mode when we know that the selection should not appear, that is when + * we know the user moved the selection away from the list. + * + * This boolean is set to true whenever we explicitly hide the list's + * selection and reset to false whenever we know the user moved the + * selection back to the list. + * + * When this boolean is true, isInTouchMode() returns true, otherwise it + * returns super.isInTouchMode(). + */ + private boolean mListSelectionHidden; + + private boolean mHijackFocus; + + public DropDownListView(Context context, boolean hijackFocus) { + super(context, null, /*com.android.internal.*/R.attr.dropDownListViewStyle); + mHijackFocus = hijackFocus; + // TODO: Add an API to control this + setCacheColorHint(0); // Transparent, since the background drawable could be anything. + } + + //XXX @Override + //View obtainView(int position, boolean[] isScrap) { + // View view = super.obtainView(position, isScrap); + + // if (view instanceof TextView) { + // ((TextView) view).setHorizontallyScrolling(true); + // } + + // return view; + //} + + @Override + public boolean isInTouchMode() { + // WARNING: Please read the comment where mListSelectionHidden is declared + return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); + } + + @Override + public boolean hasWindowFocus() { + return mHijackFocus || super.hasWindowFocus(); + } + + @Override + public boolean isFocused() { + return mHijackFocus || super.isFocused(); + } + + @Override + public boolean hasFocus() { + return mHijackFocus || super.hasFocus(); + } + } + + private class PopupDataSetObserver extends DataSetObserver { + @Override + public void onChanged() { + if (isShowing()) { + // Resize the popup to fit new content + show(); + } + } + + @Override + public void onInvalidated() { + dismiss(); + } + } + + private class ListSelectorHider implements Runnable { + public void run() { + clearListSelection(); + } + } + + private class ResizePopupRunnable implements Runnable { + public void run() { + if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() && + mDropDownList.getChildCount() <= mListItemExpandMaximum) { + mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); + show(); + } + } + } + + private class PopupTouchInterceptor implements OnTouchListener { + public boolean onTouch(View v, MotionEvent event) { + final int action = event.getAction(); + final int x = (int) event.getX(); + final int y = (int) event.getY(); + + if (action == MotionEvent.ACTION_DOWN && + mPopup != null && mPopup.isShowing() && + (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) { + mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT); + } else if (action == MotionEvent.ACTION_UP) { + mHandler.removeCallbacks(mResizePopupRunnable); + } + return false; + } + } + + private class PopupScrollListener implements ListView.OnScrollListener { + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, + int totalItemCount) { + + } + + public void onScrollStateChanged(AbsListView view, int scrollState) { + if (scrollState == SCROLL_STATE_TOUCH_SCROLL && + !isInputMethodNotNeeded() && mPopup.getContentView() != null) { + mHandler.removeCallbacks(mResizePopupRunnable); + mResizePopupRunnable.run(); + } + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java new file mode 100644 index 0000000000..433783c7c9 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java @@ -0,0 +1,1193 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.Shader; +import android.graphics.drawable.Animatable; +import android.graphics.drawable.AnimationDrawable; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ClipDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.RoundRectShape; +import android.graphics.drawable.shapes.Shape; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewDebug; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; +import android.view.animation.Transformation; +import android.widget.RemoteViews.RemoteView; + + +/** + *

+ * Visual indicator of progress in some operation. Displays a bar to the user + * representing how far the operation has progressed; the application can + * change the amount of progress (modifying the length of the bar) as it moves + * forward. There is also a secondary progress displayable on a progress bar + * which is useful for displaying intermediate progress, such as the buffer + * level during a streaming playback progress bar. + *

+ * + *

+ * A progress bar can also be made indeterminate. In indeterminate mode, the + * progress bar shows a cyclic animation without an indication of progress. This mode is used by + * applications when the length of the task is unknown. The indeterminate progress bar can be either + * a spinning wheel or a horizontal bar. + *

+ * + *

The following code example shows how a progress bar can be used from + * a worker thread to update the user interface to notify the user of progress: + *

+ * + *
+ * public class MyActivity extends Activity {
+ *     private static final int PROGRESS = 0x1;
+ *
+ *     private ProgressBar mProgress;
+ *     private int mProgressStatus = 0;
+ *
+ *     private Handler mHandler = new Handler();
+ *
+ *     protected void onCreate(Bundle icicle) {
+ *         super.onCreate(icicle);
+ *
+ *         setContentView(R.layout.progressbar_activity);
+ *
+ *         mProgress = (ProgressBar) findViewById(R.id.progress_bar);
+ *
+ *         // Start lengthy operation in a background thread
+ *         new Thread(new Runnable() {
+ *             public void run() {
+ *                 while (mProgressStatus < 100) {
+ *                     mProgressStatus = doWork();
+ *
+ *                     // Update the progress bar
+ *                     mHandler.post(new Runnable() {
+ *                         public void run() {
+ *                             mProgress.setProgress(mProgressStatus);
+ *                         }
+ *                     });
+ *                 }
+ *             }
+ *         }).start();
+ *     }
+ * }
+ * + *

To add a progress bar to a layout file, you can use the {@code <ProgressBar>} element. + * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a + * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal + * Widget.ProgressBar.Horizontal} style, like so:

+ * + *
+ * <ProgressBar
+ *     style="@android:style/Widget.ProgressBar.Horizontal"
+ *     ... />
+ * + *

If you will use the progress bar to show real progress, you must use the horizontal bar. You + * can then increment the progress with {@link #incrementProgressBy incrementProgressBy()} or + * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If + * necessary, you can adjust the maximum value (the value for a full bar) using the {@link + * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed + * below.

+ * + *

Another common style to apply to the progress bar is {@link + * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller + * version of the spinning wheel—useful when waiting for content to load. + * For example, you can insert this kind of progress bar into your default layout for + * a view that will be populated by some content fetched from the Internet—the spinning wheel + * appears immediately and when your application receives the content, it replaces the progress bar + * with the loaded content. For example:

+ * + *
+ * <LinearLayout
+ *     android:orientation="horizontal"
+ *     ... >
+ *     <ProgressBar
+ *         android:layout_width="wrap_content"
+ *         android:layout_height="wrap_content"
+ *         style="@android:style/Widget.ProgressBar.Small"
+ *         android:layout_marginRight="5dp" />
+ *     <TextView
+ *         android:layout_width="wrap_content"
+ *         android:layout_height="wrap_content"
+ *         android:text="@string/loading" />
+ * </LinearLayout>
+ * + *

Other progress bar styles provided by the system include:

+ *
    + *
  • {@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}
  • + *
  • {@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}
  • + *
  • {@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}
  • + *
  • {@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}
  • + *
  • {@link android.R.style#Widget_ProgressBar_Small_Inverse + * Widget.ProgressBar.Small.Inverse}
  • + *
  • {@link android.R.style#Widget_ProgressBar_Large_Inverse + * Widget.ProgressBar.Large.Inverse}
  • + *
+ *

The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary + * if your application uses a light colored theme (a white background).

+ * + *

XML attributes + *

+ * See {@link android.R.styleable#ProgressBar ProgressBar Attributes}, + * {@link android.R.styleable#View View Attributes} + *

+ * + * @attr ref android.R.styleable#ProgressBar_animationResolution + * @attr ref android.R.styleable#ProgressBar_indeterminate + * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior + * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable + * @attr ref android.R.styleable#ProgressBar_indeterminateDuration + * @attr ref android.R.styleable#ProgressBar_indeterminateOnly + * @attr ref android.R.styleable#ProgressBar_interpolator + * @attr ref android.R.styleable#ProgressBar_max + * @attr ref android.R.styleable#ProgressBar_maxHeight + * @attr ref android.R.styleable#ProgressBar_maxWidth + * @attr ref android.R.styleable#ProgressBar_minHeight + * @attr ref android.R.styleable#ProgressBar_minWidth + * @attr ref android.R.styleable#ProgressBar_progress + * @attr ref android.R.styleable#ProgressBar_progressDrawable + * @attr ref android.R.styleable#ProgressBar_secondaryProgress + */ +@RemoteView +public class IcsProgressBar extends View { + private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; + private static final int MAX_LEVEL = 10000; + private static final int ANIMATION_RESOLUTION = 200; + private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200; + + private static final int[] ProgressBar = new int[] { + android.R.attr.maxWidth, + android.R.attr.maxHeight, + android.R.attr.max, + android.R.attr.progress, + android.R.attr.secondaryProgress, + android.R.attr.indeterminate, + android.R.attr.indeterminateOnly, + android.R.attr.indeterminateDrawable, + android.R.attr.progressDrawable, + android.R.attr.indeterminateDuration, + android.R.attr.indeterminateBehavior, + android.R.attr.minWidth, + android.R.attr.minHeight, + android.R.attr.interpolator, + android.R.attr.animationResolution, + }; + private static final int ProgressBar_maxWidth = 0; + private static final int ProgressBar_maxHeight = 1; + private static final int ProgressBar_max = 2; + private static final int ProgressBar_progress = 3; + private static final int ProgressBar_secondaryProgress = 4; + private static final int ProgressBar_indeterminate = 5; + private static final int ProgressBar_indeterminateOnly = 6; + private static final int ProgressBar_indeterminateDrawable = 7; + private static final int ProgressBar_progressDrawable = 8; + private static final int ProgressBar_indeterminateDuration = 9; + private static final int ProgressBar_indeterminateBehavior = 10; + private static final int ProgressBar_minWidth = 11; + private static final int ProgressBar_minHeight = 12; + private static final int ProgressBar_interpolator = 13; + private static final int ProgressBar_animationResolution = 14; + + int mMinWidth; + int mMaxWidth; + int mMinHeight; + int mMaxHeight; + + private int mProgress; + private int mSecondaryProgress; + private int mMax; + + private int mBehavior; + private int mDuration; + private boolean mIndeterminate; + private boolean mOnlyIndeterminate; + private Transformation mTransformation; + private AlphaAnimation mAnimation; + private Drawable mIndeterminateDrawable; + private int mIndeterminateRealLeft; + private int mIndeterminateRealTop; + private Drawable mProgressDrawable; + private Drawable mCurrentDrawable; + Bitmap mSampleTile; + private boolean mNoInvalidate; + private Interpolator mInterpolator; + private RefreshProgressRunnable mRefreshProgressRunnable; + private long mUiThreadId; + private boolean mShouldStartAnimationDrawable; + private long mLastDrawTime; + + private boolean mInDrawing; + + private int mAnimationResolution; + + private AccessibilityManager mAccessibilityManager; + private AccessibilityEventSender mAccessibilityEventSender; + + /** + * Create a new progress bar with range 0...100 and initial progress of 0. + * @param context the application environment + */ + public IcsProgressBar(Context context) { + this(context, null); + } + + public IcsProgressBar(Context context, AttributeSet attrs) { + this(context, attrs, android.R.attr.progressBarStyle); + } + + public IcsProgressBar(Context context, AttributeSet attrs, int defStyle) { + this(context, attrs, defStyle, 0); + } + + /** + * @hide + */ + public IcsProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) { + super(context, attrs, defStyle); + mUiThreadId = Thread.currentThread().getId(); + initProgressBar(); + + TypedArray a = + context.obtainStyledAttributes(attrs, /*R.styleable.*/ProgressBar, defStyle, styleRes); + + mNoInvalidate = true; + + Drawable drawable = a.getDrawable(/*R.styleable.*/ProgressBar_progressDrawable); + if (drawable != null) { + drawable = tileify(drawable, false); + // Calling this method can set mMaxHeight, make sure the corresponding + // XML attribute for mMaxHeight is read after calling this method + setProgressDrawable(drawable); + } + + + mDuration = a.getInt(/*R.styleable.*/ProgressBar_indeterminateDuration, mDuration); + + mMinWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minWidth, mMinWidth); + mMaxWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxWidth, mMaxWidth); + mMinHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minHeight, mMinHeight); + mMaxHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxHeight, mMaxHeight); + + mBehavior = a.getInt(/*R.styleable.*/ProgressBar_indeterminateBehavior, mBehavior); + + final int resID = a.getResourceId( + /*com.android.internal.R.styleable.*/ProgressBar_interpolator, + android.R.anim.linear_interpolator); // default to linear interpolator + if (resID > 0) { + setInterpolator(context, resID); + } + + setMax(a.getInt(/*R.styleable.*/ProgressBar_max, mMax)); + + setProgress(a.getInt(/*R.styleable.*/ProgressBar_progress, mProgress)); + + setSecondaryProgress( + a.getInt(/*R.styleable.*/ProgressBar_secondaryProgress, mSecondaryProgress)); + + drawable = a.getDrawable(/*R.styleable.*/ProgressBar_indeterminateDrawable); + if (drawable != null) { + drawable = tileifyIndeterminate(drawable); + setIndeterminateDrawable(drawable); + } + + mOnlyIndeterminate = a.getBoolean( + /*R.styleable.*/ProgressBar_indeterminateOnly, mOnlyIndeterminate); + + mNoInvalidate = false; + + setIndeterminate(mOnlyIndeterminate || a.getBoolean( + /*R.styleable.*/ProgressBar_indeterminate, mIndeterminate)); + + mAnimationResolution = a.getInteger(/*R.styleable.*/ProgressBar_animationResolution, + ANIMATION_RESOLUTION); + + a.recycle(); + + mAccessibilityManager = (AccessibilityManager)context.getSystemService(Context.ACCESSIBILITY_SERVICE); + } + + /** + * Converts a drawable to a tiled version of itself. It will recursively + * traverse layer and state list drawables. + */ + private Drawable tileify(Drawable drawable, boolean clip) { + + if (drawable instanceof LayerDrawable) { + LayerDrawable background = (LayerDrawable) drawable; + final int N = background.getNumberOfLayers(); + Drawable[] outDrawables = new Drawable[N]; + + for (int i = 0; i < N; i++) { + int id = background.getId(i); + outDrawables[i] = tileify(background.getDrawable(i), + (id == android.R.id.progress || id == android.R.id.secondaryProgress)); + } + + LayerDrawable newBg = new LayerDrawable(outDrawables); + + for (int i = 0; i < N; i++) { + newBg.setId(i, background.getId(i)); + } + + return newBg; + + }/* else if (drawable instanceof StateListDrawable) { + StateListDrawable in = (StateListDrawable) drawable; + StateListDrawable out = new StateListDrawable(); + int numStates = in.getStateCount(); + for (int i = 0; i < numStates; i++) { + out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip)); + } + return out; + + }*/ else if (drawable instanceof BitmapDrawable) { + final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap(); + if (mSampleTile == null) { + mSampleTile = tileBitmap; + } + + final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); + + final BitmapShader bitmapShader = new BitmapShader(tileBitmap, + Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); + shapeDrawable.getPaint().setShader(bitmapShader); + + return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, + ClipDrawable.HORIZONTAL) : shapeDrawable; + } + + return drawable; + } + + Shape getDrawableShape() { + final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 }; + return new RoundRectShape(roundedCorners, null, null); + } + + /** + * Convert a AnimationDrawable for use as a barberpole animation. + * Each frame of the animation is wrapped in a ClipDrawable and + * given a tiling BitmapShader. + */ + private Drawable tileifyIndeterminate(Drawable drawable) { + if (drawable instanceof AnimationDrawable) { + AnimationDrawable background = (AnimationDrawable) drawable; + final int N = background.getNumberOfFrames(); + AnimationDrawable newBg = new AnimationDrawable(); + newBg.setOneShot(background.isOneShot()); + + for (int i = 0; i < N; i++) { + Drawable frame = tileify(background.getFrame(i), true); + frame.setLevel(10000); + newBg.addFrame(frame, background.getDuration(i)); + } + newBg.setLevel(10000); + drawable = newBg; + } + return drawable; + } + + /** + *

+ * Initialize the progress bar's default values: + *

+ *
    + *
  • progress = 0
  • + *
  • max = 100
  • + *
  • animation duration = 4000 ms
  • + *
  • indeterminate = false
  • + *
  • behavior = repeat
  • + *
+ */ + private void initProgressBar() { + mMax = 100; + mProgress = 0; + mSecondaryProgress = 0; + mIndeterminate = false; + mOnlyIndeterminate = false; + mDuration = 4000; + mBehavior = AlphaAnimation.RESTART; + mMinWidth = 24; + mMaxWidth = 48; + mMinHeight = 24; + mMaxHeight = 48; + } + + /** + *

Indicate whether this progress bar is in indeterminate mode.

+ * + * @return true if the progress bar is in indeterminate mode + */ + @ViewDebug.ExportedProperty(category = "progress") + public synchronized boolean isIndeterminate() { + return mIndeterminate; + } + + /** + *

Change the indeterminate mode for this progress bar. In indeterminate + * mode, the progress is ignored and the progress bar shows an infinite + * animation instead.

+ * + * If this progress bar's style only supports indeterminate mode (such as the circular + * progress bars), then this will be ignored. + * + * @param indeterminate true to enable the indeterminate mode + */ + public synchronized void setIndeterminate(boolean indeterminate) { + if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) { + mIndeterminate = indeterminate; + + if (indeterminate) { + // swap between indeterminate and regular backgrounds + mCurrentDrawable = mIndeterminateDrawable; + startAnimation(); + } else { + mCurrentDrawable = mProgressDrawable; + stopAnimation(); + } + } + } + + /** + *

Get the drawable used to draw the progress bar in + * indeterminate mode.

+ * + * @return a {@link android.graphics.drawable.Drawable} instance + * + * @see #setIndeterminateDrawable(android.graphics.drawable.Drawable) + * @see #setIndeterminate(boolean) + */ + public Drawable getIndeterminateDrawable() { + return mIndeterminateDrawable; + } + + /** + *

Define the drawable used to draw the progress bar in + * indeterminate mode.

+ * + * @param d the new drawable + * + * @see #getIndeterminateDrawable() + * @see #setIndeterminate(boolean) + */ + public void setIndeterminateDrawable(Drawable d) { + if (d != null) { + d.setCallback(this); + } + mIndeterminateDrawable = d; + if (mIndeterminate) { + mCurrentDrawable = d; + postInvalidate(); + } + } + + /** + *

Get the drawable used to draw the progress bar in + * progress mode.

+ * + * @return a {@link android.graphics.drawable.Drawable} instance + * + * @see #setProgressDrawable(android.graphics.drawable.Drawable) + * @see #setIndeterminate(boolean) + */ + public Drawable getProgressDrawable() { + return mProgressDrawable; + } + + /** + *

Define the drawable used to draw the progress bar in + * progress mode.

+ * + * @param d the new drawable + * + * @see #getProgressDrawable() + * @see #setIndeterminate(boolean) + */ + public void setProgressDrawable(Drawable d) { + boolean needUpdate; + if (mProgressDrawable != null && d != mProgressDrawable) { + mProgressDrawable.setCallback(null); + needUpdate = true; + } else { + needUpdate = false; + } + + if (d != null) { + d.setCallback(this); + + // Make sure the ProgressBar is always tall enough + int drawableHeight = d.getMinimumHeight(); + if (mMaxHeight < drawableHeight) { + mMaxHeight = drawableHeight; + requestLayout(); + } + } + mProgressDrawable = d; + if (!mIndeterminate) { + mCurrentDrawable = d; + postInvalidate(); + } + + if (needUpdate) { + updateDrawableBounds(getWidth(), getHeight()); + updateDrawableState(); + doRefreshProgress(android.R.id.progress, mProgress, false, false); + doRefreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false, false); + } + } + + /** + * @return The drawable currently used to draw the progress bar + */ + Drawable getCurrentDrawable() { + return mCurrentDrawable; + } + + @Override + protected boolean verifyDrawable(Drawable who) { + return who == mProgressDrawable || who == mIndeterminateDrawable + || super.verifyDrawable(who); + } + + @Override + public void jumpDrawablesToCurrentState() { + super.jumpDrawablesToCurrentState(); + if (mProgressDrawable != null) mProgressDrawable.jumpToCurrentState(); + if (mIndeterminateDrawable != null) mIndeterminateDrawable.jumpToCurrentState(); + } + + @Override + public void postInvalidate() { + if (!mNoInvalidate) { + super.postInvalidate(); + } + } + + private class RefreshProgressRunnable implements Runnable { + + private int mId; + private int mProgress; + private boolean mFromUser; + + RefreshProgressRunnable(int id, int progress, boolean fromUser) { + mId = id; + mProgress = progress; + mFromUser = fromUser; + } + + public void run() { + doRefreshProgress(mId, mProgress, mFromUser, true); + // Put ourselves back in the cache when we are done + mRefreshProgressRunnable = this; + } + + public void setup(int id, int progress, boolean fromUser) { + mId = id; + mProgress = progress; + mFromUser = fromUser; + } + + } + + private synchronized void doRefreshProgress(int id, int progress, boolean fromUser, + boolean callBackToApp) { + float scale = mMax > 0 ? (float) progress / (float) mMax : 0; + final Drawable d = mCurrentDrawable; + if (d != null) { + Drawable progressDrawable = null; + + if (d instanceof LayerDrawable) { + progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id); + } + + final int level = (int) (scale * MAX_LEVEL); + (progressDrawable != null ? progressDrawable : d).setLevel(level); + } else { + invalidate(); + } + + if (callBackToApp && id == android.R.id.progress) { + onProgressRefresh(scale, fromUser); + } + } + + void onProgressRefresh(float scale, boolean fromUser) { + if (mAccessibilityManager.isEnabled()) { + scheduleAccessibilityEventSender(); + } + } + + private synchronized void refreshProgress(int id, int progress, boolean fromUser) { + if (mUiThreadId == Thread.currentThread().getId()) { + doRefreshProgress(id, progress, fromUser, true); + } else { + RefreshProgressRunnable r; + if (mRefreshProgressRunnable != null) { + // Use cached RefreshProgressRunnable if available + r = mRefreshProgressRunnable; + // Uncache it + mRefreshProgressRunnable = null; + r.setup(id, progress, fromUser); + } else { + // Make a new one + r = new RefreshProgressRunnable(id, progress, fromUser); + } + post(r); + } + } + + /** + *

Set the current progress to the specified value. Does not do anything + * if the progress bar is in indeterminate mode.

+ * + * @param progress the new progress, between 0 and {@link #getMax()} + * + * @see #setIndeterminate(boolean) + * @see #isIndeterminate() + * @see #getProgress() + * @see #incrementProgressBy(int) + */ + public synchronized void setProgress(int progress) { + setProgress(progress, false); + } + + synchronized void setProgress(int progress, boolean fromUser) { + if (mIndeterminate) { + return; + } + + if (progress < 0) { + progress = 0; + } + + if (progress > mMax) { + progress = mMax; + } + + if (progress != mProgress) { + mProgress = progress; + refreshProgress(android.R.id.progress, mProgress, fromUser); + } + } + + /** + *

+ * Set the current secondary progress to the specified value. Does not do + * anything if the progress bar is in indeterminate mode. + *

+ * + * @param secondaryProgress the new secondary progress, between 0 and {@link #getMax()} + * @see #setIndeterminate(boolean) + * @see #isIndeterminate() + * @see #getSecondaryProgress() + * @see #incrementSecondaryProgressBy(int) + */ + public synchronized void setSecondaryProgress(int secondaryProgress) { + if (mIndeterminate) { + return; + } + + if (secondaryProgress < 0) { + secondaryProgress = 0; + } + + if (secondaryProgress > mMax) { + secondaryProgress = mMax; + } + + if (secondaryProgress != mSecondaryProgress) { + mSecondaryProgress = secondaryProgress; + refreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false); + } + } + + /** + *

Get the progress bar's current level of progress. Return 0 when the + * progress bar is in indeterminate mode.

+ * + * @return the current progress, between 0 and {@link #getMax()} + * + * @see #setIndeterminate(boolean) + * @see #isIndeterminate() + * @see #setProgress(int) + * @see #setMax(int) + * @see #getMax() + */ + @ViewDebug.ExportedProperty(category = "progress") + public synchronized int getProgress() { + return mIndeterminate ? 0 : mProgress; + } + + /** + *

Get the progress bar's current level of secondary progress. Return 0 when the + * progress bar is in indeterminate mode.

+ * + * @return the current secondary progress, between 0 and {@link #getMax()} + * + * @see #setIndeterminate(boolean) + * @see #isIndeterminate() + * @see #setSecondaryProgress(int) + * @see #setMax(int) + * @see #getMax() + */ + @ViewDebug.ExportedProperty(category = "progress") + public synchronized int getSecondaryProgress() { + return mIndeterminate ? 0 : mSecondaryProgress; + } + + /** + *

Return the upper limit of this progress bar's range.

+ * + * @return a positive integer + * + * @see #setMax(int) + * @see #getProgress() + * @see #getSecondaryProgress() + */ + @ViewDebug.ExportedProperty(category = "progress") + public synchronized int getMax() { + return mMax; + } + + /** + *

Set the range of the progress bar to 0...max.

+ * + * @param max the upper range of this progress bar + * + * @see #getMax() + * @see #setProgress(int) + * @see #setSecondaryProgress(int) + */ + public synchronized void setMax(int max) { + if (max < 0) { + max = 0; + } + if (max != mMax) { + mMax = max; + postInvalidate(); + + if (mProgress > max) { + mProgress = max; + } + refreshProgress(android.R.id.progress, mProgress, false); + } + } + + /** + *

Increase the progress bar's progress by the specified amount.

+ * + * @param diff the amount by which the progress must be increased + * + * @see #setProgress(int) + */ + public synchronized final void incrementProgressBy(int diff) { + setProgress(mProgress + diff); + } + + /** + *

Increase the progress bar's secondary progress by the specified amount.

+ * + * @param diff the amount by which the secondary progress must be increased + * + * @see #setSecondaryProgress(int) + */ + public synchronized final void incrementSecondaryProgressBy(int diff) { + setSecondaryProgress(mSecondaryProgress + diff); + } + + /** + *

Start the indeterminate progress animation.

+ */ + void startAnimation() { + if (getVisibility() != VISIBLE) { + return; + } + + if (mIndeterminateDrawable instanceof Animatable) { + mShouldStartAnimationDrawable = true; + mAnimation = null; + } else { + if (mInterpolator == null) { + mInterpolator = new LinearInterpolator(); + } + + mTransformation = new Transformation(); + mAnimation = new AlphaAnimation(0.0f, 1.0f); + mAnimation.setRepeatMode(mBehavior); + mAnimation.setRepeatCount(Animation.INFINITE); + mAnimation.setDuration(mDuration); + mAnimation.setInterpolator(mInterpolator); + mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME); + } + postInvalidate(); + } + + /** + *

Stop the indeterminate progress animation.

+ */ + void stopAnimation() { + mAnimation = null; + mTransformation = null; + if (mIndeterminateDrawable instanceof Animatable) { + ((Animatable) mIndeterminateDrawable).stop(); + mShouldStartAnimationDrawable = false; + } + postInvalidate(); + } + + /** + * Sets the acceleration curve for the indeterminate animation. + * The interpolator is loaded as a resource from the specified context. + * + * @param context The application environment + * @param resID The resource identifier of the interpolator to load + */ + public void setInterpolator(Context context, int resID) { + setInterpolator(AnimationUtils.loadInterpolator(context, resID)); + } + + /** + * Sets the acceleration curve for the indeterminate animation. + * Defaults to a linear interpolation. + * + * @param interpolator The interpolator which defines the acceleration curve + */ + public void setInterpolator(Interpolator interpolator) { + mInterpolator = interpolator; + } + + /** + * Gets the acceleration curve type for the indeterminate animation. + * + * @return the {@link Interpolator} associated to this animation + */ + public Interpolator getInterpolator() { + return mInterpolator; + } + + @Override + public void setVisibility(int v) { + if (getVisibility() != v) { + super.setVisibility(v); + + if (mIndeterminate) { + // let's be nice with the UI thread + if (v == GONE || v == INVISIBLE) { + stopAnimation(); + } else { + startAnimation(); + } + } + } + } + + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + + if (mIndeterminate) { + // let's be nice with the UI thread + if (visibility == GONE || visibility == INVISIBLE) { + stopAnimation(); + } else { + startAnimation(); + } + } + } + + @Override + public void invalidateDrawable(Drawable dr) { + if (!mInDrawing) { + if (verifyDrawable(dr)) { + final Rect dirty = dr.getBounds(); + final int scrollX = getScrollX() + getPaddingLeft(); + final int scrollY = getScrollY() + getPaddingTop(); + + invalidate(dirty.left + scrollX, dirty.top + scrollY, + dirty.right + scrollX, dirty.bottom + scrollY); + } else { + super.invalidateDrawable(dr); + } + } + } + + /** + * @hide + * + @Override + public int getResolvedLayoutDirection(Drawable who) { + return (who == mProgressDrawable || who == mIndeterminateDrawable) ? + getResolvedLayoutDirection() : super.getResolvedLayoutDirection(who); + } + */ + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + updateDrawableBounds(w, h); + } + + private void updateDrawableBounds(int w, int h) { + // onDraw will translate the canvas so we draw starting at 0,0 + int right = w - getPaddingRight() - getPaddingLeft(); + int bottom = h - getPaddingBottom() - getPaddingTop(); + int top = 0; + int left = 0; + + if (mIndeterminateDrawable != null) { + // Aspect ratio logic does not apply to AnimationDrawables + if (mOnlyIndeterminate && !(mIndeterminateDrawable instanceof AnimationDrawable)) { + // Maintain aspect ratio. Certain kinds of animated drawables + // get very confused otherwise. + final int intrinsicWidth = mIndeterminateDrawable.getIntrinsicWidth(); + final int intrinsicHeight = mIndeterminateDrawable.getIntrinsicHeight(); + final float intrinsicAspect = (float) intrinsicWidth / intrinsicHeight; + final float boundAspect = (float) w / h; + if (intrinsicAspect != boundAspect) { + if (boundAspect > intrinsicAspect) { + // New width is larger. Make it smaller to match height. + final int width = (int) (h * intrinsicAspect); + left = (w - width) / 2; + right = left + width; + } else { + // New height is larger. Make it smaller to match width. + final int height = (int) (w * (1 / intrinsicAspect)); + top = (h - height) / 2; + bottom = top + height; + } + } + } + mIndeterminateDrawable.setBounds(0, 0, right - left, bottom - top); + mIndeterminateRealLeft = left; + mIndeterminateRealTop = top; + } + + if (mProgressDrawable != null) { + mProgressDrawable.setBounds(0, 0, right, bottom); + } + } + + @Override + protected synchronized void onDraw(Canvas canvas) { + super.onDraw(canvas); + + Drawable d = mCurrentDrawable; + if (d != null) { + // Translate canvas so a indeterminate circular progress bar with padding + // rotates properly in its animation + canvas.save(); + canvas.translate(getPaddingLeft() + mIndeterminateRealLeft, getPaddingTop() + mIndeterminateRealTop); + long time = getDrawingTime(); + if (mAnimation != null) { + mAnimation.getTransformation(time, mTransformation); + float scale = mTransformation.getAlpha(); + try { + mInDrawing = true; + d.setLevel((int) (scale * MAX_LEVEL)); + } finally { + mInDrawing = false; + } + if (SystemClock.uptimeMillis() - mLastDrawTime >= mAnimationResolution) { + mLastDrawTime = SystemClock.uptimeMillis(); + postInvalidateDelayed(mAnimationResolution); + } + } + d.draw(canvas); + canvas.restore(); + if (mShouldStartAnimationDrawable && d instanceof Animatable) { + ((Animatable) d).start(); + mShouldStartAnimationDrawable = false; + } + } + } + + @Override + protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + Drawable d = mCurrentDrawable; + + int dw = 0; + int dh = 0; + if (d != null) { + dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth())); + dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight())); + } + updateDrawableState(); + dw += getPaddingLeft() + getPaddingRight(); + dh += getPaddingTop() + getPaddingBottom(); + + if (IS_HONEYCOMB) { + setMeasuredDimension(View.resolveSizeAndState(dw, widthMeasureSpec, 0), + View.resolveSizeAndState(dh, heightMeasureSpec, 0)); + } else { + setMeasuredDimension(View.resolveSize(dw, widthMeasureSpec), + View.resolveSize(dh, heightMeasureSpec)); + } + } + + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + updateDrawableState(); + } + + private void updateDrawableState() { + int[] state = getDrawableState(); + + if (mProgressDrawable != null && mProgressDrawable.isStateful()) { + mProgressDrawable.setState(state); + } + + if (mIndeterminateDrawable != null && mIndeterminateDrawable.isStateful()) { + mIndeterminateDrawable.setState(state); + } + } + + static class SavedState extends BaseSavedState { + int progress; + int secondaryProgress; + + /** + * Constructor called from {@link com.actionbarsherlock.internal.widget.IcsProgressBar#onSaveInstanceState()} + */ + SavedState(Parcelable superState) { + super(superState); + } + + /** + * Constructor called from {@link #CREATOR} + */ + private SavedState(Parcel in) { + super(in); + progress = in.readInt(); + secondaryProgress = in.readInt(); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(progress); + out.writeInt(secondaryProgress); + } + + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + @Override + public Parcelable onSaveInstanceState() { + // Force our ancestor class to save its state + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + + ss.progress = mProgress; + ss.secondaryProgress = mSecondaryProgress; + + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + + setProgress(ss.progress); + setSecondaryProgress(ss.secondaryProgress); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (mIndeterminate) { + startAnimation(); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mIndeterminate) { + stopAnimation(); + } + if(mRefreshProgressRunnable != null) { + removeCallbacks(mRefreshProgressRunnable); + } + if (mAccessibilityEventSender != null) { + removeCallbacks(mAccessibilityEventSender); + } + // This should come after stopAnimation(), otherwise an invalidate message remains in the + // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation + super.onDetachedFromWindow(); + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setItemCount(mMax); + event.setCurrentItemIndex(mProgress); + } + + /** + * Schedule a command for sending an accessibility event. + *
+ * Note: A command is used to ensure that accessibility events + * are sent at most one in a given time frame to save + * system resources while the progress changes quickly. + */ + private void scheduleAccessibilityEventSender() { + if (mAccessibilityEventSender == null) { + mAccessibilityEventSender = new AccessibilityEventSender(); + } else { + removeCallbacks(mAccessibilityEventSender); + } + postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT); + } + + /** + * Command for sending an accessibility event. + */ + private class AccessibilityEventSender implements Runnable { + public void run() { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsSpinner.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsSpinner.java new file mode 100644 index 0000000000..038d1e0318 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsSpinner.java @@ -0,0 +1,703 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.widget; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import com.actionbarsherlock.R; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.res.TypedArray; +import android.database.DataSetObserver; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.SpinnerAdapter; + + +/** + * A view that displays one child at a time and lets the user pick among them. + * The items in the Spinner come from the {@link Adapter} associated with + * this view. + * + *

See the Spinner + * tutorial.

+ * + * @attr ref android.R.styleable#Spinner_prompt + */ +public class IcsSpinner extends IcsAbsSpinner implements OnClickListener { + //private static final String TAG = "Spinner"; + + // Only measure this many items to get a decent max width. + private static final int MAX_ITEMS_MEASURED = 15; + + /** + * Use a dialog window for selecting spinner options. + */ + //public static final int MODE_DIALOG = 0; + + /** + * Use a dropdown anchored to the Spinner for selecting spinner options. + */ + public static final int MODE_DROPDOWN = 1; + + /** + * Use the theme-supplied value to select the dropdown mode. + */ + //private static final int MODE_THEME = -1; + + private SpinnerPopup mPopup; + private DropDownAdapter mTempAdapter; + int mDropDownWidth; + + private int mGravity; + private boolean mDisableChildrenWhenDisabled; + + private Rect mTempRect = new Rect(); + + public IcsSpinner(Context context, AttributeSet attrs) { + this(context, attrs, R.attr.actionDropDownStyle); + } + + /** + * Construct a new spinner with the given context's theme, the supplied attribute set, + * and default style. + * + * @param context The Context the view is running in, through which it can + * access the current theme, resources, etc. + * @param attrs The attributes of the XML tag that is inflating the view. + * @param defStyle The default style to apply to this view. If 0, no style + * will be applied (beyond what is included in the theme). This may + * either be an attribute resource, whose value will be retrieved + * from the current theme, or an explicit style resource. + */ + public IcsSpinner(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.SherlockSpinner, defStyle, 0); + + + DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); + + mDropDownWidth = a.getLayoutDimension( + R.styleable.SherlockSpinner_android_dropDownWidth, + ViewGroup.LayoutParams.WRAP_CONTENT); + popup.setBackgroundDrawable(a.getDrawable( + R.styleable.SherlockSpinner_android_popupBackground)); + final int verticalOffset = a.getDimensionPixelOffset( + R.styleable.SherlockSpinner_android_dropDownVerticalOffset, 0); + if (verticalOffset != 0) { + popup.setVerticalOffset(verticalOffset); + } + + final int horizontalOffset = a.getDimensionPixelOffset( + R.styleable.SherlockSpinner_android_dropDownHorizontalOffset, 0); + if (horizontalOffset != 0) { + popup.setHorizontalOffset(horizontalOffset); + } + + mPopup = popup; + + mGravity = a.getInt(R.styleable.SherlockSpinner_android_gravity, Gravity.CENTER); + + mPopup.setPromptText(a.getString(R.styleable.SherlockSpinner_android_prompt)); + + mDisableChildrenWhenDisabled = true; + + a.recycle(); + + // Base constructor can call setAdapter before we initialize mPopup. + // Finish setting things up if this happened. + if (mTempAdapter != null) { + mPopup.setAdapter(mTempAdapter); + mTempAdapter = null; + } + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + if (mDisableChildrenWhenDisabled) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + getChildAt(i).setEnabled(enabled); + } + } + } + + /** + * Describes how the selected item view is positioned. Currently only the horizontal component + * is used. The default is determined by the current theme. + * + * @param gravity See {@link android.view.Gravity} + * + * @attr ref android.R.styleable#Spinner_gravity + */ + public void setGravity(int gravity) { + if (mGravity != gravity) { + if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) { + gravity |= Gravity.LEFT; + } + mGravity = gravity; + requestLayout(); + } + } + + @Override + public void setAdapter(SpinnerAdapter adapter) { + super.setAdapter(adapter); + + if (mPopup != null) { + mPopup.setAdapter(new DropDownAdapter(adapter)); + } else { + mTempAdapter = new DropDownAdapter(adapter); + } + } + + @Override + public int getBaseline() { + View child = null; + + if (getChildCount() > 0) { + child = getChildAt(0); + } else if (mAdapter != null && mAdapter.getCount() > 0) { + child = makeAndAddView(0); + mRecycler.put(0, child); + removeAllViewsInLayout(); + } + + if (child != null) { + final int childBaseline = child.getBaseline(); + return childBaseline >= 0 ? child.getTop() + childBaseline : -1; + } else { + return -1; + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + if (mPopup != null && mPopup.isShowing()) { + mPopup.dismiss(); + } + } + + /** + *

A spinner does not support item click events. Calling this method + * will raise an exception.

+ * + * @param l this listener will be ignored + */ + @Override + public void setOnItemClickListener(OnItemClickListener l) { + throw new RuntimeException("setOnItemClickListener cannot be used with a spinner."); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (mPopup != null && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) { + final int measuredWidth = getMeasuredWidth(); + setMeasuredDimension(Math.min(Math.max(measuredWidth, + measureContentWidth(getAdapter(), getBackground())), + MeasureSpec.getSize(widthMeasureSpec)), + getMeasuredHeight()); + } + } + + /** + * @see android.view.View#onLayout(boolean,int,int,int,int) + * + * Creates and positions all views + * + */ + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + mInLayout = true; + layout(0, false); + mInLayout = false; + } + + /** + * Creates and positions all views for this Spinner. + * + * @param delta Change in the selected position. +1 moves selection is moving to the right, + * so views are scrolling to the left. -1 means selection is moving to the left. + */ + @Override + void layout(int delta, boolean animate) { + int childrenLeft = mSpinnerPadding.left; + int childrenWidth = getRight() - getLeft() - mSpinnerPadding.left - mSpinnerPadding.right; + + if (mDataChanged) { + handleDataChanged(); + } + + // Handle the empty set by removing all views + if (mItemCount == 0) { + resetList(); + return; + } + + if (mNextSelectedPosition >= 0) { + setSelectedPositionInt(mNextSelectedPosition); + } + + recycleAllViews(); + + // Clear out old views + removeAllViewsInLayout(); + + // Make selected view and position it + mFirstPosition = mSelectedPosition; + View sel = makeAndAddView(mSelectedPosition); + int width = sel.getMeasuredWidth(); + int selectedOffset = childrenLeft; + switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { + case Gravity.CENTER_HORIZONTAL: + selectedOffset = childrenLeft + (childrenWidth / 2) - (width / 2); + break; + case Gravity.RIGHT: + selectedOffset = childrenLeft + childrenWidth - width; + break; + } + sel.offsetLeftAndRight(selectedOffset); + + // Flush any cached views that did not get reused above + mRecycler.clear(); + + invalidate(); + + checkSelectionChanged(); + + mDataChanged = false; + mNeedSync = false; + setNextSelectedPositionInt(mSelectedPosition); + } + + /** + * Obtain a view, either by pulling an existing view from the recycler or + * by getting a new one from the adapter. If we are animating, make sure + * there is enough information in the view's layout parameters to animate + * from the old to new positions. + * + * @param position Position in the spinner for the view to obtain + * @return A view that has been added to the spinner + */ + private View makeAndAddView(int position) { + + View child; + + if (!mDataChanged) { + child = mRecycler.get(position); + if (child != null) { + // Position the view + setUpChild(child); + + return child; + } + } + + // Nothing found in the recycler -- ask the adapter for a view + child = mAdapter.getView(position, null, this); + + // Position the view + setUpChild(child); + + return child; + } + + /** + * Helper for makeAndAddView to set the position of a view + * and fill out its layout paramters. + * + * @param child The view to position + */ + private void setUpChild(View child) { + + // Respect layout params that are already in the view. Otherwise + // make some up... + ViewGroup.LayoutParams lp = child.getLayoutParams(); + if (lp == null) { + lp = generateDefaultLayoutParams(); + } + + addViewInLayout(child, 0, lp); + + child.setSelected(hasFocus()); + if (mDisableChildrenWhenDisabled) { + child.setEnabled(isEnabled()); + } + + // Get measure specs + int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, + mSpinnerPadding.top + mSpinnerPadding.bottom, lp.height); + int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, + mSpinnerPadding.left + mSpinnerPadding.right, lp.width); + + // Measure child + child.measure(childWidthSpec, childHeightSpec); + + int childLeft; + int childRight; + + // Position vertically based on gravity setting + int childTop = mSpinnerPadding.top + + ((getMeasuredHeight() - mSpinnerPadding.bottom - + mSpinnerPadding.top - child.getMeasuredHeight()) / 2); + int childBottom = childTop + child.getMeasuredHeight(); + + int width = child.getMeasuredWidth(); + childLeft = 0; + childRight = childLeft + width; + + child.layout(childLeft, childTop, childRight, childBottom); + } + + @Override + public boolean performClick() { + boolean handled = super.performClick(); + + if (!handled) { + handled = true; + + if (!mPopup.isShowing()) { + mPopup.show(); + } + } + + return handled; + } + + public void onClick(DialogInterface dialog, int which) { + setSelection(which); + dialog.dismiss(); + } + + /** + * Sets the prompt to display when the dialog is shown. + * @param prompt the prompt to set + */ + public void setPrompt(CharSequence prompt) { + mPopup.setPromptText(prompt); + } + + /** + * Sets the prompt to display when the dialog is shown. + * @param promptId the resource ID of the prompt to display when the dialog is shown + */ + public void setPromptId(int promptId) { + setPrompt(getContext().getText(promptId)); + } + + /** + * @return The prompt to display when the dialog is shown + */ + public CharSequence getPrompt() { + return mPopup.getHintText(); + } + + int measureContentWidth(SpinnerAdapter adapter, Drawable background) { + if (adapter == null) { + return 0; + } + + int width = 0; + View itemView = null; + int itemType = 0; + final int widthMeasureSpec = + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final int heightMeasureSpec = + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + + // Make sure the number of items we'll measure is capped. If it's a huge data set + // with wildly varying sizes, oh well. + int start = Math.max(0, getSelectedItemPosition()); + final int end = Math.min(adapter.getCount(), start + MAX_ITEMS_MEASURED); + final int count = end - start; + start = Math.max(0, start - (MAX_ITEMS_MEASURED - count)); + for (int i = start; i < end; i++) { + final int positionType = adapter.getItemViewType(i); + if (positionType != itemType) { + itemType = positionType; + itemView = null; + } + itemView = adapter.getView(i, itemView, this); + if (itemView.getLayoutParams() == null) { + itemView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + } + itemView.measure(widthMeasureSpec, heightMeasureSpec); + width = Math.max(width, itemView.getMeasuredWidth()); + } + + // Add background padding to measured width + if (background != null) { + background.getPadding(mTempRect); + width += mTempRect.left + mTempRect.right; + } + + return width; + } + + /** + *

Wrapper class for an Adapter. Transforms the embedded Adapter instance + * into a ListAdapter.

+ */ + private static class DropDownAdapter implements ListAdapter, SpinnerAdapter { + private SpinnerAdapter mAdapter; + private ListAdapter mListAdapter; + + /** + *

Creates a new ListAdapter wrapper for the specified adapter.

+ * + * @param adapter the Adapter to transform into a ListAdapter + */ + public DropDownAdapter(SpinnerAdapter adapter) { + this.mAdapter = adapter; + if (adapter instanceof ListAdapter) { + this.mListAdapter = (ListAdapter) adapter; + } + } + + public int getCount() { + return mAdapter == null ? 0 : mAdapter.getCount(); + } + + public Object getItem(int position) { + return mAdapter == null ? null : mAdapter.getItem(position); + } + + public long getItemId(int position) { + return mAdapter == null ? -1 : mAdapter.getItemId(position); + } + + public View getView(int position, View convertView, ViewGroup parent) { + return getDropDownView(position, convertView, parent); + } + + public View getDropDownView(int position, View convertView, ViewGroup parent) { + return mAdapter == null ? null : + mAdapter.getDropDownView(position, convertView, parent); + } + + public boolean hasStableIds() { + return mAdapter != null && mAdapter.hasStableIds(); + } + + public void registerDataSetObserver(DataSetObserver observer) { + if (mAdapter != null) { + mAdapter.registerDataSetObserver(observer); + } + } + + public void unregisterDataSetObserver(DataSetObserver observer) { + if (mAdapter != null) { + mAdapter.unregisterDataSetObserver(observer); + } + } + + /** + * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call. + * Otherwise, return true. + */ + public boolean areAllItemsEnabled() { + final ListAdapter adapter = mListAdapter; + if (adapter != null) { + return adapter.areAllItemsEnabled(); + } else { + return true; + } + } + + /** + * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call. + * Otherwise, return true. + */ + public boolean isEnabled(int position) { + final ListAdapter adapter = mListAdapter; + if (adapter != null) { + return adapter.isEnabled(position); + } else { + return true; + } + } + + public int getItemViewType(int position) { + return 0; + } + + public int getViewTypeCount() { + return 1; + } + + public boolean isEmpty() { + return getCount() == 0; + } + } + + /** + * Implements some sort of popup selection interface for selecting a spinner option. + * Allows for different spinner modes. + */ + private interface SpinnerPopup { + public void setAdapter(ListAdapter adapter); + + /** + * Show the popup + */ + public void show(); + + /** + * Dismiss the popup + */ + public void dismiss(); + + /** + * @return true if the popup is showing, false otherwise. + */ + public boolean isShowing(); + + /** + * Set hint text to be displayed to the user. This should provide + * a description of the choice being made. + * @param hintText Hint text to set. + */ + public void setPromptText(CharSequence hintText); + public CharSequence getHintText(); + } + + /* + private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener { + private AlertDialog mPopup; + private ListAdapter mListAdapter; + private CharSequence mPrompt; + + public void dismiss() { + mPopup.dismiss(); + mPopup = null; + } + + public boolean isShowing() { + return mPopup != null ? mPopup.isShowing() : false; + } + + public void setAdapter(ListAdapter adapter) { + mListAdapter = adapter; + } + + public void setPromptText(CharSequence hintText) { + mPrompt = hintText; + } + + public CharSequence getHintText() { + return mPrompt; + } + + public void show() { + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + if (mPrompt != null) { + builder.setTitle(mPrompt); + } + mPopup = builder.setSingleChoiceItems(mListAdapter, + getSelectedItemPosition(), this).show(); + } + + public void onClick(DialogInterface dialog, int which) { + setSelection(which); + dismiss(); + } + } + */ + + private class DropdownPopup extends IcsListPopupWindow implements SpinnerPopup { + private CharSequence mHintText; + private ListAdapter mAdapter; + + public DropdownPopup(Context context, AttributeSet attrs, int defStyleRes) { + super(context, attrs, 0, defStyleRes); + + setAnchorView(IcsSpinner.this); + setModal(true); + setPromptPosition(POSITION_PROMPT_ABOVE); + setOnItemClickListener(new OnItemClickListener() { + @SuppressWarnings("rawtypes") + public void onItemClick(AdapterView parent, View v, int position, long id) { + IcsSpinner.this.setSelection(position); + dismiss(); + } + }); + } + + @Override + public void setAdapter(ListAdapter adapter) { + super.setAdapter(adapter); + mAdapter = adapter; + } + + public CharSequence getHintText() { + return mHintText; + } + + public void setPromptText(CharSequence hintText) { + // Hint text is ignored for dropdowns, but maintain it here. + mHintText = hintText; + } + + @Override + public void show() { + final int spinnerPaddingLeft = IcsSpinner.this.getPaddingLeft(); + if (mDropDownWidth == WRAP_CONTENT) { + final int spinnerWidth = IcsSpinner.this.getWidth(); + final int spinnerPaddingRight = IcsSpinner.this.getPaddingRight(); + setContentWidth(Math.max( + measureContentWidth((SpinnerAdapter) mAdapter, getBackground()), + spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight)); + } else if (mDropDownWidth == MATCH_PARENT) { + final int spinnerWidth = IcsSpinner.this.getWidth(); + final int spinnerPaddingRight = IcsSpinner.this.getPaddingRight(); + setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight); + } else { + setContentWidth(mDropDownWidth); + } + final Drawable background = getBackground(); + int bgOffset = 0; + if (background != null) { + background.getPadding(mTempRect); + bgOffset = -mTempRect.left; + } + setHorizontalOffset(bgOffset + spinnerPaddingLeft); + setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); + super.show(); + getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); + setSelection(IcsSpinner.this.getSelectedItemPosition()); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsView.java new file mode 100644 index 0000000000..a7185d082c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/IcsView.java @@ -0,0 +1,21 @@ +package com.actionbarsherlock.internal.widget; + +import android.view.View; + +final class IcsView { + //No instances + private IcsView() {} + + /** + * Return only the state bits of {@link #getMeasuredWidthAndState()} + * and {@link #getMeasuredHeightAndState()}, combined into one integer. + * The width component is in the regular bits {@link #MEASURED_STATE_MASK} + * and the height component is at the shifted bits + * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}. + */ + public static int getMeasuredStateInt(View child) { + return (child.getMeasuredWidth()&View.MEASURED_STATE_MASK) + | ((child.getMeasuredHeight()>>View.MEASURED_HEIGHT_STATE_SHIFT) + & (View.MEASURED_STATE_MASK>>View.MEASURED_HEIGHT_STATE_SHIFT)); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java new file mode 100644 index 0000000000..48fb5d8b4f --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java @@ -0,0 +1,546 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.text.TextUtils.TruncateAt; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import com.actionbarsherlock.R; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; +import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; +import com.actionbarsherlock.internal.nineoldandroids.widget.NineHorizontalScrollView; + +/** + * This widget implements the dynamic action bar tab behavior that can change + * across different configurations or circumstances. + */ +public class ScrollingTabContainerView extends NineHorizontalScrollView + implements IcsAdapterView.OnItemSelectedListener { + //UNUSED private static final String TAG = "ScrollingTabContainerView"; + Runnable mTabSelector; + private TabClickListener mTabClickListener; + + private IcsLinearLayout mTabLayout; + private IcsSpinner mTabSpinner; + private boolean mAllowCollapse; + + private LayoutInflater mInflater; + + int mMaxTabWidth; + private int mContentHeight; + private int mSelectedTabIndex; + + protected Animator mVisibilityAnim; + protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); + + private static final /*Time*/Interpolator sAlphaInterpolator = new DecelerateInterpolator(); + + private static final int FADE_DURATION = 200; + + public ScrollingTabContainerView(Context context) { + super(context); + setHorizontalScrollBarEnabled(false); + + TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, + R.attr.actionBarStyle, 0); + setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); + a.recycle(); + + mInflater = LayoutInflater.from(context); + + mTabLayout = createTabLayout(); + addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + } + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY; + setFillViewport(lockedExpanded); + + final int childCount = mTabLayout.getChildCount(); + if (childCount > 1 && + (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) { + if (childCount > 2) { + mMaxTabWidth = (int) (MeasureSpec.getSize(widthMeasureSpec) * 0.4f); + } else { + mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2; + } + } else { + mMaxTabWidth = -1; + } + + heightMeasureSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY); + + final boolean canCollapse = !lockedExpanded && mAllowCollapse; + + if (canCollapse) { + // See if we should expand + mTabLayout.measure(MeasureSpec.UNSPECIFIED, heightMeasureSpec); + if (mTabLayout.getMeasuredWidth() > MeasureSpec.getSize(widthMeasureSpec)) { + performCollapse(); + } else { + performExpand(); + } + } else { + performExpand(); + } + + final int oldWidth = getMeasuredWidth(); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + final int newWidth = getMeasuredWidth(); + + if (lockedExpanded && oldWidth != newWidth) { + // Recenter the tab display if we're at a new (scrollable) size. + setTabSelected(mSelectedTabIndex); + } + } + + /** + * Indicates whether this view is collapsed into a dropdown menu instead + * of traditional tabs. + * @return true if showing as a spinner + */ + private boolean isCollapsed() { + return mTabSpinner != null && mTabSpinner.getParent() == this; + } + + public void setAllowCollapse(boolean allowCollapse) { + mAllowCollapse = allowCollapse; + } + + private void performCollapse() { + if (isCollapsed()) return; + + if (mTabSpinner == null) { + mTabSpinner = createSpinner(); + } + removeView(mTabLayout); + addView(mTabSpinner, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + if (mTabSpinner.getAdapter() == null) { + mTabSpinner.setAdapter(new TabAdapter()); + } + if (mTabSelector != null) { + removeCallbacks(mTabSelector); + mTabSelector = null; + } + mTabSpinner.setSelection(mSelectedTabIndex); + } + + private boolean performExpand() { + if (!isCollapsed()) return false; + + removeView(mTabSpinner); + addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + setTabSelected(mTabSpinner.getSelectedItemPosition()); + return false; + } + + public void setTabSelected(int position) { + mSelectedTabIndex = position; + final int tabCount = mTabLayout.getChildCount(); + for (int i = 0; i < tabCount; i++) { + final View child = mTabLayout.getChildAt(i); + final boolean isSelected = i == position; + child.setSelected(isSelected); + if (isSelected) { + animateToTab(position); + } + } + } + + public void setContentHeight(int contentHeight) { + mContentHeight = contentHeight; + requestLayout(); + } + + private IcsLinearLayout createTabLayout() { + final IcsLinearLayout tabLayout = (IcsLinearLayout) LayoutInflater.from(getContext()) + .inflate(R.layout.abs__action_bar_tab_bar_view, null); + tabLayout.setMeasureWithLargestChildEnabled(true); + tabLayout.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); + return tabLayout; + } + + private IcsSpinner createSpinner() { + final IcsSpinner spinner = new IcsSpinner(getContext(), null, + R.attr.actionDropDownStyle); + spinner.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); + spinner.setOnItemSelectedListener(this); + return spinner; + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + // Action bar can change size on configuration changes. + // Reread the desired height from the theme-specified style. + TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, + R.attr.actionBarStyle, 0); + setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); + a.recycle(); + } + + public void animateToVisibility(int visibility) { + if (mVisibilityAnim != null) { + mVisibilityAnim.cancel(); + } + if (visibility == VISIBLE) { + if (getVisibility() != VISIBLE) { + setAlpha(0); + } + ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1); + anim.setDuration(FADE_DURATION); + anim.setInterpolator(sAlphaInterpolator); + + anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); + anim.start(); + } else { + ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0); + anim.setDuration(FADE_DURATION); + anim.setInterpolator(sAlphaInterpolator); + + anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); + anim.start(); + } + } + + public void animateToTab(final int position) { + final View tabView = mTabLayout.getChildAt(position); + if (mTabSelector != null) { + removeCallbacks(mTabSelector); + } + mTabSelector = new Runnable() { + public void run() { + final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2; + smoothScrollTo(scrollPos, 0); + mTabSelector = null; + } + }; + post(mTabSelector); + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + if (mTabSelector != null) { + // Re-post the selector we saved + post(mTabSelector); + } + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mTabSelector != null) { + removeCallbacks(mTabSelector); + } + } + + private TabView createTabView(ActionBar.Tab tab, boolean forAdapter) { + //Workaround for not being able to pass a defStyle on pre-3.0 + final TabView tabView = (TabView)mInflater.inflate(R.layout.abs__action_bar_tab, null); + tabView.init(this, tab, forAdapter); + + if (forAdapter) { + tabView.setBackgroundDrawable(null); + tabView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, + mContentHeight)); + } else { + tabView.setFocusable(true); + + if (mTabClickListener == null) { + mTabClickListener = new TabClickListener(); + } + tabView.setOnClickListener(mTabClickListener); + } + return tabView; + } + + public void addTab(ActionBar.Tab tab, boolean setSelected) { + TabView tabView = createTabView(tab, false); + mTabLayout.addView(tabView, new IcsLinearLayout.LayoutParams(0, + LayoutParams.MATCH_PARENT, 1)); + if (mTabSpinner != null) { + ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); + } + if (setSelected) { + tabView.setSelected(true); + } + if (mAllowCollapse) { + requestLayout(); + } + } + + public void addTab(ActionBar.Tab tab, int position, boolean setSelected) { + final TabView tabView = createTabView(tab, false); + mTabLayout.addView(tabView, position, new IcsLinearLayout.LayoutParams( + 0, LayoutParams.MATCH_PARENT, 1)); + if (mTabSpinner != null) { + ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); + } + if (setSelected) { + tabView.setSelected(true); + } + if (mAllowCollapse) { + requestLayout(); + } + } + + public void updateTab(int position) { + ((TabView) mTabLayout.getChildAt(position)).update(); + if (mTabSpinner != null) { + ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); + } + if (mAllowCollapse) { + requestLayout(); + } + } + + public void removeTabAt(int position) { + mTabLayout.removeViewAt(position); + if (mTabSpinner != null) { + ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); + } + if (mAllowCollapse) { + requestLayout(); + } + } + + public void removeAllTabs() { + mTabLayout.removeAllViews(); + if (mTabSpinner != null) { + ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); + } + if (mAllowCollapse) { + requestLayout(); + } + } + + @Override + public void onItemSelected(IcsAdapterView parent, View view, int position, long id) { + TabView tabView = (TabView) view; + tabView.getTab().select(); + } + + @Override + public void onNothingSelected(IcsAdapterView parent) { + } + + public static class TabView extends LinearLayout { + private ScrollingTabContainerView mParent; + private ActionBar.Tab mTab; + private CapitalizingTextView mTextView; + private ImageView mIconView; + private View mCustomView; + + public TabView(Context context, AttributeSet attrs) { + //TODO super(context, null, R.attr.actionBarTabStyle); + super(context, attrs); + } + + public void init(ScrollingTabContainerView parent, ActionBar.Tab tab, boolean forList) { + mParent = parent; + mTab = tab; + + if (forList) { + setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); + } + + update(); + } + + public void bindTab(ActionBar.Tab tab) { + mTab = tab; + update(); + } + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + // Re-measure if we went beyond our maximum size. + if (mParent.mMaxTabWidth > 0 && getMeasuredWidth() > mParent.mMaxTabWidth) { + super.onMeasure(MeasureSpec.makeMeasureSpec(mParent.mMaxTabWidth, MeasureSpec.EXACTLY), + heightMeasureSpec); + } + } + + public void update() { + final ActionBar.Tab tab = mTab; + final View custom = tab.getCustomView(); + if (custom != null) { + final ViewParent customParent = custom.getParent(); + if (customParent != this) { + if (customParent != null) ((ViewGroup) customParent).removeView(custom); + addView(custom); + } + mCustomView = custom; + if (mTextView != null) mTextView.setVisibility(GONE); + if (mIconView != null) { + mIconView.setVisibility(GONE); + mIconView.setImageDrawable(null); + } + } else { + if (mCustomView != null) { + removeView(mCustomView); + mCustomView = null; + } + + final Drawable icon = tab.getIcon(); + final CharSequence text = tab.getText(); + + if (icon != null) { + if (mIconView == null) { + ImageView iconView = new ImageView(getContext()); + LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.CENTER_VERTICAL; + iconView.setLayoutParams(lp); + addView(iconView, 0); + mIconView = iconView; + } + mIconView.setImageDrawable(icon); + mIconView.setVisibility(VISIBLE); + } else if (mIconView != null) { + mIconView.setVisibility(GONE); + mIconView.setImageDrawable(null); + } + + if (text != null) { + if (mTextView == null) { + CapitalizingTextView textView = new CapitalizingTextView(getContext(), null, + R.attr.actionBarTabTextStyle); + textView.setEllipsize(TruncateAt.END); + LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.CENTER_VERTICAL; + textView.setLayoutParams(lp); + addView(textView); + mTextView = textView; + } + mTextView.setTextCompat(text); + mTextView.setVisibility(VISIBLE); + } else if (mTextView != null) { + mTextView.setVisibility(GONE); + mTextView.setText(null); + } + + if (mIconView != null) { + mIconView.setContentDescription(tab.getContentDescription()); + } + } + } + + public ActionBar.Tab getTab() { + return mTab; + } + } + + private class TabAdapter extends BaseAdapter { + @Override + public int getCount() { + return mTabLayout.getChildCount(); + } + + @Override + public Object getItem(int position) { + return ((TabView) mTabLayout.getChildAt(position)).getTab(); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = createTabView((ActionBar.Tab) getItem(position), true); + } else { + ((TabView) convertView).bindTab((ActionBar.Tab) getItem(position)); + } + return convertView; + } + } + + private class TabClickListener implements OnClickListener { + public void onClick(View view) { + TabView tabView = (TabView) view; + tabView.getTab().select(); + final int tabCount = mTabLayout.getChildCount(); + for (int i = 0; i < tabCount; i++) { + final View child = mTabLayout.getChildAt(i); + child.setSelected(child == view); + } + } + } + + protected class VisibilityAnimListener implements Animator.AnimatorListener { + private boolean mCanceled = false; + private int mFinalVisibility; + + public VisibilityAnimListener withFinalVisibility(int visibility) { + mFinalVisibility = visibility; + return this; + } + + @Override + public void onAnimationStart(Animator animation) { + setVisibility(VISIBLE); + mVisibilityAnim = animation; + mCanceled = false; + } + + @Override + public void onAnimationEnd(Animator animation) { + if (mCanceled) return; + + mVisibilityAnim = null; + setVisibility(mFinalVisibility); + } + + @Override + public void onAnimationCancel(Animator animation) { + mCanceled = true; + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionMode.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionMode.java new file mode 100644 index 0000000000..73f1876950 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionMode.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.view; + +import android.view.View; + + +/** + * Represents a contextual mode of the user interface. Action modes can be used for + * modal interactions with content and replace parts of the normal UI until finished. + * Examples of good action modes include selection modes, search, content editing, etc. + */ +public abstract class ActionMode { + private Object mTag; + + /** + * Set a tag object associated with this ActionMode. + * + *

Like the tag available to views, this allows applications to associate arbitrary + * data with an ActionMode for later reference. + * + * @param tag Tag to associate with this ActionMode + * + * @see #getTag() + */ + public void setTag(Object tag) { + mTag = tag; + } + + /** + * Retrieve the tag object associated with this ActionMode. + * + *

Like the tag available to views, this allows applications to associate arbitrary + * data with an ActionMode for later reference. + * + * @return Tag associated with this ActionMode + * + * @see #setTag(Object) + */ + public Object getTag() { + return mTag; + } + + /** + * Set the title of the action mode. This method will have no visible effect if + * a custom view has been set. + * + * @param title Title string to set + * + * @see #setTitle(int) + * @see #setCustomView(View) + */ + public abstract void setTitle(CharSequence title); + + /** + * Set the title of the action mode. This method will have no visible effect if + * a custom view has been set. + * + * @param resId Resource ID of a string to set as the title + * + * @see #setTitle(CharSequence) + * @see #setCustomView(View) + */ + public abstract void setTitle(int resId); + + /** + * Set the subtitle of the action mode. This method will have no visible effect if + * a custom view has been set. + * + * @param subtitle Subtitle string to set + * + * @see #setSubtitle(int) + * @see #setCustomView(View) + */ + public abstract void setSubtitle(CharSequence subtitle); + + /** + * Set the subtitle of the action mode. This method will have no visible effect if + * a custom view has been set. + * + * @param resId Resource ID of a string to set as the subtitle + * + * @see #setSubtitle(CharSequence) + * @see #setCustomView(View) + */ + public abstract void setSubtitle(int resId); + + /** + * Set a custom view for this action mode. The custom view will take the place of + * the title and subtitle. Useful for things like search boxes. + * + * @param view Custom view to use in place of the title/subtitle. + * + * @see #setTitle(CharSequence) + * @see #setSubtitle(CharSequence) + */ + public abstract void setCustomView(View view); + + /** + * Invalidate the action mode and refresh menu content. The mode's + * {@link com.actionbarsherlock.view.ActionMode.Callback} will have its + * {@link com.actionbarsherlock.view.ActionMode.Callback#onPrepareActionMode(com.actionbarsherlock.view.ActionMode, Menu)} method called. + * If it returns true the menu will be scanned for updated content and any relevant changes + * will be reflected to the user. + */ + public abstract void invalidate(); + + /** + * Finish and close this action mode. The action mode's {@link com.actionbarsherlock.view.ActionMode.Callback} will + * have its {@link com.actionbarsherlock.view.ActionMode.Callback#onDestroyActionMode(com.actionbarsherlock.view.ActionMode)} method called. + */ + public abstract void finish(); + + /** + * Returns the menu of actions that this action mode presents. + * @return The action mode's menu. + */ + public abstract Menu getMenu(); + + /** + * Returns the current title of this action mode. + * @return Title text + */ + public abstract CharSequence getTitle(); + + /** + * Returns the current subtitle of this action mode. + * @return Subtitle text + */ + public abstract CharSequence getSubtitle(); + + /** + * Returns the current custom view for this action mode. + * @return The current custom view + */ + public abstract View getCustomView(); + + /** + * Returns a {@link MenuInflater} with the ActionMode's context. + */ + public abstract MenuInflater getMenuInflater(); + + /** + * Returns whether the UI presenting this action mode can take focus or not. + * This is used by internal components within the framework that would otherwise + * present an action mode UI that requires focus, such as an EditText as a custom view. + * + * @return true if the UI used to show this action mode can take focus + * @hide Internal use only + */ + public boolean isUiFocusable() { + return true; + } + + /** + * Callback interface for action modes. Supplied to + * {@link View#startActionMode(com.actionbarsherlock.view.ActionMode.Callback)}, a Callback + * configures and handles events raised by a user's interaction with an action mode. + * + *

An action mode's lifecycle is as follows: + *

    + *
  • {@link com.actionbarsherlock.view.ActionMode.Callback#onCreateActionMode(com.actionbarsherlock.view.ActionMode, Menu)} once on initial + * creation
  • + *
  • {@link com.actionbarsherlock.view.ActionMode.Callback#onPrepareActionMode(com.actionbarsherlock.view.ActionMode, Menu)} after creation + * and any time the {@link com.actionbarsherlock.view.ActionMode} is invalidated
  • + *
  • {@link com.actionbarsherlock.view.ActionMode.Callback#onActionItemClicked(com.actionbarsherlock.view.ActionMode, MenuItem)} any time a + * contextual action button is clicked
  • + *
  • {@link com.actionbarsherlock.view.ActionMode.Callback#onDestroyActionMode(com.actionbarsherlock.view.ActionMode)} when the action mode + * is closed
  • + *
+ */ + public interface Callback { + /** + * Called when action mode is first created. The menu supplied will be used to + * generate action buttons for the action mode. + * + * @param mode ActionMode being created + * @param menu Menu used to populate action buttons + * @return true if the action mode should be created, false if entering this + * mode should be aborted. + */ + public boolean onCreateActionMode(ActionMode mode, Menu menu); + + /** + * Called to refresh an action mode's action menu whenever it is invalidated. + * + * @param mode ActionMode being prepared + * @param menu Menu used to populate action buttons + * @return true if the menu or action mode was updated, false otherwise. + */ + public boolean onPrepareActionMode(ActionMode mode, Menu menu); + + /** + * Called to report a user click on an action button. + * + * @param mode The current ActionMode + * @param item The item that was clicked + * @return true if this callback handled the event, false if the standard MenuItem + * invocation should continue. + */ + public boolean onActionItemClicked(ActionMode mode, MenuItem item); + + /** + * Called when an action mode is about to be exited and destroyed. + * + * @param mode The current ActionMode being destroyed + */ + public void onDestroyActionMode(ActionMode mode); + } +} \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionProvider.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionProvider.java new file mode 100644 index 0000000000..e49e95ec3e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/ActionProvider.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.view; + +import android.content.Context; +import android.view.View; + +/** + * This class is a mediator for accomplishing a given task, for example sharing a file. + * It is responsible for creating a view that performs an action that accomplishes the task. + * This class also implements other functions such a performing a default action. + *

+ * An ActionProvider can be optionally specified for a {@link MenuItem} and in such a + * case it will be responsible for creating the action view that appears in the + * {@link android.app.ActionBar} as a substitute for the menu item when the item is + * displayed as an action item. Also the provider is responsible for performing a + * default action if a menu item placed on the overflow menu of the ActionBar is + * selected and none of the menu item callbacks has handled the selection. For this + * case the provider can also optionally provide a sub-menu for accomplishing the + * task at hand. + *

+ *

+ * There are two ways for using an action provider for creating and handling of action views: + *

    + *
  • + * Setting the action provider on a {@link MenuItem} directly by calling + * {@link MenuItem#setActionProvider(com.actionbarsherlock.view.ActionProvider)}. + *
  • + *
  • + * Declaring the action provider in the menu XML resource. For example: + *
    + * 
    + *   <item android:id="@+id/my_menu_item"
    + *     android:title="Title"
    + *     android:icon="@drawable/my_menu_item_icon"
    + *     android:showAsAction="ifRoom"
    + *     android:actionProviderClass="foo.bar.SomeActionProvider" />
    + * 
    + * 
    + *
  • + *
+ *

+ * + * @see MenuItem#setActionProvider(com.actionbarsherlock.view.ActionProvider) + * @see MenuItem#getActionProvider() + */ +public abstract class ActionProvider { + private SubUiVisibilityListener mSubUiVisibilityListener; + + /** + * Creates a new instance. + * + * @param context Context for accessing resources. + */ + public ActionProvider(Context context) { + } + + /** + * Factory method for creating new action views. + * + * @return A new action view. + */ + public abstract View onCreateActionView(); + + /** + * Performs an optional default action. + *

+ * For the case of an action provider placed in a menu item not shown as an action this + * method is invoked if previous callbacks for processing menu selection has handled + * the event. + *

+ *

+ * A menu item selection is processed in the following order: + *

    + *
  • + * Receiving a call to {@link MenuItem.OnMenuItemClickListener#onMenuItemClick + * MenuItem.OnMenuItemClickListener.onMenuItemClick}. + *
  • + *
  • + * Receiving a call to {@link android.app.Activity#onOptionsItemSelected(MenuItem) + * Activity.onOptionsItemSelected(MenuItem)} + *
  • + *
  • + * Receiving a call to {@link android.app.Fragment#onOptionsItemSelected(MenuItem) + * Fragment.onOptionsItemSelected(MenuItem)} + *
  • + *
  • + * Launching the {@link android.content.Intent} set via + * {@link MenuItem#setIntent(android.content.Intent) MenuItem.setIntent(android.content.Intent)} + *
  • + *
  • + * Invoking this method. + *
  • + *
+ *

+ *

+ * The default implementation does not perform any action and returns false. + *

+ */ + public boolean onPerformDefaultAction() { + return false; + } + + /** + * Determines if this ActionProvider has a submenu associated with it. + * + *

Associated submenus will be shown when an action view is not. This + * provider instance will receive a call to {@link #onPrepareSubMenu(SubMenu)} + * after the call to {@link #onPerformDefaultAction()} and before a submenu is + * displayed to the user. + * + * @return true if the item backed by this provider should have an associated submenu + */ + public boolean hasSubMenu() { + return false; + } + + /** + * Called to prepare an associated submenu for the menu item backed by this ActionProvider. + * + *

if {@link #hasSubMenu()} returns true, this method will be called when the + * menu item is selected to prepare the submenu for presentation to the user. Apps + * may use this to create or alter submenu content right before display. + * + * @param subMenu Submenu that will be displayed + */ + public void onPrepareSubMenu(SubMenu subMenu) { + } + + /** + * Notify the system that the visibility of an action view's sub-UI such as + * an anchored popup has changed. This will affect how other system + * visibility notifications occur. + * + * @hide Pending future API approval + */ + public void subUiVisibilityChanged(boolean isVisible) { + if (mSubUiVisibilityListener != null) { + mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible); + } + } + + /** + * @hide Internal use only + */ + public void setSubUiVisibilityListener(SubUiVisibilityListener listener) { + mSubUiVisibilityListener = listener; + } + + /** + * @hide Internal use only + */ + public interface SubUiVisibilityListener { + public void onSubUiVisibilityChanged(boolean isVisible); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/CollapsibleActionView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/CollapsibleActionView.java new file mode 100644 index 0000000000..43281b013c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/CollapsibleActionView.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.view; + +/** + * When a {@link View} implements this interface it will receive callbacks + * when expanded or collapsed as an action view alongside the optional, + * app-specified callbacks to {@link OnActionExpandListener}. + * + *

See {@link MenuItem} for more information about action views. + * See {@link android.app.ActionBar} for more information about the action bar. + */ +public interface CollapsibleActionView { + /** + * Called when this view is expanded as an action view. + * See {@link MenuItem#expandActionView()}. + */ + public void onActionViewExpanded(); + + /** + * Called when this view is collapsed as an action view. + * See {@link MenuItem#collapseActionView()}. + */ + public void onActionViewCollapsed(); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Menu.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Menu.java new file mode 100644 index 0000000000..afb8c29901 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Menu.java @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.view; + +import android.content.ComponentName; +import android.content.Intent; +import android.view.KeyEvent; + +/** + * Interface for managing the items in a menu. + *

+ * By default, every Activity supports an options menu of actions or options. + * You can add items to this menu and handle clicks on your additions. The + * easiest way of adding menu items is inflating an XML file into the + * {@link com.actionbarsherlock.view.Menu} via {@link MenuInflater}. The easiest way of attaching code to + * clicks is via {@link Activity#onOptionsItemSelected(MenuItem)} and + * {@link Activity#onContextItemSelected(MenuItem)}. + *

+ * Different menu types support different features: + *

    + *
  1. Context menus: Do not support item shortcuts and item icons. + *
  2. Options menus: The icon menus do not support item check + * marks and only show the item's + * {@link MenuItem#setTitleCondensed(CharSequence) condensed title}. The + * expanded menus (only available if six or more menu items are visible, + * reached via the 'More' item in the icon menu) do not show item icons, and + * item check marks are discouraged. + *
  3. Sub menus: Do not support item icons, or nested sub menus. + *
+ * + *
+ *

Developer Guides

+ *

For more information about creating menus, read the + * Menus developer guide.

+ *
+ */ +public interface Menu { + + /** + * This is the part of an order integer that the user can provide. + * @hide + */ + static final int USER_MASK = 0x0000ffff; + /** + * Bit shift of the user portion of the order integer. + * @hide + */ + static final int USER_SHIFT = 0; + + /** + * This is the part of an order integer that supplies the category of the + * item. + * @hide + */ + static final int CATEGORY_MASK = 0xffff0000; + /** + * Bit shift of the category portion of the order integer. + * @hide + */ + static final int CATEGORY_SHIFT = 16; + + /** + * Value to use for group and item identifier integers when you don't care + * about them. + */ + static final int NONE = 0; + + /** + * First value for group and item identifier integers. + */ + static final int FIRST = 1; + + // Implementation note: Keep these CATEGORY_* in sync with the category enum + // in attrs.xml + + /** + * Category code for the order integer for items/groups that are part of a + * container -- or/add this with your base value. + */ + static final int CATEGORY_CONTAINER = 0x00010000; + + /** + * Category code for the order integer for items/groups that are provided by + * the system -- or/add this with your base value. + */ + static final int CATEGORY_SYSTEM = 0x00020000; + + /** + * Category code for the order integer for items/groups that are + * user-supplied secondary (infrequently used) options -- or/add this with + * your base value. + */ + static final int CATEGORY_SECONDARY = 0x00030000; + + /** + * Category code for the order integer for items/groups that are + * alternative actions on the data that is currently displayed -- or/add + * this with your base value. + */ + static final int CATEGORY_ALTERNATIVE = 0x00040000; + + /** + * Flag for {@link #addIntentOptions}: if set, do not automatically remove + * any existing menu items in the same group. + */ + static final int FLAG_APPEND_TO_GROUP = 0x0001; + + /** + * Flag for {@link #performShortcut}: if set, do not close the menu after + * executing the shortcut. + */ + static final int FLAG_PERFORM_NO_CLOSE = 0x0001; + + /** + * Flag for {@link #performShortcut(int, KeyEvent, int)}: if set, always + * close the menu after executing the shortcut. Closing the menu also resets + * the prepared state. + */ + static final int FLAG_ALWAYS_PERFORM_CLOSE = 0x0002; + + /** + * Add a new item to the menu. This item displays the given title for its + * label. + * + * @param title The text to display for the item. + * @return The newly added menu item. + */ + public MenuItem add(CharSequence title); + + /** + * Add a new item to the menu. This item displays the given title for its + * label. + * + * @param titleRes Resource identifier of title string. + * @return The newly added menu item. + */ + public MenuItem add(int titleRes); + + /** + * Add a new item to the menu. This item displays the given title for its + * label. + * + * @param groupId The group identifier that this item should be part of. + * This can be used to define groups of items for batch state + * changes. Normally use {@link #NONE} if an item should not be in a + * group. + * @param itemId Unique item ID. Use {@link #NONE} if you do not need a + * unique ID. + * @param order The order for the item. Use {@link #NONE} if you do not care + * about the order. See {@link MenuItem#getOrder()}. + * @param title The text to display for the item. + * @return The newly added menu item. + */ + public MenuItem add(int groupId, int itemId, int order, CharSequence title); + + /** + * Variation on {@link #add(int, int, int, CharSequence)} that takes a + * string resource identifier instead of the string itself. + * + * @param groupId The group identifier that this item should be part of. + * This can also be used to define groups of items for batch state + * changes. Normally use {@link #NONE} if an item should not be in a + * group. + * @param itemId Unique item ID. Use {@link #NONE} if you do not need a + * unique ID. + * @param order The order for the item. Use {@link #NONE} if you do not care + * about the order. See {@link MenuItem#getOrder()}. + * @param titleRes Resource identifier of title string. + * @return The newly added menu item. + */ + public MenuItem add(int groupId, int itemId, int order, int titleRes); + + /** + * Add a new sub-menu to the menu. This item displays the given title for + * its label. To modify other attributes on the submenu's menu item, use + * {@link SubMenu#getItem()}. + * + * @param title The text to display for the item. + * @return The newly added sub-menu + */ + SubMenu addSubMenu(final CharSequence title); + + /** + * Add a new sub-menu to the menu. This item displays the given title for + * its label. To modify other attributes on the submenu's menu item, use + * {@link SubMenu#getItem()}. + * + * @param titleRes Resource identifier of title string. + * @return The newly added sub-menu + */ + SubMenu addSubMenu(final int titleRes); + + /** + * Add a new sub-menu to the menu. This item displays the given + * title for its label. To modify other attributes on the + * submenu's menu item, use {@link SubMenu#getItem()}. + *

+ * Note that you can only have one level of sub-menus, i.e. you cannnot add + * a subMenu to a subMenu: An {@link UnsupportedOperationException} will be + * thrown if you try. + * + * @param groupId The group identifier that this item should be part of. + * This can also be used to define groups of items for batch state + * changes. Normally use {@link #NONE} if an item should not be in a + * group. + * @param itemId Unique item ID. Use {@link #NONE} if you do not need a + * unique ID. + * @param order The order for the item. Use {@link #NONE} if you do not care + * about the order. See {@link MenuItem#getOrder()}. + * @param title The text to display for the item. + * @return The newly added sub-menu + */ + SubMenu addSubMenu(final int groupId, final int itemId, int order, final CharSequence title); + + /** + * Variation on {@link #addSubMenu(int, int, int, CharSequence)} that takes + * a string resource identifier for the title instead of the string itself. + * + * @param groupId The group identifier that this item should be part of. + * This can also be used to define groups of items for batch state + * changes. Normally use {@link #NONE} if an item should not be in a group. + * @param itemId Unique item ID. Use {@link #NONE} if you do not need a unique ID. + * @param order The order for the item. Use {@link #NONE} if you do not care about the + * order. See {@link MenuItem#getOrder()}. + * @param titleRes Resource identifier of title string. + * @return The newly added sub-menu + */ + SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes); + + /** + * Add a group of menu items corresponding to actions that can be performed + * for a particular Intent. The Intent is most often configured with a null + * action, the data that the current activity is working with, and includes + * either the {@link Intent#CATEGORY_ALTERNATIVE} or + * {@link Intent#CATEGORY_SELECTED_ALTERNATIVE} to find activities that have + * said they would like to be included as optional action. You can, however, + * use any Intent you want. + * + *

+ * See {@link android.content.pm.PackageManager#queryIntentActivityOptions} + * for more * details on the caller, specifics, and + * intent arguments. The list returned by that function is used + * to populate the resulting menu items. + * + *

+ * All of the menu items of possible options for the intent will be added + * with the given group and id. You can use the group to control ordering of + * the items in relation to other items in the menu. Normally this function + * will automatically remove any existing items in the menu in the same + * group and place a divider above and below the added items; this behavior + * can be modified with the flags parameter. For each of the + * generated items {@link MenuItem#setIntent} is called to associate the + * appropriate Intent with the item; this means the activity will + * automatically be started for you without having to do anything else. + * + * @param groupId The group identifier that the items should be part of. + * This can also be used to define groups of items for batch state + * changes. Normally use {@link #NONE} if the items should not be in + * a group. + * @param itemId Unique item ID. Use {@link #NONE} if you do not need a + * unique ID. + * @param order The order for the items. Use {@link #NONE} if you do not + * care about the order. See {@link MenuItem#getOrder()}. + * @param caller The current activity component name as defined by + * queryIntentActivityOptions(). + * @param specifics Specific items to place first as defined by + * queryIntentActivityOptions(). + * @param intent Intent describing the kinds of items to populate in the + * list as defined by queryIntentActivityOptions(). + * @param flags Additional options controlling how the items are added. + * @param outSpecificItems Optional array in which to place the menu items + * that were generated for each of the specifics that were + * requested. Entries may be null if no activity was found for that + * specific action. + * @return The number of menu items that were added. + * + * @see #FLAG_APPEND_TO_GROUP + * @see MenuItem#setIntent + * @see android.content.pm.PackageManager#queryIntentActivityOptions + */ + public int addIntentOptions(int groupId, int itemId, int order, + ComponentName caller, Intent[] specifics, + Intent intent, int flags, MenuItem[] outSpecificItems); + + /** + * Remove the item with the given identifier. + * + * @param id The item to be removed. If there is no item with this + * identifier, nothing happens. + */ + public void removeItem(int id); + + /** + * Remove all items in the given group. + * + * @param groupId The group to be removed. If there are no items in this + * group, nothing happens. + */ + public void removeGroup(int groupId); + + /** + * Remove all existing items from the menu, leaving it empty as if it had + * just been created. + */ + public void clear(); + + /** + * Control whether a particular group of items can show a check mark. This + * is similar to calling {@link MenuItem#setCheckable} on all of the menu items + * with the given group identifier, but in addition you can control whether + * this group contains a mutually-exclusive set items. This should be called + * after the items of the group have been added to the menu. + * + * @param group The group of items to operate on. + * @param checkable Set to true to allow a check mark, false to + * disallow. The default is false. + * @param exclusive If set to true, only one item in this group can be + * checked at a time; checking an item will automatically + * uncheck all others in the group. If set to false, each + * item can be checked independently of the others. + * + * @see MenuItem#setCheckable + * @see MenuItem#setChecked + */ + public void setGroupCheckable(int group, boolean checkable, boolean exclusive); + + /** + * Show or hide all menu items that are in the given group. + * + * @param group The group of items to operate on. + * @param visible If true the items are visible, else they are hidden. + * + * @see MenuItem#setVisible + */ + public void setGroupVisible(int group, boolean visible); + + /** + * Enable or disable all menu items that are in the given group. + * + * @param group The group of items to operate on. + * @param enabled If true the items will be enabled, else they will be disabled. + * + * @see MenuItem#setEnabled + */ + public void setGroupEnabled(int group, boolean enabled); + + /** + * Return whether the menu currently has item items that are visible. + * + * @return True if there is one or more item visible, + * else false. + */ + public boolean hasVisibleItems(); + + /** + * Return the menu item with a particular identifier. + * + * @param id The identifier to find. + * + * @return The menu item object, or null if there is no item with + * this identifier. + */ + public MenuItem findItem(int id); + + /** + * Get the number of items in the menu. Note that this will change any + * times items are added or removed from the menu. + * + * @return The item count. + */ + public int size(); + + /** + * Gets the menu item at the given index. + * + * @param index The index of the menu item to return. + * @return The menu item. + * @exception IndexOutOfBoundsException + * when {@code index < 0 || >= size()} + */ + public MenuItem getItem(int index); + + /** + * Closes the menu, if open. + */ + public void close(); + + /** + * Execute the menu item action associated with the given shortcut + * character. + * + * @param keyCode The keycode of the shortcut key. + * @param event Key event message. + * @param flags Additional option flags or 0. + * + * @return If the given shortcut exists and is shown, returns + * true; else returns false. + * + * @see #FLAG_PERFORM_NO_CLOSE + */ + public boolean performShortcut(int keyCode, KeyEvent event, int flags); + + /** + * Is a keypress one of the defined shortcut keys for this window. + * @param keyCode the key code from {@link KeyEvent} to check. + * @param event the {@link KeyEvent} to use to help check. + */ + boolean isShortcutKey(int keyCode, KeyEvent event); + + /** + * Execute the menu item action associated with the given menu identifier. + * + * @param id Identifier associated with the menu item. + * @param flags Additional option flags or 0. + * + * @return If the given identifier exists and is shown, returns + * true; else returns false. + * + * @see #FLAG_PERFORM_NO_CLOSE + */ + public boolean performIdentifierAction(int id, int flags); + + + /** + * Control whether the menu should be running in qwerty mode (alphabetic + * shortcuts) or 12-key mode (numeric shortcuts). + * + * @param isQwerty If true the menu will use alphabetic shortcuts; else it + * will use numeric shortcuts. + */ + public void setQwertyMode(boolean isQwerty); +} + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuInflater.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuInflater.java new file mode 100644 index 0000000000..afe9f7361c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuInflater.java @@ -0,0 +1,495 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * 2011 Jake Wharton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this 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.actionbarsherlock.view; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import android.content.Context; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.util.AttributeSet; +import android.util.Log; +import android.util.TypedValue; +import android.util.Xml; +import android.view.InflateException; +import android.view.View; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.internal.view.menu.MenuItemImpl; + +/** + * This class is used to instantiate menu XML files into Menu objects. + *

+ * For performance reasons, menu inflation relies heavily on pre-processing of + * XML files that is done at build time. Therefore, it is not currently possible + * to use MenuInflater with an XmlPullParser over a plain XML file at runtime; + * it only works with an XmlPullParser returned from a compiled resource (R. + * something file.) + */ +public class MenuInflater { + private static final String LOG_TAG = "MenuInflater"; + + /** Menu tag name in XML. */ + private static final String XML_MENU = "menu"; + + /** Group tag name in XML. */ + private static final String XML_GROUP = "group"; + + /** Item tag name in XML. */ + private static final String XML_ITEM = "item"; + + private static final int NO_ID = 0; + + private static final Class[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class}; + + private static final Class[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE = ACTION_VIEW_CONSTRUCTOR_SIGNATURE; + + private final Object[] mActionViewConstructorArguments; + + private final Object[] mActionProviderConstructorArguments; + + private Context mContext; + private Object mRealOwner; + + /** + * Constructs a menu inflater. + * + * @see Activity#getMenuInflater() + */ + public MenuInflater(Context context) { + mContext = context; + mRealOwner = context; + mActionViewConstructorArguments = new Object[] {context}; + mActionProviderConstructorArguments = mActionViewConstructorArguments; + } + + /** + * Constructs a menu inflater. + * + * @see Activity#getMenuInflater() + * @hide + */ + public MenuInflater(Context context, Object realOwner) { + mContext = context; + mRealOwner = realOwner; + mActionViewConstructorArguments = new Object[] {context}; + mActionProviderConstructorArguments = mActionViewConstructorArguments; + } + + /** + * Inflate a menu hierarchy from the specified XML resource. Throws + * {@link InflateException} if there is an error. + * + * @param menuRes Resource ID for an XML layout resource to load (e.g., + * R.menu.main_activity) + * @param menu The Menu to inflate into. The items and submenus will be + * added to this Menu. + */ + public void inflate(int menuRes, Menu menu) { + XmlResourceParser parser = null; + try { + parser = mContext.getResources().getLayout(menuRes); + AttributeSet attrs = Xml.asAttributeSet(parser); + + parseMenu(parser, attrs, menu); + } catch (XmlPullParserException e) { + throw new InflateException("Error inflating menu XML", e); + } catch (IOException e) { + throw new InflateException("Error inflating menu XML", e); + } finally { + if (parser != null) parser.close(); + } + } + + /** + * Called internally to fill the given menu. If a sub menu is seen, it will + * call this recursively. + */ + private void parseMenu(XmlPullParser parser, AttributeSet attrs, Menu menu) + throws XmlPullParserException, IOException { + MenuState menuState = new MenuState(menu); + + int eventType = parser.getEventType(); + String tagName; + boolean lookingForEndOfUnknownTag = false; + String unknownTagName = null; + + // This loop will skip to the menu start tag + do { + if (eventType == XmlPullParser.START_TAG) { + tagName = parser.getName(); + if (tagName.equals(XML_MENU)) { + // Go to next tag + eventType = parser.next(); + break; + } + + throw new RuntimeException("Expecting menu, got " + tagName); + } + eventType = parser.next(); + } while (eventType != XmlPullParser.END_DOCUMENT); + + boolean reachedEndOfMenu = false; + while (!reachedEndOfMenu) { + switch (eventType) { + case XmlPullParser.START_TAG: + if (lookingForEndOfUnknownTag) { + break; + } + + tagName = parser.getName(); + if (tagName.equals(XML_GROUP)) { + menuState.readGroup(attrs); + } else if (tagName.equals(XML_ITEM)) { + menuState.readItem(attrs); + } else if (tagName.equals(XML_MENU)) { + // A menu start tag denotes a submenu for an item + SubMenu subMenu = menuState.addSubMenuItem(); + + // Parse the submenu into returned SubMenu + parseMenu(parser, attrs, subMenu); + } else { + lookingForEndOfUnknownTag = true; + unknownTagName = tagName; + } + break; + + case XmlPullParser.END_TAG: + tagName = parser.getName(); + if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) { + lookingForEndOfUnknownTag = false; + unknownTagName = null; + } else if (tagName.equals(XML_GROUP)) { + menuState.resetGroup(); + } else if (tagName.equals(XML_ITEM)) { + // Add the item if it hasn't been added (if the item was + // a submenu, it would have been added already) + if (!menuState.hasAddedItem()) { + if (menuState.itemActionProvider != null && + menuState.itemActionProvider.hasSubMenu()) { + menuState.addSubMenuItem(); + } else { + menuState.addItem(); + } + } + } else if (tagName.equals(XML_MENU)) { + reachedEndOfMenu = true; + } + break; + + case XmlPullParser.END_DOCUMENT: + throw new RuntimeException("Unexpected end of document"); + } + + eventType = parser.next(); + } + } + + private static class InflatedOnMenuItemClickListener + implements MenuItem.OnMenuItemClickListener { + private static final Class[] PARAM_TYPES = new Class[] { MenuItem.class }; + + private Object mRealOwner; + private Method mMethod; + + public InflatedOnMenuItemClickListener(Object realOwner, String methodName) { + mRealOwner = realOwner; + Class c = realOwner.getClass(); + try { + mMethod = c.getMethod(methodName, PARAM_TYPES); + } catch (Exception e) { + InflateException ex = new InflateException( + "Couldn't resolve menu item onClick handler " + methodName + + " in class " + c.getName()); + ex.initCause(e); + throw ex; + } + } + + public boolean onMenuItemClick(MenuItem item) { + try { + if (mMethod.getReturnType() == Boolean.TYPE) { + return (Boolean) mMethod.invoke(mRealOwner, item); + } else { + mMethod.invoke(mRealOwner, item); + return true; + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + /** + * State for the current menu. + *

+ * Groups can not be nested unless there is another menu (which will have + * its state class). + */ + private class MenuState { + private Menu menu; + + /* + * Group state is set on items as they are added, allowing an item to + * override its group state. (As opposed to set on items at the group end tag.) + */ + private int groupId; + private int groupCategory; + private int groupOrder; + private int groupCheckable; + private boolean groupVisible; + private boolean groupEnabled; + + private boolean itemAdded; + private int itemId; + private int itemCategoryOrder; + private CharSequence itemTitle; + private CharSequence itemTitleCondensed; + private int itemIconResId; + private char itemAlphabeticShortcut; + private char itemNumericShortcut; + /** + * Sync to attrs.xml enum: + * - 0: none + * - 1: all + * - 2: exclusive + */ + private int itemCheckable; + private boolean itemChecked; + private boolean itemVisible; + private boolean itemEnabled; + + /** + * Sync to attrs.xml enum, values in MenuItem: + * - 0: never + * - 1: ifRoom + * - 2: always + * - -1: Safe sentinel for "no value". + */ + private int itemShowAsAction; + + private int itemActionViewLayout; + private String itemActionViewClassName; + private String itemActionProviderClassName; + + private String itemListenerMethodName; + + private ActionProvider itemActionProvider; + + private static final int defaultGroupId = NO_ID; + private static final int defaultItemId = NO_ID; + private static final int defaultItemCategory = 0; + private static final int defaultItemOrder = 0; + private static final int defaultItemCheckable = 0; + private static final boolean defaultItemChecked = false; + private static final boolean defaultItemVisible = true; + private static final boolean defaultItemEnabled = true; + + public MenuState(final Menu menu) { + this.menu = menu; + + resetGroup(); + } + + public void resetGroup() { + groupId = defaultGroupId; + groupCategory = defaultItemCategory; + groupOrder = defaultItemOrder; + groupCheckable = defaultItemCheckable; + groupVisible = defaultItemVisible; + groupEnabled = defaultItemEnabled; + } + + /** + * Called when the parser is pointing to a group tag. + */ + public void readGroup(AttributeSet attrs) { + TypedArray a = mContext.obtainStyledAttributes(attrs, + R.styleable.SherlockMenuGroup); + + groupId = a.getResourceId(R.styleable.SherlockMenuGroup_android_id, defaultGroupId); + groupCategory = a.getInt(R.styleable.SherlockMenuGroup_android_menuCategory, defaultItemCategory); + groupOrder = a.getInt(R.styleable.SherlockMenuGroup_android_orderInCategory, defaultItemOrder); + groupCheckable = a.getInt(R.styleable.SherlockMenuGroup_android_checkableBehavior, defaultItemCheckable); + groupVisible = a.getBoolean(R.styleable.SherlockMenuGroup_android_visible, defaultItemVisible); + groupEnabled = a.getBoolean(R.styleable.SherlockMenuGroup_android_enabled, defaultItemEnabled); + + a.recycle(); + } + + /** + * Called when the parser is pointing to an item tag. + */ + public void readItem(AttributeSet attrs) { + TypedArray a = mContext.obtainStyledAttributes(attrs, + R.styleable.SherlockMenuItem); + + // Inherit attributes from the group as default value + itemId = a.getResourceId(R.styleable.SherlockMenuItem_android_id, defaultItemId); + final int category = a.getInt(R.styleable.SherlockMenuItem_android_menuCategory, groupCategory); + final int order = a.getInt(R.styleable.SherlockMenuItem_android_orderInCategory, groupOrder); + itemCategoryOrder = (category & Menu.CATEGORY_MASK) | (order & Menu.USER_MASK); + itemTitle = a.getText(R.styleable.SherlockMenuItem_android_title); + itemTitleCondensed = a.getText(R.styleable.SherlockMenuItem_android_titleCondensed); + itemIconResId = a.getResourceId(R.styleable.SherlockMenuItem_android_icon, 0); + itemAlphabeticShortcut = + getShortcut(a.getString(R.styleable.SherlockMenuItem_android_alphabeticShortcut)); + itemNumericShortcut = + getShortcut(a.getString(R.styleable.SherlockMenuItem_android_numericShortcut)); + if (a.hasValue(R.styleable.SherlockMenuItem_android_checkable)) { + // Item has attribute checkable, use it + itemCheckable = a.getBoolean(R.styleable.SherlockMenuItem_android_checkable, false) ? 1 : 0; + } else { + // Item does not have attribute, use the group's (group can have one more state + // for checkable that represents the exclusive checkable) + itemCheckable = groupCheckable; + } + + itemChecked = a.getBoolean(R.styleable.SherlockMenuItem_android_checked, defaultItemChecked); + itemVisible = a.getBoolean(R.styleable.SherlockMenuItem_android_visible, groupVisible); + itemEnabled = a.getBoolean(R.styleable.SherlockMenuItem_android_enabled, groupEnabled); + + TypedValue value = new TypedValue(); + a.getValue(R.styleable.SherlockMenuItem_android_showAsAction, value); + itemShowAsAction = value.type == TypedValue.TYPE_INT_HEX ? value.data : -1; + + itemListenerMethodName = a.getString(R.styleable.SherlockMenuItem_android_onClick); + itemActionViewLayout = a.getResourceId(R.styleable.SherlockMenuItem_android_actionLayout, 0); + + // itemActionViewClassName = a.getString(R.styleable.SherlockMenuItem_android_actionViewClass); + value = new TypedValue(); + a.getValue(R.styleable.SherlockMenuItem_android_actionViewClass, value); + itemActionViewClassName = value.type == TypedValue.TYPE_STRING ? value.string.toString() : null; + + // itemActionProviderClassName = a.getString(R.styleable.SherlockMenuItem_android_actionProviderClass); + value = new TypedValue(); + a.getValue(R.styleable.SherlockMenuItem_android_actionProviderClass, value); + itemActionProviderClassName = value.type == TypedValue.TYPE_STRING ? value.string.toString() : null; + + final boolean hasActionProvider = itemActionProviderClassName != null; + if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) { + itemActionProvider = newInstance(itemActionProviderClassName, + ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE, + mActionProviderConstructorArguments); + } else { + if (hasActionProvider) { + Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'." + + " Action view already specified."); + } + itemActionProvider = null; + } + + a.recycle(); + + itemAdded = false; + } + + private char getShortcut(String shortcutString) { + if (shortcutString == null) { + return 0; + } else { + return shortcutString.charAt(0); + } + } + + private void setItem(MenuItem item) { + item.setChecked(itemChecked) + .setVisible(itemVisible) + .setEnabled(itemEnabled) + .setCheckable(itemCheckable >= 1) + .setTitleCondensed(itemTitleCondensed) + .setIcon(itemIconResId) + .setAlphabeticShortcut(itemAlphabeticShortcut) + .setNumericShortcut(itemNumericShortcut); + + if (itemShowAsAction >= 0) { + item.setShowAsAction(itemShowAsAction); + } + + if (itemListenerMethodName != null) { + if (mContext.isRestricted()) { + throw new IllegalStateException("The android:onClick attribute cannot " + + "be used within a restricted context"); + } + item.setOnMenuItemClickListener( + new InflatedOnMenuItemClickListener(mRealOwner, itemListenerMethodName)); + } + + if (itemCheckable >= 2) { + if (item instanceof MenuItemImpl) { + MenuItemImpl impl = (MenuItemImpl) item; + impl.setExclusiveCheckable(true); + } else { + menu.setGroupCheckable(groupId, true, true); + } + } + + boolean actionViewSpecified = false; + if (itemActionViewClassName != null) { + View actionView = (View) newInstance(itemActionViewClassName, + ACTION_VIEW_CONSTRUCTOR_SIGNATURE, mActionViewConstructorArguments); + item.setActionView(actionView); + actionViewSpecified = true; + } + if (itemActionViewLayout > 0) { + if (!actionViewSpecified) { + item.setActionView(itemActionViewLayout); + actionViewSpecified = true; + } else { + Log.w(LOG_TAG, "Ignoring attribute 'itemActionViewLayout'." + + " Action view already specified."); + } + } + if (itemActionProvider != null) { + item.setActionProvider(itemActionProvider); + } + } + + public void addItem() { + itemAdded = true; + setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle)); + } + + public SubMenu addSubMenuItem() { + itemAdded = true; + SubMenu subMenu = menu.addSubMenu(groupId, itemId, itemCategoryOrder, itemTitle); + setItem(subMenu.getItem()); + return subMenu; + } + + public boolean hasAddedItem() { + return itemAdded; + } + + @SuppressWarnings("unchecked") + private T newInstance(String className, Class[] constructorSignature, + Object[] arguments) { + try { + Class clazz = mContext.getClassLoader().loadClass(className); + Constructor constructor = clazz.getConstructor(constructorSignature); + return (T) constructor.newInstance(arguments); + } catch (Exception e) { + Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); + } + return null; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuItem.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuItem.java new file mode 100644 index 0000000000..25179bbe8a --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/MenuItem.java @@ -0,0 +1,598 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.view; + +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.View; + +/** + * Interface for direct access to a previously created menu item. + *

+ * An Item is returned by calling one of the {@link android.view.Menu#add} + * methods. + *

+ * For a feature set of specific menu types, see {@link Menu}. + * + *

+ *

Developer Guides

+ *

For information about creating menus, read the + * Menus developer guide.

+ *
+ */ +public interface MenuItem { + /* + * These should be kept in sync with attrs.xml enum constants for showAsAction + */ + /** Never show this item as a button in an Action Bar. */ + public static final int SHOW_AS_ACTION_NEVER = android.view.MenuItem.SHOW_AS_ACTION_NEVER; + /** Show this item as a button in an Action Bar if the system decides there is room for it. */ + public static final int SHOW_AS_ACTION_IF_ROOM = android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM; + /** + * Always show this item as a button in an Action Bar. + * Use sparingly! If too many items are set to always show in the Action Bar it can + * crowd the Action Bar and degrade the user experience on devices with smaller screens. + * A good rule of thumb is to have no more than 2 items set to always show at a time. + */ + public static final int SHOW_AS_ACTION_ALWAYS = android.view.MenuItem.SHOW_AS_ACTION_ALWAYS; + + /** + * When this item is in the action bar, always show it with a text label even if + * it also has an icon specified. + */ + public static final int SHOW_AS_ACTION_WITH_TEXT = android.view.MenuItem.SHOW_AS_ACTION_WITH_TEXT; + + /** + * This item's action view collapses to a normal menu item. + * When expanded, the action view temporarily takes over + * a larger segment of its container. + */ + public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = android.view.MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW; + + /** + * Interface definition for a callback to be invoked when a menu item is + * clicked. + * + * @see Activity#onContextItemSelected(com.actionbarsherlock.view.MenuItem) + * @see Activity#onOptionsItemSelected(com.actionbarsherlock.view.MenuItem) + */ + public interface OnMenuItemClickListener { + /** + * Called when a menu item has been invoked. This is the first code + * that is executed; if it returns true, no other callbacks will be + * executed. + * + * @param item The menu item that was invoked. + * + * @return Return true to consume this click and prevent others from + * executing. + */ + public boolean onMenuItemClick(MenuItem item); + } + + /** + * Interface definition for a callback to be invoked when a menu item + * marked with {@link com.actionbarsherlock.view.MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} is + * expanded or collapsed. + * + * @see com.actionbarsherlock.view.MenuItem#expandActionView() + * @see com.actionbarsherlock.view.MenuItem#collapseActionView() + * @see com.actionbarsherlock.view.MenuItem#setShowAsActionFlags(int) + */ + public interface OnActionExpandListener { + /** + * Called when a menu item with {@link com.actionbarsherlock.view.MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} + * is expanded. + * @param item Item that was expanded + * @return true if the item should expand, false if expansion should be suppressed. + */ + public boolean onMenuItemActionExpand(MenuItem item); + + /** + * Called when a menu item with {@link com.actionbarsherlock.view.MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} + * is collapsed. + * @param item Item that was collapsed + * @return true if the item should collapse, false if collapsing should be suppressed. + */ + public boolean onMenuItemActionCollapse(MenuItem item); + } + + /** + * Return the identifier for this menu item. The identifier can not + * be changed after the menu is created. + * + * @return The menu item's identifier. + */ + public int getItemId(); + + /** + * Return the group identifier that this menu item is part of. The group + * identifier can not be changed after the menu is created. + * + * @return The menu item's group identifier. + */ + public int getGroupId(); + + /** + * Return the category and order within the category of this item. This + * item will be shown before all items (within its category) that have + * order greater than this value. + *

+ * An order integer contains the item's category (the upper bits of the + * integer; set by or/add the category with the order within the + * category) and the ordering of the item within that category (the + * lower bits). Example categories are {@link Menu#CATEGORY_SYSTEM}, + * {@link Menu#CATEGORY_SECONDARY}, {@link Menu#CATEGORY_ALTERNATIVE}, + * {@link Menu#CATEGORY_CONTAINER}. See {@link Menu} for a full list. + * + * @return The order of this item. + */ + public int getOrder(); + + /** + * Change the title associated with this item. + * + * @param title The new text to be displayed. + * @return This Item so additional setters can be called. + */ + public MenuItem setTitle(CharSequence title); + + /** + * Change the title associated with this item. + *

+ * Some menu types do not sufficient space to show the full title, and + * instead a condensed title is preferred. See {@link Menu} for more + * information. + * + * @param title The resource id of the new text to be displayed. + * @return This Item so additional setters can be called. + * @see #setTitleCondensed(CharSequence) + */ + + public MenuItem setTitle(int title); + + /** + * Retrieve the current title of the item. + * + * @return The title. + */ + public CharSequence getTitle(); + + /** + * Change the condensed title associated with this item. The condensed + * title is used in situations where the normal title may be too long to + * be displayed. + * + * @param title The new text to be displayed as the condensed title. + * @return This Item so additional setters can be called. + */ + public MenuItem setTitleCondensed(CharSequence title); + + /** + * Retrieve the current condensed title of the item. If a condensed + * title was never set, it will return the normal title. + * + * @return The condensed title, if it exists. + * Otherwise the normal title. + */ + public CharSequence getTitleCondensed(); + + /** + * Change the icon associated with this item. This icon will not always be + * shown, so the title should be sufficient in describing this item. See + * {@link Menu} for the menu types that support icons. + * + * @param icon The new icon (as a Drawable) to be displayed. + * @return This Item so additional setters can be called. + */ + public MenuItem setIcon(Drawable icon); + + /** + * Change the icon associated with this item. This icon will not always be + * shown, so the title should be sufficient in describing this item. See + * {@link Menu} for the menu types that support icons. + *

+ * This method will set the resource ID of the icon which will be used to + * lazily get the Drawable when this item is being shown. + * + * @param iconRes The new icon (as a resource ID) to be displayed. + * @return This Item so additional setters can be called. + */ + public MenuItem setIcon(int iconRes); + + /** + * Returns the icon for this item as a Drawable (getting it from resources if it hasn't been + * loaded before). + * + * @return The icon as a Drawable. + */ + public Drawable getIcon(); + + /** + * Change the Intent associated with this item. By default there is no + * Intent associated with a menu item. If you set one, and nothing + * else handles the item, then the default behavior will be to call + * {@link android.content.Context#startActivity} with the given Intent. + * + *

Note that setIntent() can not be used with the versions of + * {@link Menu#add} that take a Runnable, because {@link Runnable#run} + * does not return a value so there is no way to tell if it handled the + * item. In this case it is assumed that the Runnable always handles + * the item, and the intent will never be started. + * + * @see #getIntent + * @param intent The Intent to associated with the item. This Intent + * object is not copied, so be careful not to + * modify it later. + * @return This Item so additional setters can be called. + */ + public MenuItem setIntent(Intent intent); + + /** + * Return the Intent associated with this item. This returns a + * reference to the Intent which you can change as desired to modify + * what the Item is holding. + * + * @see #setIntent + * @return Returns the last value supplied to {@link #setIntent}, or + * null. + */ + public Intent getIntent(); + + /** + * Change both the numeric and alphabetic shortcut associated with this + * item. Note that the shortcut will be triggered when the key that + * generates the given character is pressed alone or along with with the alt + * key. Also note that case is not significant and that alphabetic shortcut + * characters will be displayed in lower case. + *

+ * See {@link Menu} for the menu types that support shortcuts. + * + * @param numericChar The numeric shortcut key. This is the shortcut when + * using a numeric (e.g., 12-key) keyboard. + * @param alphaChar The alphabetic shortcut key. This is the shortcut when + * using a keyboard with alphabetic keys. + * @return This Item so additional setters can be called. + */ + public MenuItem setShortcut(char numericChar, char alphaChar); + + /** + * Change the numeric shortcut associated with this item. + *

+ * See {@link Menu} for the menu types that support shortcuts. + * + * @param numericChar The numeric shortcut key. This is the shortcut when + * using a 12-key (numeric) keyboard. + * @return This Item so additional setters can be called. + */ + public MenuItem setNumericShortcut(char numericChar); + + /** + * Return the char for this menu item's numeric (12-key) shortcut. + * + * @return Numeric character to use as a shortcut. + */ + public char getNumericShortcut(); + + /** + * Change the alphabetic shortcut associated with this item. The shortcut + * will be triggered when the key that generates the given character is + * pressed alone or along with with the alt key. Case is not significant and + * shortcut characters will be displayed in lower case. Note that menu items + * with the characters '\b' or '\n' as shortcuts will get triggered by the + * Delete key or Carriage Return key, respectively. + *

+ * See {@link Menu} for the menu types that support shortcuts. + * + * @param alphaChar The alphabetic shortcut key. This is the shortcut when + * using a keyboard with alphabetic keys. + * @return This Item so additional setters can be called. + */ + public MenuItem setAlphabeticShortcut(char alphaChar); + + /** + * Return the char for this menu item's alphabetic shortcut. + * + * @return Alphabetic character to use as a shortcut. + */ + public char getAlphabeticShortcut(); + + /** + * Control whether this item can display a check mark. Setting this does + * not actually display a check mark (see {@link #setChecked} for that); + * rather, it ensures there is room in the item in which to display a + * check mark. + *

+ * See {@link Menu} for the menu types that support check marks. + * + * @param checkable Set to true to allow a check mark, false to + * disallow. The default is false. + * @see #setChecked + * @see #isCheckable + * @see Menu#setGroupCheckable + * @return This Item so additional setters can be called. + */ + public MenuItem setCheckable(boolean checkable); + + /** + * Return whether the item can currently display a check mark. + * + * @return If a check mark can be displayed, returns true. + * + * @see #setCheckable + */ + public boolean isCheckable(); + + /** + * Control whether this item is shown with a check mark. Note that you + * must first have enabled checking with {@link #setCheckable} or else + * the check mark will not appear. If this item is a member of a group that contains + * mutually-exclusive items (set via {@link Menu#setGroupCheckable(int, boolean, boolean)}, + * the other items in the group will be unchecked. + *

+ * See {@link Menu} for the menu types that support check marks. + * + * @see #setCheckable + * @see #isChecked + * @see Menu#setGroupCheckable + * @param checked Set to true to display a check mark, false to hide + * it. The default value is false. + * @return This Item so additional setters can be called. + */ + public MenuItem setChecked(boolean checked); + + /** + * Return whether the item is currently displaying a check mark. + * + * @return If a check mark is displayed, returns true. + * + * @see #setChecked + */ + public boolean isChecked(); + + /** + * Sets the visibility of the menu item. Even if a menu item is not visible, + * it may still be invoked via its shortcut (to completely disable an item, + * set it to invisible and {@link #setEnabled(boolean) disabled}). + * + * @param visible If true then the item will be visible; if false it is + * hidden. + * @return This Item so additional setters can be called. + */ + public MenuItem setVisible(boolean visible); + + /** + * Return the visibility of the menu item. + * + * @return If true the item is visible; else it is hidden. + */ + public boolean isVisible(); + + /** + * Sets whether the menu item is enabled. Disabling a menu item will not + * allow it to be invoked via its shortcut. The menu item will still be + * visible. + * + * @param enabled If true then the item will be invokable; if false it is + * won't be invokable. + * @return This Item so additional setters can be called. + */ + public MenuItem setEnabled(boolean enabled); + + /** + * Return the enabled state of the menu item. + * + * @return If true the item is enabled and hence invokable; else it is not. + */ + public boolean isEnabled(); + + /** + * Check whether this item has an associated sub-menu. I.e. it is a + * sub-menu of another menu. + * + * @return If true this item has a menu; else it is a + * normal item. + */ + public boolean hasSubMenu(); + + /** + * Get the sub-menu to be invoked when this item is selected, if it has + * one. See {@link #hasSubMenu()}. + * + * @return The associated menu if there is one, else null + */ + public SubMenu getSubMenu(); + + /** + * Set a custom listener for invocation of this menu item. In most + * situations, it is more efficient and easier to use + * {@link Activity#onOptionsItemSelected(com.actionbarsherlock.view.MenuItem)} or + * {@link Activity#onContextItemSelected(com.actionbarsherlock.view.MenuItem)}. + * + * @param menuItemClickListener The object to receive invokations. + * @return This Item so additional setters can be called. + * @see Activity#onOptionsItemSelected(com.actionbarsherlock.view.MenuItem) + * @see Activity#onContextItemSelected(com.actionbarsherlock.view.MenuItem) + */ + public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener); + + /** + * Gets the extra information linked to this menu item. This extra + * information is set by the View that added this menu item to the + * menu. + * + * @see OnCreateContextMenuListener + * @return The extra information linked to the View that added this + * menu item to the menu. This can be null. + */ + public ContextMenuInfo getMenuInfo(); + + /** + * Sets how this item should display in the presence of an Action Bar. + * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS}, + * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should + * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}. + * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action, + * it should be shown with a text label. + * + * @param actionEnum How the item should display. One of + * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or + * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default. + * + * @see android.app.ActionBar + * @see #setActionView(View) + */ + public void setShowAsAction(int actionEnum); + + /** + * Sets how this item should display in the presence of an Action Bar. + * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS}, + * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should + * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}. + * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action, + * it should be shown with a text label. + * + *

Note: This method differs from {@link #setShowAsAction(int)} only in that it + * returns the current MenuItem instance for call chaining. + * + * @param actionEnum How the item should display. One of + * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or + * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default. + * + * @see android.app.ActionBar + * @see #setActionView(View) + * @return This MenuItem instance for call chaining. + */ + public MenuItem setShowAsActionFlags(int actionEnum); + + /** + * Set an action view for this menu item. An action view will be displayed in place + * of an automatically generated menu item element in the UI when this item is shown + * as an action within a parent. + *

+ * Note: Setting an action view overrides the action provider + * set via {@link #setActionProvider(ActionProvider)}. + *

+ * + * @param view View to use for presenting this item to the user. + * @return This Item so additional setters can be called. + * + * @see #setShowAsAction(int) + */ + public MenuItem setActionView(View view); + + /** + * Set an action view for this menu item. An action view will be displayed in place + * of an automatically generated menu item element in the UI when this item is shown + * as an action within a parent. + *

+ * Note: Setting an action view overrides the action provider + * set via {@link #setActionProvider(ActionProvider)}. + *

+ * + * @param resId Layout resource to use for presenting this item to the user. + * @return This Item so additional setters can be called. + * + * @see #setShowAsAction(int) + */ + public MenuItem setActionView(int resId); + + /** + * Returns the currently set action view for this menu item. + * + * @return This item's action view + * + * @see #setActionView(View) + * @see #setShowAsAction(int) + */ + public View getActionView(); + + /** + * Sets the {@link ActionProvider} responsible for creating an action view if + * the item is placed on the action bar. The provider also provides a default + * action invoked if the item is placed in the overflow menu. + *

+ * Note: Setting an action provider overrides the action view + * set via {@link #setActionView(int)} or {@link #setActionView(View)}. + *

+ * + * @param actionProvider The action provider. + * @return This Item so additional setters can be called. + * + * @see ActionProvider + */ + public MenuItem setActionProvider(ActionProvider actionProvider); + + /** + * Gets the {@link ActionProvider}. + * + * @return The action provider. + * + * @see ActionProvider + * @see #setActionProvider(ActionProvider) + */ + public ActionProvider getActionProvider(); + + /** + * Expand the action view associated with this menu item. + * The menu item must have an action view set, as well as + * the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. + * If a listener has been set using {@link #setOnActionExpandListener(com.actionbarsherlock.view.MenuItem.OnActionExpandListener)} + * it will have its {@link com.actionbarsherlock.view.MenuItem.OnActionExpandListener#onMenuItemActionExpand(com.actionbarsherlock.view.MenuItem)} + * method invoked. The listener may return false from this method to prevent expanding + * the action view. + * + * @return true if the action view was expanded, false otherwise. + */ + public boolean expandActionView(); + + /** + * Collapse the action view associated with this menu item. + * The menu item must have an action view set, as well as the showAsAction flag + * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. If a listener has been set using + * {@link #setOnActionExpandListener(com.actionbarsherlock.view.MenuItem.OnActionExpandListener)} it will have its + * {@link com.actionbarsherlock.view.MenuItem.OnActionExpandListener#onMenuItemActionCollapse(com.actionbarsherlock.view.MenuItem)} method invoked. + * The listener may return false from this method to prevent collapsing the action view. + * + * @return true if the action view was collapsed, false otherwise. + */ + public boolean collapseActionView(); + + /** + * Returns true if this menu item's action view has been expanded. + * + * @return true if the item's action view is expanded, false otherwise. + * + * @see #expandActionView() + * @see #collapseActionView() + * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW + * @see com.actionbarsherlock.view.MenuItem.OnActionExpandListener + */ + public boolean isActionViewExpanded(); + + /** + * Set an {@link com.actionbarsherlock.view.MenuItem.OnActionExpandListener} on this menu item to be notified when + * the associated action view is expanded or collapsed. The menu item must + * be configured to expand or collapse its action view using the flag + * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. + * + * @param listener Listener that will respond to expand/collapse events + * @return This menu item instance for call chaining + */ + public MenuItem setOnActionExpandListener(OnActionExpandListener listener); +} \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/SubMenu.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/SubMenu.java new file mode 100644 index 0000000000..397fd1c2d7 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/SubMenu.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.view; + +import android.graphics.drawable.Drawable; +import android.view.View; + +/** + * Subclass of {@link Menu} for sub menus. + *

+ * Sub menus do not support item icons, or nested sub menus. + * + *

+ *

Developer Guides

+ *

For information about creating menus, read the + * Menus developer guide.

+ *
+ */ + +public interface SubMenu extends Menu { + /** + * Sets the submenu header's title to the title given in titleRes + * resource identifier. + * + * @param titleRes The string resource identifier used for the title. + * @return This SubMenu so additional setters can be called. + */ + public SubMenu setHeaderTitle(int titleRes); + + /** + * Sets the submenu header's title to the title given in title. + * + * @param title The character sequence used for the title. + * @return This SubMenu so additional setters can be called. + */ + public SubMenu setHeaderTitle(CharSequence title); + + /** + * Sets the submenu header's icon to the icon given in iconRes + * resource id. + * + * @param iconRes The resource identifier used for the icon. + * @return This SubMenu so additional setters can be called. + */ + public SubMenu setHeaderIcon(int iconRes); + + /** + * Sets the submenu header's icon to the icon given in icon + * {@link Drawable}. + * + * @param icon The {@link Drawable} used for the icon. + * @return This SubMenu so additional setters can be called. + */ + public SubMenu setHeaderIcon(Drawable icon); + + /** + * Sets the header of the submenu to the {@link View} given in + * view. This replaces the header title and icon (and those + * replace this). + * + * @param view The {@link View} used for the header. + * @return This SubMenu so additional setters can be called. + */ + public SubMenu setHeaderView(View view); + + /** + * Clears the header of the submenu. + */ + public void clearHeader(); + + /** + * Change the icon associated with this submenu's item in its parent menu. + * + * @see MenuItem#setIcon(int) + * @param iconRes The new icon (as a resource ID) to be displayed. + * @return This SubMenu so additional setters can be called. + */ + public SubMenu setIcon(int iconRes); + + /** + * Change the icon associated with this submenu's item in its parent menu. + * + * @see MenuItem#setIcon(Drawable) + * @param icon The new icon (as a Drawable) to be displayed. + * @return This SubMenu so additional setters can be called. + */ + public SubMenu setIcon(Drawable icon); + + /** + * Gets the {@link MenuItem} that represents this submenu in the parent + * menu. Use this for setting additional item attributes. + * + * @return The {@link MenuItem} that launches the submenu when invoked. + */ + public MenuItem getItem(); +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Window.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Window.java new file mode 100644 index 0000000000..1d2828c581 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/view/Window.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * Copyright (C) 2011 Jake Wharton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this 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.actionbarsherlock.view; + +import android.content.Context; + +/** + *

Abstract base class for a top-level window look and behavior policy. An + * instance of this class should be used as the top-level view added to the + * window manager. It provides standard UI policies such as a background, title + * area, default key processing, etc.

+ * + *

The only existing implementation of this abstract class is + * android.policy.PhoneWindow, which you should instantiate when needing a + * Window. Eventually that class will be refactored and a factory method added + * for creating Window instances without knowing about a particular + * implementation.

+ */ +public abstract class Window extends android.view.Window { + public static final long FEATURE_ACTION_BAR = android.view.Window.FEATURE_ACTION_BAR; + public static final long FEATURE_ACTION_BAR_OVERLAY = android.view.Window.FEATURE_ACTION_BAR_OVERLAY; + public static final long FEATURE_ACTION_MODE_OVERLAY = android.view.Window.FEATURE_ACTION_MODE_OVERLAY; + public static final long FEATURE_NO_TITLE = android.view.Window.FEATURE_NO_TITLE; + public static final long FEATURE_PROGRESS = android.view.Window.FEATURE_PROGRESS; + public static final long FEATURE_INDETERMINATE_PROGRESS = android.view.Window.FEATURE_INDETERMINATE_PROGRESS; + + /** + * Create a new instance for a context. + * + * @param context Context. + */ + private Window(Context context) { + super(context); + } + + + public interface Callback { + /** + * Called when a panel's menu item has been selected by the user. + * + * @param featureId The panel that the menu is in. + * @param item The menu item that was selected. + * + * @return boolean Return true to finish processing of selection, or + * false to perform the normal menu handling (calling its + * Runnable or sending a Message to its target Handler). + */ + public boolean onMenuItemSelected(int featureId, MenuItem item); + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserModel.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserModel.java new file mode 100644 index 0000000000..5b1ed0d4c8 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserModel.java @@ -0,0 +1,1104 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.widget; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.database.DataSetObservable; +import android.os.Handler; +import android.text.TextUtils; +import android.util.Log; +import android.util.Xml; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +/** + *

+ * This class represents a data model for choosing a component for handing a + * given {@link Intent}. The model is responsible for querying the system for + * activities that can handle the given intent and order found activities + * based on historical data of previous choices. The historical data is stored + * in an application private file. If a client does not want to have persistent + * choice history the file can be omitted, thus the activities will be ordered + * based on historical usage for the current session. + *

+ *

+ * For each backing history file there is a singleton instance of this class. Thus, + * several clients that specify the same history file will share the same model. Note + * that if multiple clients are sharing the same model they should implement semantically + * equivalent functionality since setting the model intent will change the found + * activities and they may be inconsistent with the functionality of some of the clients. + * For example, choosing a share activity can be implemented by a single backing + * model and two different views for performing the selection. If however, one of the + * views is used for sharing but the other for importing, for example, then each + * view should be backed by a separate model. + *

+ *

+ * The way clients interact with this class is as follows: + *

+ *

+ *

+ * 
+ *  // Get a model and set it to a couple of clients with semantically similar function.
+ *  ActivityChooserModel dataModel =
+ *      ActivityChooserModel.get(context, "task_specific_history_file_name.xml");
+ *
+ *  ActivityChooserModelClient modelClient1 = getActivityChooserModelClient1();
+ *  modelClient1.setActivityChooserModel(dataModel);
+ *
+ *  ActivityChooserModelClient modelClient2 = getActivityChooserModelClient2();
+ *  modelClient2.setActivityChooserModel(dataModel);
+ *
+ *  // Set an intent to choose a an activity for.
+ *  dataModel.setIntent(intent);
+ * 
+ * 
+ * 

+ *

+ * Note: This class is thread safe. + *

+ * + * @hide + */ +class ActivityChooserModel extends DataSetObservable { + + /** + * Client that utilizes an {@link com.actionbarsherlock.widget.ActivityChooserModel}. + */ + public interface ActivityChooserModelClient { + + /** + * Sets the {@link com.actionbarsherlock.widget.ActivityChooserModel}. + * + * @param dataModel The model. + */ + public void setActivityChooserModel(ActivityChooserModel dataModel); + } + + /** + * Defines a sorter that is responsible for sorting the activities + * based on the provided historical choices and an intent. + */ + public interface ActivitySorter { + + /** + * Sorts the activities in descending order of relevance + * based on previous history and an intent. + * + * @param intent The {@link Intent}. + * @param activities Activities to be sorted. + * @param historicalRecords Historical records. + */ + // This cannot be done by a simple comparator since an Activity weight + // is computed from history. Note that Activity implements Comparable. + public void sort(Intent intent, List activities, + List historicalRecords); + } + + /** + * Listener for choosing an activity. + */ + public interface OnChooseActivityListener { + + /** + * Called when an activity has been chosen. The client can decide whether + * an activity can be chosen and if so the caller of + * {@link com.actionbarsherlock.widget.ActivityChooserModel#chooseActivity(int)} will receive and {@link Intent} + * for launching it. + *

+ * Note: Modifying the intent is not permitted and + * any changes to the latter will be ignored. + *

+ * + * @param host The listener's host model. + * @param intent The intent for launching the chosen activity. + * @return Whether the intent is handled and should not be delivered to clients. + * + * @see com.actionbarsherlock.widget.ActivityChooserModel#chooseActivity(int) + */ + public boolean onChooseActivity(ActivityChooserModel host, Intent intent); + } + + /** + * Flag for selecting debug mode. + */ + private static final boolean DEBUG = false; + + /** + * Tag used for logging. + */ + private static final String LOG_TAG = ActivityChooserModel.class.getSimpleName(); + + /** + * The root tag in the history file. + */ + private static final String TAG_HISTORICAL_RECORDS = "historical-records"; + + /** + * The tag for a record in the history file. + */ + private static final String TAG_HISTORICAL_RECORD = "historical-record"; + + /** + * Attribute for the activity. + */ + private static final String ATTRIBUTE_ACTIVITY = "activity"; + + /** + * Attribute for the choice time. + */ + private static final String ATTRIBUTE_TIME = "time"; + + /** + * Attribute for the choice weight. + */ + private static final String ATTRIBUTE_WEIGHT = "weight"; + + /** + * The default name of the choice history file. + */ + public static final String DEFAULT_HISTORY_FILE_NAME = + "activity_choser_model_history.xml"; + + /** + * The default maximal length of the choice history. + */ + public static final int DEFAULT_HISTORY_MAX_LENGTH = 50; + + /** + * The amount with which to inflate a chosen activity when set as default. + */ + private static final int DEFAULT_ACTIVITY_INFLATION = 5; + + /** + * Default weight for a choice record. + */ + private static final float DEFAULT_HISTORICAL_RECORD_WEIGHT = 1.0f; + + /** + * The extension of the history file. + */ + private static final String HISTORY_FILE_EXTENSION = ".xml"; + + /** + * An invalid item index. + */ + private static final int INVALID_INDEX = -1; + + /** + * Lock to guard the model registry. + */ + private static final Object sRegistryLock = new Object(); + + /** + * This the registry for data models. + */ + private static final Map sDataModelRegistry = + new HashMap(); + + /** + * Lock for synchronizing on this instance. + */ + private final Object mInstanceLock = new Object(); + + /** + * List of activities that can handle the current intent. + */ + private final List mActivites = new ArrayList(); + + /** + * List with historical choice records. + */ + private final List mHistoricalRecords = new ArrayList(); + + /** + * Context for accessing resources. + */ + private final Context mContext; + + /** + * The name of the history file that backs this model. + */ + private final String mHistoryFileName; + + /** + * The intent for which a activity is being chosen. + */ + private Intent mIntent; + + /** + * The sorter for ordering activities based on intent and past choices. + */ + private ActivitySorter mActivitySorter = new DefaultSorter(); + + /** + * The maximal length of the choice history. + */ + private int mHistoryMaxSize = DEFAULT_HISTORY_MAX_LENGTH; + + /** + * Flag whether choice history can be read. In general many clients can + * share the same data model and {@link #readHistoricalData()} may be called + * by arbitrary of them any number of times. Therefore, this class guarantees + * that the very first read succeeds and subsequent reads can be performed + * only after a call to {@link #persistHistoricalData()} followed by change + * of the share records. + */ + private boolean mCanReadHistoricalData = true; + + /** + * Flag whether the choice history was read. This is used to enforce that + * before calling {@link #persistHistoricalData()} a call to + * {@link #persistHistoricalData()} has been made. This aims to avoid a + * scenario in which a choice history file exits, it is not read yet and + * it is overwritten. Note that always all historical records are read in + * full and the file is rewritten. This is necessary since we need to + * purge old records that are outside of the sliding window of past choices. + */ + private boolean mReadShareHistoryCalled = false; + + /** + * Flag whether the choice records have changed. In general many clients can + * share the same data model and {@link #persistHistoricalData()} may be called + * by arbitrary of them any number of times. Therefore, this class guarantees + * that choice history will be persisted only if it has changed. + */ + private boolean mHistoricalRecordsChanged = true; + + /** + * Hander for scheduling work on client tread. + */ + private final Handler mHandler = new Handler(); + + /** + * Policy for controlling how the model handles chosen activities. + */ + private OnChooseActivityListener mActivityChoserModelPolicy; + + /** + * Gets the data model backed by the contents of the provided file with historical data. + * Note that only one data model is backed by a given file, thus multiple calls with + * the same file name will return the same model instance. If no such instance is present + * it is created. + *

+ * Note: To use the default historical data file clients should explicitly + * pass as file name {@link #DEFAULT_HISTORY_FILE_NAME}. If no persistence of the choice + * history is desired clients should pass null for the file name. In such + * case a new model is returned for each invocation. + *

+ * + *

+ * Always use difference historical data files for semantically different actions. + * For example, sharing is different from importing. + *

+ * + * @param context Context for loading resources. + * @param historyFileName File name with choice history, null + * if the model should not be backed by a file. In this case the activities + * will be ordered only by data from the current session. + * + * @return The model. + */ + public static ActivityChooserModel get(Context context, String historyFileName) { + synchronized (sRegistryLock) { + ActivityChooserModel dataModel = sDataModelRegistry.get(historyFileName); + if (dataModel == null) { + dataModel = new ActivityChooserModel(context, historyFileName); + sDataModelRegistry.put(historyFileName, dataModel); + } + dataModel.readHistoricalData(); + return dataModel; + } + } + + /** + * Creates a new instance. + * + * @param context Context for loading resources. + * @param historyFileName The history XML file. + */ + private ActivityChooserModel(Context context, String historyFileName) { + mContext = context.getApplicationContext(); + if (!TextUtils.isEmpty(historyFileName) + && !historyFileName.endsWith(HISTORY_FILE_EXTENSION)) { + mHistoryFileName = historyFileName + HISTORY_FILE_EXTENSION; + } else { + mHistoryFileName = historyFileName; + } + } + + /** + * Sets an intent for which to choose a activity. + *

+ * Note: Clients must set only semantically similar + * intents for each data model. + *

+ * + * @param intent The intent. + */ + public void setIntent(Intent intent) { + synchronized (mInstanceLock) { + if (mIntent == intent) { + return; + } + mIntent = intent; + loadActivitiesLocked(); + } + } + + /** + * Gets the intent for which a activity is being chosen. + * + * @return The intent. + */ + public Intent getIntent() { + synchronized (mInstanceLock) { + return mIntent; + } + } + + /** + * Gets the number of activities that can handle the intent. + * + * @return The activity count. + * + * @see #setIntent(Intent) + */ + public int getActivityCount() { + synchronized (mInstanceLock) { + return mActivites.size(); + } + } + + /** + * Gets an activity at a given index. + * + * @return The activity. + * + * @see com.actionbarsherlock.widget.ActivityChooserModel.ActivityResolveInfo + * @see #setIntent(Intent) + */ + public ResolveInfo getActivity(int index) { + synchronized (mInstanceLock) { + return mActivites.get(index).resolveInfo; + } + } + + /** + * Gets the index of a the given activity. + * + * @param activity The activity index. + * + * @return The index if found, -1 otherwise. + */ + public int getActivityIndex(ResolveInfo activity) { + List activities = mActivites; + final int activityCount = activities.size(); + for (int i = 0; i < activityCount; i++) { + ActivityResolveInfo currentActivity = activities.get(i); + if (currentActivity.resolveInfo == activity) { + return i; + } + } + return INVALID_INDEX; + } + + /** + * Chooses a activity to handle the current intent. This will result in + * adding a historical record for that action and construct intent with + * its component name set such that it can be immediately started by the + * client. + *

+ * Note: By calling this method the client guarantees + * that the returned intent will be started. This intent is returned to + * the client solely to let additional customization before the start. + *

+ * + * @return An {@link Intent} for launching the activity or null if the + * policy has consumed the intent. + * + * @see com.actionbarsherlock.widget.ActivityChooserModel.HistoricalRecord + * @see com.actionbarsherlock.widget.ActivityChooserModel.OnChooseActivityListener + */ + public Intent chooseActivity(int index) { + ActivityResolveInfo chosenActivity = mActivites.get(index); + + ComponentName chosenName = new ComponentName( + chosenActivity.resolveInfo.activityInfo.packageName, + chosenActivity.resolveInfo.activityInfo.name); + + Intent choiceIntent = new Intent(mIntent); + choiceIntent.setComponent(chosenName); + + if (mActivityChoserModelPolicy != null) { + // Do not allow the policy to change the intent. + Intent choiceIntentCopy = new Intent(choiceIntent); + final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this, + choiceIntentCopy); + if (handled) { + return null; + } + } + + HistoricalRecord historicalRecord = new HistoricalRecord(chosenName, + System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT); + addHisoricalRecord(historicalRecord); + + return choiceIntent; + } + + /** + * Sets the listener for choosing an activity. + * + * @param listener The listener. + */ + public void setOnChooseActivityListener(OnChooseActivityListener listener) { + mActivityChoserModelPolicy = listener; + } + + /** + * Gets the default activity, The default activity is defined as the one + * with highest rank i.e. the first one in the list of activities that can + * handle the intent. + * + * @return The default activity, null id not activities. + * + * @see #getActivity(int) + */ + public ResolveInfo getDefaultActivity() { + synchronized (mInstanceLock) { + if (!mActivites.isEmpty()) { + return mActivites.get(0).resolveInfo; + } + } + return null; + } + + /** + * Sets the default activity. The default activity is set by adding a + * historical record with weight high enough that this activity will + * become the highest ranked. Such a strategy guarantees that the default + * will eventually change if not used. Also the weight of the record for + * setting a default is inflated with a constant amount to guarantee that + * it will stay as default for awhile. + * + * @param index The index of the activity to set as default. + */ + public void setDefaultActivity(int index) { + ActivityResolveInfo newDefaultActivity = mActivites.get(index); + ActivityResolveInfo oldDefaultActivity = mActivites.get(0); + + final float weight; + if (oldDefaultActivity != null) { + // Add a record with weight enough to boost the chosen at the top. + weight = oldDefaultActivity.weight - newDefaultActivity.weight + + DEFAULT_ACTIVITY_INFLATION; + } else { + weight = DEFAULT_HISTORICAL_RECORD_WEIGHT; + } + + ComponentName defaultName = new ComponentName( + newDefaultActivity.resolveInfo.activityInfo.packageName, + newDefaultActivity.resolveInfo.activityInfo.name); + HistoricalRecord historicalRecord = new HistoricalRecord(defaultName, + System.currentTimeMillis(), weight); + addHisoricalRecord(historicalRecord); + } + + /** + * Reads the history data from the backing file if the latter + * was provided. Calling this method more than once before a call + * to {@link #persistHistoricalData()} has been made has no effect. + *

+ * Note: Historical data is read asynchronously and + * as soon as the reading is completed any registered + * {@link DataSetObserver}s will be notified. Also no historical + * data is read until this method is invoked. + *

+ */ + private void readHistoricalData() { + synchronized (mInstanceLock) { + if (!mCanReadHistoricalData || !mHistoricalRecordsChanged) { + return; + } + mCanReadHistoricalData = false; + mReadShareHistoryCalled = true; + if (!TextUtils.isEmpty(mHistoryFileName)) { + /*AsyncTask.*/SERIAL_EXECUTOR.execute(new HistoryLoader()); + } + } + } + + private static final Executor SERIAL_EXECUTOR = Executors.newSingleThreadExecutor(); + + /** + * Persists the history data to the backing file if the latter + * was provided. Calling this method before a call to {@link #readHistoricalData()} + * throws an exception. Calling this method more than one without choosing an + * activity has not effect. + * + * @throws IllegalStateException If this method is called before a call to + * {@link #readHistoricalData()}. + */ + private void persistHistoricalData() { + synchronized (mInstanceLock) { + if (!mReadShareHistoryCalled) { + throw new IllegalStateException("No preceding call to #readHistoricalData"); + } + if (!mHistoricalRecordsChanged) { + return; + } + mHistoricalRecordsChanged = false; + mCanReadHistoricalData = true; + if (!TextUtils.isEmpty(mHistoryFileName)) { + /*AsyncTask.*/SERIAL_EXECUTOR.execute(new HistoryPersister()); + } + } + } + + /** + * Sets the sorter for ordering activities based on historical data and an intent. + * + * @param activitySorter The sorter. + * + * @see com.actionbarsherlock.widget.ActivityChooserModel.ActivitySorter + */ + public void setActivitySorter(ActivitySorter activitySorter) { + synchronized (mInstanceLock) { + if (mActivitySorter == activitySorter) { + return; + } + mActivitySorter = activitySorter; + sortActivities(); + } + } + + /** + * Sorts the activities based on history and an intent. If + * a sorter is not specified this a default implementation is used. + * + * @see #setActivitySorter(com.actionbarsherlock.widget.ActivityChooserModel.ActivitySorter) + */ + private void sortActivities() { + synchronized (mInstanceLock) { + if (mActivitySorter != null && !mActivites.isEmpty()) { + mActivitySorter.sort(mIntent, mActivites, + Collections.unmodifiableList(mHistoricalRecords)); + notifyChanged(); + } + } + } + + /** + * Sets the maximal size of the historical data. Defaults to + * {@link #DEFAULT_HISTORY_MAX_LENGTH} + *

+ * Note: Setting this property will immediately + * enforce the specified max history size by dropping enough old + * historical records to enforce the desired size. Thus, any + * records that exceed the history size will be discarded and + * irreversibly lost. + *

+ * + * @param historyMaxSize The max history size. + */ + public void setHistoryMaxSize(int historyMaxSize) { + synchronized (mInstanceLock) { + if (mHistoryMaxSize == historyMaxSize) { + return; + } + mHistoryMaxSize = historyMaxSize; + pruneExcessiveHistoricalRecordsLocked(); + sortActivities(); + } + } + + /** + * Gets the history max size. + * + * @return The history max size. + */ + public int getHistoryMaxSize() { + synchronized (mInstanceLock) { + return mHistoryMaxSize; + } + } + + /** + * Gets the history size. + * + * @return The history size. + */ + public int getHistorySize() { + synchronized (mInstanceLock) { + return mHistoricalRecords.size(); + } + } + + /** + * Adds a historical record. + * + * @param historicalRecord The record to add. + * @return True if the record was added. + */ + private boolean addHisoricalRecord(HistoricalRecord historicalRecord) { + synchronized (mInstanceLock) { + final boolean added = mHistoricalRecords.add(historicalRecord); + if (added) { + mHistoricalRecordsChanged = true; + pruneExcessiveHistoricalRecordsLocked(); + persistHistoricalData(); + sortActivities(); + } + return added; + } + } + + /** + * Prunes older excessive records to guarantee {@link #mHistoryMaxSize}. + */ + private void pruneExcessiveHistoricalRecordsLocked() { + List choiceRecords = mHistoricalRecords; + final int pruneCount = choiceRecords.size() - mHistoryMaxSize; + if (pruneCount <= 0) { + return; + } + mHistoricalRecordsChanged = true; + for (int i = 0; i < pruneCount; i++) { + HistoricalRecord prunedRecord = choiceRecords.remove(0); + if (DEBUG) { + Log.i(LOG_TAG, "Pruned: " + prunedRecord); + } + } + } + + /** + * Loads the activities. + */ + private void loadActivitiesLocked() { + mActivites.clear(); + if (mIntent != null) { + List resolveInfos = + mContext.getPackageManager().queryIntentActivities(mIntent, 0); + final int resolveInfoCount = resolveInfos.size(); + for (int i = 0; i < resolveInfoCount; i++) { + ResolveInfo resolveInfo = resolveInfos.get(i); + mActivites.add(new ActivityResolveInfo(resolveInfo)); + } + sortActivities(); + } else { + notifyChanged(); + } + } + + /** + * Represents a record in the history. + */ + public final static class HistoricalRecord { + + /** + * The activity name. + */ + public final ComponentName activity; + + /** + * The choice time. + */ + public final long time; + + /** + * The record weight. + */ + public final float weight; + + /** + * Creates a new instance. + * + * @param activityName The activity component name flattened to string. + * @param time The time the activity was chosen. + * @param weight The weight of the record. + */ + public HistoricalRecord(String activityName, long time, float weight) { + this(ComponentName.unflattenFromString(activityName), time, weight); + } + + /** + * Creates a new instance. + * + * @param activityName The activity name. + * @param time The time the activity was chosen. + * @param weight The weight of the record. + */ + public HistoricalRecord(ComponentName activityName, long time, float weight) { + this.activity = activityName; + this.time = time; + this.weight = weight; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((activity == null) ? 0 : activity.hashCode()); + result = prime * result + (int) (time ^ (time >>> 32)); + result = prime * result + Float.floatToIntBits(weight); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + HistoricalRecord other = (HistoricalRecord) obj; + if (activity == null) { + if (other.activity != null) { + return false; + } + } else if (!activity.equals(other.activity)) { + return false; + } + if (time != other.time) { + return false; + } + if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("["); + builder.append("; activity:").append(activity); + builder.append("; time:").append(time); + builder.append("; weight:").append(new BigDecimal(weight)); + builder.append("]"); + return builder.toString(); + } + } + + /** + * Represents an activity. + */ + public final class ActivityResolveInfo implements Comparable { + + /** + * The {@link ResolveInfo} of the activity. + */ + public final ResolveInfo resolveInfo; + + /** + * Weight of the activity. Useful for sorting. + */ + public float weight; + + /** + * Creates a new instance. + * + * @param resolveInfo activity {@link ResolveInfo}. + */ + public ActivityResolveInfo(ResolveInfo resolveInfo) { + this.resolveInfo = resolveInfo; + } + + @Override + public int hashCode() { + return 31 + Float.floatToIntBits(weight); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ActivityResolveInfo other = (ActivityResolveInfo) obj; + if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { + return false; + } + return true; + } + + public int compareTo(ActivityResolveInfo another) { + return Float.floatToIntBits(another.weight) - Float.floatToIntBits(weight); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("["); + builder.append("resolveInfo:").append(resolveInfo.toString()); + builder.append("; weight:").append(new BigDecimal(weight)); + builder.append("]"); + return builder.toString(); + } + } + + /** + * Default activity sorter implementation. + */ + private final class DefaultSorter implements ActivitySorter { + private static final float WEIGHT_DECAY_COEFFICIENT = 0.95f; + + private final Map mPackageNameToActivityMap = + new HashMap(); + + public void sort(Intent intent, List activities, + List historicalRecords) { + Map packageNameToActivityMap = + mPackageNameToActivityMap; + packageNameToActivityMap.clear(); + + final int activityCount = activities.size(); + for (int i = 0; i < activityCount; i++) { + ActivityResolveInfo activity = activities.get(i); + activity.weight = 0.0f; + String packageName = activity.resolveInfo.activityInfo.packageName; + packageNameToActivityMap.put(packageName, activity); + } + + final int lastShareIndex = historicalRecords.size() - 1; + float nextRecordWeight = 1; + for (int i = lastShareIndex; i >= 0; i--) { + HistoricalRecord historicalRecord = historicalRecords.get(i); + String packageName = historicalRecord.activity.getPackageName(); + ActivityResolveInfo activity = packageNameToActivityMap.get(packageName); + if (activity != null) { + activity.weight += historicalRecord.weight * nextRecordWeight; + nextRecordWeight = nextRecordWeight * WEIGHT_DECAY_COEFFICIENT; + } + } + + Collections.sort(activities); + + if (DEBUG) { + for (int i = 0; i < activityCount; i++) { + Log.i(LOG_TAG, "Sorted: " + activities.get(i)); + } + } + } + } + + /** + * Command for reading the historical records from a file off the UI thread. + */ + private final class HistoryLoader implements Runnable { + + public void run() { + FileInputStream fis = null; + try { + fis = mContext.openFileInput(mHistoryFileName); + } catch (FileNotFoundException fnfe) { + if (DEBUG) { + Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName); + } + return; + } + try { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(fis, null); + + int type = XmlPullParser.START_DOCUMENT; + while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { + type = parser.next(); + } + + if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) { + throw new XmlPullParserException("Share records file does not start with " + + TAG_HISTORICAL_RECORDS + " tag."); + } + + List readRecords = new ArrayList(); + + while (true) { + type = parser.next(); + if (type == XmlPullParser.END_DOCUMENT) { + break; + } + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + String nodeName = parser.getName(); + if (!TAG_HISTORICAL_RECORD.equals(nodeName)) { + throw new XmlPullParserException("Share records file not well-formed."); + } + + String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY); + final long time = + Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME)); + final float weight = + Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT)); + + HistoricalRecord readRecord = new HistoricalRecord(activity, time, + weight); + readRecords.add(readRecord); + + if (DEBUG) { + Log.i(LOG_TAG, "Read " + readRecord.toString()); + } + } + + if (DEBUG) { + Log.i(LOG_TAG, "Read " + readRecords.size() + " historical records."); + } + + synchronized (mInstanceLock) { + Set uniqueShareRecords = + new LinkedHashSet(readRecords); + + // Make sure no duplicates. Example: Read a file with + // one record, add one record, persist the two records, + // add a record, read the persisted records - the + // read two records should not be added again. + List historicalRecords = mHistoricalRecords; + final int historicalRecordsCount = historicalRecords.size(); + for (int i = historicalRecordsCount - 1; i >= 0; i--) { + HistoricalRecord historicalRecord = historicalRecords.get(i); + uniqueShareRecords.add(historicalRecord); + } + + if (historicalRecords.size() == uniqueShareRecords.size()) { + return; + } + + // Make sure the oldest records go to the end. + historicalRecords.clear(); + historicalRecords.addAll(uniqueShareRecords); + + mHistoricalRecordsChanged = true; + + // Do this on the client thread since the client may be on the UI + // thread, wait for data changes which happen during sorting, and + // perform UI modification based on the data change. + mHandler.post(new Runnable() { + public void run() { + pruneExcessiveHistoricalRecordsLocked(); + sortActivities(); + } + }); + } + } catch (XmlPullParserException xppe) { + Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe); + } catch (IOException ioe) { + Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException ioe) { + /* ignore */ + } + } + } + } + } + + /** + * Command for persisting the historical records to a file off the UI thread. + */ + private final class HistoryPersister implements Runnable { + + public void run() { + FileOutputStream fos = null; + List records = null; + + synchronized (mInstanceLock) { + records = new ArrayList(mHistoricalRecords); + } + + try { + fos = mContext.openFileOutput(mHistoryFileName, Context.MODE_PRIVATE); + } catch (FileNotFoundException fnfe) { + Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, fnfe); + return; + } + + XmlSerializer serializer = Xml.newSerializer(); + + try { + serializer.setOutput(fos, null); + serializer.startDocument("UTF-8", true); + serializer.startTag(null, TAG_HISTORICAL_RECORDS); + + final int recordCount = records.size(); + for (int i = 0; i < recordCount; i++) { + HistoricalRecord record = records.remove(0); + serializer.startTag(null, TAG_HISTORICAL_RECORD); + serializer.attribute(null, ATTRIBUTE_ACTIVITY, record.activity.flattenToString()); + serializer.attribute(null, ATTRIBUTE_TIME, String.valueOf(record.time)); + serializer.attribute(null, ATTRIBUTE_WEIGHT, String.valueOf(record.weight)); + serializer.endTag(null, TAG_HISTORICAL_RECORD); + if (DEBUG) { + Log.i(LOG_TAG, "Wrote " + record.toString()); + } + } + + serializer.endTag(null, TAG_HISTORICAL_RECORDS); + serializer.endDocument(); + + if (DEBUG) { + Log.i(LOG_TAG, "Wrote " + recordCount + " historical records."); + } + } catch (IllegalArgumentException iae) { + Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, iae); + } catch (IllegalStateException ise) { + Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ise); + } catch (IOException ioe) { + Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ioe); + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + /* ignore */ + } + } + } + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserView.java new file mode 100644 index 0000000000..e19ea9e9e1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ActivityChooserView.java @@ -0,0 +1,827 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.widget; + +import android.os.Build; +import com.actionbarsherlock.R; +import com.actionbarsherlock.internal.widget.IcsLinearLayout; +import com.actionbarsherlock.internal.widget.IcsListPopupWindow; +import com.actionbarsherlock.view.ActionProvider; +import com.actionbarsherlock.widget.ActivityChooserModel.ActivityChooserModelClient; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.database.DataSetObserver; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.PopupWindow; +import android.widget.TextView; + +/** + * This class is a view for choosing an activity for handling a given {@link Intent}. + *

+ * The view is composed of two adjacent buttons: + *

    + *
  • + * The left button is an immediate action and allows one click activity choosing. + * Tapping this button immediately executes the intent without requiring any further + * user input. Long press on this button shows a popup for changing the default + * activity. + *
  • + *
  • + * The right button is an overflow action and provides an optimized menu + * of additional activities. Tapping this button shows a popup anchored to this + * view, listing the most frequently used activities. This list is initially + * limited to a small number of items in frequency used order. The last item, + * "Show all..." serves as an affordance to display all available activities. + *
  • + *
+ *

+ * + * @hide + */ +class ActivityChooserView extends ViewGroup implements ActivityChooserModelClient { + + /** + * An adapter for displaying the activities in an {@link AdapterView}. + */ + private final ActivityChooserViewAdapter mAdapter; + + /** + * Implementation of various interfaces to avoid publishing them in the APIs. + */ + private final Callbacks mCallbacks; + + /** + * The content of this view. + */ + private final IcsLinearLayout mActivityChooserContent; + + /** + * Stores the background drawable to allow hiding and latter showing. + */ + private final Drawable mActivityChooserContentBackground; + + /** + * The expand activities action button; + */ + private final FrameLayout mExpandActivityOverflowButton; + + /** + * The image for the expand activities action button; + */ + private final ImageView mExpandActivityOverflowButtonImage; + + /** + * The default activities action button; + */ + private final FrameLayout mDefaultActivityButton; + + /** + * The image for the default activities action button; + */ + private final ImageView mDefaultActivityButtonImage; + + /** + * The maximal width of the list popup. + */ + private final int mListPopupMaxWidth; + + /** + * The ActionProvider hosting this view, if applicable. + */ + ActionProvider mProvider; + + /** + * Observer for the model data. + */ + private final DataSetObserver mModelDataSetOberver = new DataSetObserver() { + + @Override + public void onChanged() { + super.onChanged(); + mAdapter.notifyDataSetChanged(); + } + @Override + public void onInvalidated() { + super.onInvalidated(); + mAdapter.notifyDataSetInvalidated(); + } + }; + + private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (isShowingPopup()) { + if (!isShown()) { + getListPopupWindow().dismiss(); + } else { + getListPopupWindow().show(); + if (mProvider != null) { + mProvider.subUiVisibilityChanged(true); + } + } + } + } + }; + + /** + * Popup window for showing the activity overflow list. + */ + private IcsListPopupWindow mListPopupWindow; + + /** + * Listener for the dismissal of the popup/alert. + */ + private PopupWindow.OnDismissListener mOnDismissListener; + + /** + * Flag whether a default activity currently being selected. + */ + private boolean mIsSelectingDefaultActivity; + + /** + * The count of activities in the popup. + */ + private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT; + + /** + * Flag whether this view is attached to a window. + */ + private boolean mIsAttachedToWindow; + + /** + * String resource for formatting content description of the default target. + */ + private int mDefaultActionButtonContentDescription; + + private final Context mContext; + + /** + * Create a new instance. + * + * @param context The application environment. + */ + public ActivityChooserView(Context context) { + this(context, null); + } + + /** + * Create a new instance. + * + * @param context The application environment. + * @param attrs A collection of attributes. + */ + public ActivityChooserView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + /** + * Create a new instance. + * + * @param context The application environment. + * @param attrs A collection of attributes. + * @param defStyle The default style to apply to this view. + */ + public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mContext = context; + + TypedArray attributesArray = context.obtainStyledAttributes(attrs, + R.styleable.SherlockActivityChooserView, defStyle, 0); + + mInitialActivityCount = attributesArray.getInt( + R.styleable.SherlockActivityChooserView_initialActivityCount, + ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT); + + Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable( + R.styleable.SherlockActivityChooserView_expandActivityOverflowButtonDrawable); + + attributesArray.recycle(); + + LayoutInflater inflater = LayoutInflater.from(mContext); + inflater.inflate(R.layout.abs__activity_chooser_view, this, true); + + mCallbacks = new Callbacks(); + + mActivityChooserContent = (IcsLinearLayout) findViewById(R.id.abs__activity_chooser_view_content); + mActivityChooserContentBackground = mActivityChooserContent.getBackground(); + + mDefaultActivityButton = (FrameLayout) findViewById(R.id.abs__default_activity_button); + mDefaultActivityButton.setOnClickListener(mCallbacks); + mDefaultActivityButton.setOnLongClickListener(mCallbacks); + mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.abs__image); + + mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.abs__expand_activities_button); + mExpandActivityOverflowButton.setOnClickListener(mCallbacks); + mExpandActivityOverflowButtonImage = + (ImageView) mExpandActivityOverflowButton.findViewById(R.id.abs__image); + mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable); + + mAdapter = new ActivityChooserViewAdapter(); + mAdapter.registerDataSetObserver(new DataSetObserver() { + @Override + public void onChanged() { + super.onChanged(); + updateAppearance(); + } + }); + + Resources resources = context.getResources(); + mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2, + resources.getDimensionPixelSize(R.dimen.abs__config_prefDialogWidth)); + } + + /** + * {@inheritDoc} + */ + public void setActivityChooserModel(ActivityChooserModel dataModel) { + mAdapter.setDataModel(dataModel); + if (isShowingPopup()) { + dismissPopup(); + showPopup(); + } + } + + /** + * Sets the background for the button that expands the activity + * overflow list. + * + * Note: Clients would like to set this drawable + * as a clue about the action the chosen activity will perform. For + * example, if a share activity is to be chosen the drawable should + * give a clue that sharing is to be performed. + * + * @param drawable The drawable. + */ + public void setExpandActivityOverflowButtonDrawable(Drawable drawable) { + mExpandActivityOverflowButtonImage.setImageDrawable(drawable); + } + + /** + * Sets the content description for the button that expands the activity + * overflow list. + * + * description as a clue about the action performed by the button. + * For example, if a share activity is to be chosen the content + * description should be something like "Share with". + * + * @param resourceId The content description resource id. + */ + public void setExpandActivityOverflowButtonContentDescription(int resourceId) { + CharSequence contentDescription = mContext.getString(resourceId); + mExpandActivityOverflowButtonImage.setContentDescription(contentDescription); + } + + /** + * Set the provider hosting this view, if applicable. + * @hide Internal use only + */ + public void setProvider(ActionProvider provider) { + mProvider = provider; + } + + /** + * Shows the popup window with activities. + * + * @return True if the popup was shown, false if already showing. + */ + public boolean showPopup() { + if (isShowingPopup() || !mIsAttachedToWindow) { + return false; + } + mIsSelectingDefaultActivity = false; + showPopupUnchecked(mInitialActivityCount); + return true; + } + + /** + * Shows the popup no matter if it was already showing. + * + * @param maxActivityCount The max number of activities to display. + */ + private void showPopupUnchecked(int maxActivityCount) { + if (mAdapter.getDataModel() == null) { + throw new IllegalStateException("No data model. Did you call #setDataModel?"); + } + + getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); + + final boolean defaultActivityButtonShown = + mDefaultActivityButton.getVisibility() == VISIBLE; + + final int activityCount = mAdapter.getActivityCount(); + final int maxActivityCountOffset = defaultActivityButtonShown ? 1 : 0; + if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED + && activityCount > maxActivityCount + maxActivityCountOffset) { + mAdapter.setShowFooterView(true); + mAdapter.setMaxActivityCount(maxActivityCount - 1); + } else { + mAdapter.setShowFooterView(false); + mAdapter.setMaxActivityCount(maxActivityCount); + } + + IcsListPopupWindow popupWindow = getListPopupWindow(); + if (!popupWindow.isShowing()) { + if (mIsSelectingDefaultActivity || !defaultActivityButtonShown) { + mAdapter.setShowDefaultActivity(true, defaultActivityButtonShown); + } else { + mAdapter.setShowDefaultActivity(false, false); + } + final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth); + popupWindow.setContentWidth(contentWidth); + popupWindow.show(); + if (mProvider != null) { + mProvider.subUiVisibilityChanged(true); + } + popupWindow.getListView().setContentDescription(mContext.getString( + R.string.abs__activitychooserview_choose_application)); + } + } + + /** + * Dismisses the popup window with activities. + * + * @return True if dismissed, false if already dismissed. + */ + public boolean dismissPopup() { + if (isShowingPopup()) { + getListPopupWindow().dismiss(); + ViewTreeObserver viewTreeObserver = getViewTreeObserver(); + if (viewTreeObserver.isAlive()) { + viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener); + } + } + return true; + } + + /** + * Gets whether the popup window with activities is shown. + * + * @return True if the popup is shown. + */ + public boolean isShowingPopup() { + return getListPopupWindow().isShowing(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + ActivityChooserModel dataModel = mAdapter.getDataModel(); + if (dataModel != null) { + dataModel.registerObserver(mModelDataSetOberver); + } + mIsAttachedToWindow = true; + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + ActivityChooserModel dataModel = mAdapter.getDataModel(); + if (dataModel != null) { + try { + dataModel.unregisterObserver(mModelDataSetOberver); + } catch (IllegalStateException e) { + //Oh, well... fixes issue #557 + } + } + ViewTreeObserver viewTreeObserver = getViewTreeObserver(); + if (viewTreeObserver.isAlive()) { + viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener); + } + mIsAttachedToWindow = false; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + View child = mActivityChooserContent; + // If the default action is not visible we want to be as tall as the + // ActionBar so if this widget is used in the latter it will look as + // a normal action button. + if (mDefaultActivityButton.getVisibility() != VISIBLE) { + heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), + MeasureSpec.EXACTLY); + } + measureChild(child, widthMeasureSpec, heightMeasureSpec); + setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight()); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + mActivityChooserContent.layout(0, 0, right - left, bottom - top); + if (getListPopupWindow().isShowing()) { + showPopupUnchecked(mAdapter.getMaxActivityCount()); + } else { + dismissPopup(); + } + } + + public ActivityChooserModel getDataModel() { + return mAdapter.getDataModel(); + } + + /** + * Sets a listener to receive a callback when the popup is dismissed. + * + * @param listener The listener to be notified. + */ + public void setOnDismissListener(PopupWindow.OnDismissListener listener) { + mOnDismissListener = listener; + } + + /** + * Sets the initial count of items shown in the activities popup + * i.e. the items before the popup is expanded. This is an upper + * bound since it is not guaranteed that such number of intent + * handlers exist. + * + * @param itemCount The initial popup item count. + */ + public void setInitialActivityCount(int itemCount) { + mInitialActivityCount = itemCount; + } + + /** + * Sets a content description of the default action button. This + * resource should be a string taking one formatting argument and + * will be used for formatting the content description of the button + * dynamically as the default target changes. For example, a resource + * pointing to the string "share with %1$s" will result in a content + * description "share with Bluetooth" for the Bluetooth activity. + * + * @param resourceId The resource id. + */ + public void setDefaultActionButtonContentDescription(int resourceId) { + mDefaultActionButtonContentDescription = resourceId; + } + + /** + * Gets the list popup window which is lazily initialized. + * + * @return The popup. + */ + private IcsListPopupWindow getListPopupWindow() { + if (mListPopupWindow == null) { + mListPopupWindow = new IcsListPopupWindow(getContext()); + mListPopupWindow.setAdapter(mAdapter); + mListPopupWindow.setAnchorView(ActivityChooserView.this); + mListPopupWindow.setModal(true); + mListPopupWindow.setOnItemClickListener(mCallbacks); + mListPopupWindow.setOnDismissListener(mCallbacks); + } + return mListPopupWindow; + } + + /** + * Updates the buttons state. + */ + private void updateAppearance() { + // Expand overflow button. + if (mAdapter.getCount() > 0) { + mExpandActivityOverflowButton.setEnabled(true); + } else { + mExpandActivityOverflowButton.setEnabled(false); + } + // Default activity button. + final int activityCount = mAdapter.getActivityCount(); + final int historySize = mAdapter.getHistorySize(); + if (activityCount > 0 && historySize > 0) { + mDefaultActivityButton.setVisibility(VISIBLE); + ResolveInfo activity = mAdapter.getDefaultActivity(); + PackageManager packageManager = mContext.getPackageManager(); + mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager)); + if (mDefaultActionButtonContentDescription != 0) { + CharSequence label = activity.loadLabel(packageManager); + String contentDescription = mContext.getString( + mDefaultActionButtonContentDescription, label); + mDefaultActivityButton.setContentDescription(contentDescription); + } + } else { + mDefaultActivityButton.setVisibility(View.GONE); + } + // Activity chooser content. + if (mDefaultActivityButton.getVisibility() == VISIBLE) { + mActivityChooserContent.setBackgroundDrawable(mActivityChooserContentBackground); + } else { + mActivityChooserContent.setBackgroundDrawable(null); + mActivityChooserContent.setPadding(0, 0, 0, 0); + } + } + + /** + * Interface implementation to avoid publishing them in the APIs. + */ + private class Callbacks implements AdapterView.OnItemClickListener, + View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener { + + // AdapterView#OnItemClickListener + public void onItemClick(AdapterView parent, View view, int position, long id) { + ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter(); + final int itemViewType = adapter.getItemViewType(position); + switch (itemViewType) { + case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: { + showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED); + } break; + case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: { + dismissPopup(); + if (mIsSelectingDefaultActivity) { + // The item at position zero is the default already. + if (position > 0) { + mAdapter.getDataModel().setDefaultActivity(position); + } + } else { + // If the default target is not shown in the list, the first + // item in the model is default action => adjust index + position = mAdapter.getShowDefaultActivity() ? position : position + 1; + Intent launchIntent = mAdapter.getDataModel().chooseActivity(position); + if (launchIntent != null) { + mContext.startActivity(launchIntent); + } + } + } break; + default: + throw new IllegalArgumentException(); + } + } + + // View.OnClickListener + public void onClick(View view) { + if (view == mDefaultActivityButton) { + dismissPopup(); + ResolveInfo defaultActivity = mAdapter.getDefaultActivity(); + final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity); + Intent launchIntent = mAdapter.getDataModel().chooseActivity(index); + if (launchIntent != null) { + mContext.startActivity(launchIntent); + } + } else if (view == mExpandActivityOverflowButton) { + mIsSelectingDefaultActivity = false; + showPopupUnchecked(mInitialActivityCount); + } else { + throw new IllegalArgumentException(); + } + } + + // OnLongClickListener#onLongClick + @Override + public boolean onLongClick(View view) { + if (view == mDefaultActivityButton) { + if (mAdapter.getCount() > 0) { + mIsSelectingDefaultActivity = true; + showPopupUnchecked(mInitialActivityCount); + } + } else { + throw new IllegalArgumentException(); + } + return true; + } + + // PopUpWindow.OnDismissListener#onDismiss + public void onDismiss() { + notifyOnDismissListener(); + if (mProvider != null) { + mProvider.subUiVisibilityChanged(false); + } + } + + private void notifyOnDismissListener() { + if (mOnDismissListener != null) { + mOnDismissListener.onDismiss(); + } + } + } + + private static class SetActivated { + public static void invoke(View view, boolean activated) { + view.setActivated(activated); + } + } + + private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; + + /** + * Adapter for backing the list of activities shown in the popup. + */ + private class ActivityChooserViewAdapter extends BaseAdapter { + + public static final int MAX_ACTIVITY_COUNT_UNLIMITED = Integer.MAX_VALUE; + + public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4; + + private static final int ITEM_VIEW_TYPE_ACTIVITY = 0; + + private static final int ITEM_VIEW_TYPE_FOOTER = 1; + + private static final int ITEM_VIEW_TYPE_COUNT = 3; + + private ActivityChooserModel mDataModel; + + private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT; + + private boolean mShowDefaultActivity; + + private boolean mHighlightDefaultActivity; + + private boolean mShowFooterView; + + public void setDataModel(ActivityChooserModel dataModel) { + ActivityChooserModel oldDataModel = mAdapter.getDataModel(); + if (oldDataModel != null && isShown()) { + try { + oldDataModel.unregisterObserver(mModelDataSetOberver); + } catch (IllegalStateException e) { + //Oh, well... fixes issue #557 + } + } + mDataModel = dataModel; + if (dataModel != null && isShown()) { + dataModel.registerObserver(mModelDataSetOberver); + } + notifyDataSetChanged(); + } + + @Override + public int getItemViewType(int position) { + if (mShowFooterView && position == getCount() - 1) { + return ITEM_VIEW_TYPE_FOOTER; + } else { + return ITEM_VIEW_TYPE_ACTIVITY; + } + } + + @Override + public int getViewTypeCount() { + return ITEM_VIEW_TYPE_COUNT; + } + + public int getCount() { + int count = 0; + int activityCount = mDataModel.getActivityCount(); + if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { + activityCount--; + } + count = Math.min(activityCount, mMaxActivityCount); + if (mShowFooterView) { + count++; + } + return count; + } + + public Object getItem(int position) { + final int itemViewType = getItemViewType(position); + switch (itemViewType) { + case ITEM_VIEW_TYPE_FOOTER: + return null; + case ITEM_VIEW_TYPE_ACTIVITY: + if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { + position++; + } + return mDataModel.getActivity(position); + default: + throw new IllegalArgumentException(); + } + } + + public long getItemId(int position) { + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + final int itemViewType = getItemViewType(position); + switch (itemViewType) { + case ITEM_VIEW_TYPE_FOOTER: + if (convertView == null || convertView.getId() != ITEM_VIEW_TYPE_FOOTER) { + convertView = LayoutInflater.from(getContext()).inflate( + R.layout.abs__activity_chooser_view_list_item, parent, false); + convertView.setId(ITEM_VIEW_TYPE_FOOTER); + TextView titleView = (TextView) convertView.findViewById(R.id.abs__title); + titleView.setText(mContext.getString( + R.string.abs__activity_chooser_view_see_all)); + } + return convertView; + case ITEM_VIEW_TYPE_ACTIVITY: + if (convertView == null || convertView.getId() != R.id.abs__list_item) { + convertView = LayoutInflater.from(getContext()).inflate( + R.layout.abs__activity_chooser_view_list_item, parent, false); + } + PackageManager packageManager = mContext.getPackageManager(); + // Set the icon + ImageView iconView = (ImageView) convertView.findViewById(R.id.abs__icon); + ResolveInfo activity = (ResolveInfo) getItem(position); + iconView.setImageDrawable(activity.loadIcon(packageManager)); + // Set the title. + TextView titleView = (TextView) convertView.findViewById(R.id.abs__title); + titleView.setText(activity.loadLabel(packageManager)); + if (IS_HONEYCOMB) { + // Highlight the default. + if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) { + SetActivated.invoke(convertView, true); + } else { + SetActivated.invoke(convertView, false); + } + } + return convertView; + default: + throw new IllegalArgumentException(); + } + } + + public int measureContentWidth() { + // The user may have specified some of the target not to be shown but we + // want to measure all of them since after expansion they should fit. + final int oldMaxActivityCount = mMaxActivityCount; + mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED; + + int contentWidth = 0; + View itemView = null; + + final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final int count = getCount(); + + for (int i = 0; i < count; i++) { + itemView = getView(i, itemView, null); + itemView.measure(widthMeasureSpec, heightMeasureSpec); + contentWidth = Math.max(contentWidth, itemView.getMeasuredWidth()); + } + + mMaxActivityCount = oldMaxActivityCount; + + return contentWidth; + } + + public void setMaxActivityCount(int maxActivityCount) { + if (mMaxActivityCount != maxActivityCount) { + mMaxActivityCount = maxActivityCount; + notifyDataSetChanged(); + } + } + + public ResolveInfo getDefaultActivity() { + return mDataModel.getDefaultActivity(); + } + + public void setShowFooterView(boolean showFooterView) { + if (mShowFooterView != showFooterView) { + mShowFooterView = showFooterView; + notifyDataSetChanged(); + } + } + + public int getActivityCount() { + return mDataModel.getActivityCount(); + } + + public int getHistorySize() { + return mDataModel.getHistorySize(); + } + + public int getMaxActivityCount() { + return mMaxActivityCount; + } + + public ActivityChooserModel getDataModel() { + return mDataModel; + } + + public void setShowDefaultActivity(boolean showDefaultActivity, + boolean highlightDefaultActivity) { + if (mShowDefaultActivity != showDefaultActivity + || mHighlightDefaultActivity != highlightDefaultActivity) { + mShowDefaultActivity = showDefaultActivity; + mHighlightDefaultActivity = highlightDefaultActivity; + notifyDataSetChanged(); + } + } + + public boolean getShowDefaultActivity() { + return mShowDefaultActivity; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SearchView.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SearchView.java new file mode 100644 index 0000000000..c9e7897d43 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SearchView.java @@ -0,0 +1,1811 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.widget; + +import android.app.PendingIntent; +import android.app.SearchManager; +import android.app.SearchableInfo; +import android.content.ActivityNotFoundException; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.database.Cursor; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.ResultReceiver; +import android.speech.RecognizerIntent; +import android.support.v4.view.KeyEventCompat; +import android.support.v4.widget.CursorAdapter; +import android.text.Editable; +import android.text.InputType; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.text.style.ImageSpan; +import android.util.AttributeSet; +import android.util.Log; +import android.util.TypedValue; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.AutoCompleteTextView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.TextView.OnEditorActionListener; +import com.actionbarsherlock.R; +import com.actionbarsherlock.view.CollapsibleActionView; + +import java.lang.reflect.Method; +import java.util.WeakHashMap; + +import static com.actionbarsherlock.widget.SuggestionsAdapter.getColumnString; + +/** + * A widget that provides a user interface for the user to enter a search query and submit a request + * to a search provider. Shows a list of query suggestions or results, if available, and allows the + * user to pick a suggestion or result to launch into. + * + *

+ * When the SearchView is used in an ActionBar as an action view for a collapsible menu item, it + * needs to be set to iconified by default using {@link #setIconifiedByDefault(boolean) + * setIconifiedByDefault(true)}. This is the default, so nothing needs to be done. + *

+ *

+ * If you want the search field to always be visible, then call setIconifiedByDefault(false). + *

+ * + *
+ *

Developer Guides

+ *

For information about using {@code SearchView}, read the + * Search developer guide.

+ *
+ * + * @see android.view.MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW + * @attr ref android.R.styleable#SearchView_iconifiedByDefault + * @attr ref android.R.styleable#SearchView_imeOptions + * @attr ref android.R.styleable#SearchView_inputType + * @attr ref android.R.styleable#SearchView_maxWidth + * @attr ref android.R.styleable#SearchView_queryHint + */ +public class SearchView extends LinearLayout implements CollapsibleActionView { + + private static final boolean DBG = false; + private static final String LOG_TAG = "SearchView"; + + /** + * Private constant for removing the microphone in the keyboard. + */ + private static final String IME_OPTION_NO_MICROPHONE = "nm"; + + private OnQueryTextListener mOnQueryChangeListener; + private OnCloseListener mOnCloseListener; + private OnFocusChangeListener mOnQueryTextFocusChangeListener; + private OnSuggestionListener mOnSuggestionListener; + private OnClickListener mOnSearchClickListener; + + private boolean mIconifiedByDefault; + private boolean mIconified; + private CursorAdapter mSuggestionsAdapter; + private View mSearchButton; + private View mSubmitButton; + private View mSearchPlate; + private View mSubmitArea; + private ImageView mCloseButton; + private View mSearchEditFrame; + private View mVoiceButton; + private SearchAutoComplete mQueryTextView; + private View mDropDownAnchor; + private ImageView mSearchHintIcon; + private boolean mSubmitButtonEnabled; + private CharSequence mQueryHint; + private boolean mQueryRefinement; + private boolean mClearingFocus; + private int mMaxWidth; + private boolean mVoiceButtonEnabled; + private CharSequence mOldQueryText; + private CharSequence mUserQuery; + private boolean mExpandedInActionView; + private int mCollapsedImeOptions; + + private SearchableInfo mSearchable; + private Bundle mAppSearchData; + + /* + * SearchView can be set expanded before the IME is ready to be shown during + * initial UI setup. The show operation is asynchronous to account for this. + */ + private Runnable mShowImeRunnable = new Runnable() { + public void run() { + InputMethodManager imm = (InputMethodManager) + getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + + if (imm != null) { + showSoftInputUnchecked(SearchView.this, imm, 0); + } + } + }; + + private Runnable mUpdateDrawableStateRunnable = new Runnable() { + public void run() { + updateFocusedState(); + } + }; + + private Runnable mReleaseCursorRunnable = new Runnable() { + public void run() { + if (mSuggestionsAdapter != null && mSuggestionsAdapter instanceof SuggestionsAdapter) { + mSuggestionsAdapter.changeCursor(null); + } + } + }; + + // For voice searching + private final Intent mVoiceWebSearchIntent; + private final Intent mVoiceAppSearchIntent; + + // A weak map of drawables we've gotten from other packages, so we don't load them + // more than once. + private final WeakHashMap mOutsideDrawablesCache = + new WeakHashMap(); + + /** + * Callbacks for changes to the query text. + */ + public interface OnQueryTextListener { + + /** + * Called when the user submits the query. This could be due to a key press on the + * keyboard or due to pressing a submit button. + * The listener can override the standard behavior by returning true + * to indicate that it has handled the submit request. Otherwise return false to + * let the SearchView handle the submission by launching any associated intent. + * + * @param query the query text that is to be submitted + * + * @return true if the query has been handled by the listener, false to let the + * SearchView perform the default action. + */ + boolean onQueryTextSubmit(String query); + + /** + * Called when the query text is changed by the user. + * + * @param newText the new content of the query text field. + * + * @return false if the SearchView should perform the default action of showing any + * suggestions if available, true if the action was handled by the listener. + */ + boolean onQueryTextChange(String newText); + } + + public interface OnCloseListener { + + /** + * The user is attempting to close the SearchView. + * + * @return true if the listener wants to override the default behavior of clearing the + * text field and dismissing it, false otherwise. + */ + boolean onClose(); + } + + /** + * Callback interface for selection events on suggestions. These callbacks + * are only relevant when a SearchableInfo has been specified by {@link #setSearchableInfo}. + */ + public interface OnSuggestionListener { + + /** + * Called when a suggestion was selected by navigating to it. + * @param position the absolute position in the list of suggestions. + * + * @return true if the listener handles the event and wants to override the default + * behavior of possibly rewriting the query based on the selected item, false otherwise. + */ + boolean onSuggestionSelect(int position); + + /** + * Called when a suggestion was clicked. + * @param position the absolute position of the clicked item in the list of suggestions. + * + * @return true if the listener handles the event and wants to override the default + * behavior of launching any intent or submitting a search query specified on that item. + * Return false otherwise. + */ + boolean onSuggestionClick(int position); + } + + public SearchView(Context context) { + this(context, null); + } + + public SearchView(Context context, AttributeSet attrs) { + super(context, attrs); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { + throw new IllegalStateException("SearchView is API 8+ only."); + } + + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflater.inflate(R.layout.abs__search_view, this, true); + + mSearchButton = findViewById(R.id.abs__search_button); + mQueryTextView = (SearchAutoComplete) findViewById(R.id.abs__search_src_text); + mQueryTextView.setSearchView(this); + + mSearchEditFrame = findViewById(R.id.abs__search_edit_frame); + mSearchPlate = findViewById(R.id.abs__search_plate); + mSubmitArea = findViewById(R.id.abs__submit_area); + mSubmitButton = findViewById(R.id.abs__search_go_btn); + mCloseButton = (ImageView) findViewById(R.id.abs__search_close_btn); + mVoiceButton = findViewById(R.id.abs__search_voice_btn); + mSearchHintIcon = (ImageView) findViewById(R.id.abs__search_mag_icon); + + mSearchButton.setOnClickListener(mOnClickListener); + mCloseButton.setOnClickListener(mOnClickListener); + mSubmitButton.setOnClickListener(mOnClickListener); + mVoiceButton.setOnClickListener(mOnClickListener); + mQueryTextView.setOnClickListener(mOnClickListener); + + mQueryTextView.addTextChangedListener(mTextWatcher); + mQueryTextView.setOnEditorActionListener(mOnEditorActionListener); + mQueryTextView.setOnItemClickListener(mOnItemClickListener); + mQueryTextView.setOnItemSelectedListener(mOnItemSelectedListener); + mQueryTextView.setOnKeyListener(mTextKeyListener); + // Inform any listener of focus changes + mQueryTextView.setOnFocusChangeListener(new OnFocusChangeListener() { + + public void onFocusChange(View v, boolean hasFocus) { + if (mOnQueryTextFocusChangeListener != null) { + mOnQueryTextFocusChangeListener.onFocusChange(SearchView.this, hasFocus); + } + } + }); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockSearchView, 0, 0); + setIconifiedByDefault(a.getBoolean(R.styleable.SherlockSearchView_iconifiedByDefault, true)); + int maxWidth = a.getDimensionPixelSize(R.styleable.SherlockSearchView_android_maxWidth, -1); + if (maxWidth != -1) { + setMaxWidth(maxWidth); + } + CharSequence queryHint = a.getText(R.styleable.SherlockSearchView_queryHint); + if (!TextUtils.isEmpty(queryHint)) { + setQueryHint(queryHint); + } + int imeOptions = a.getInt(R.styleable.SherlockSearchView_android_imeOptions, -1); + if (imeOptions != -1) { + setImeOptions(imeOptions); + } + int inputType = a.getInt(R.styleable.SherlockSearchView_android_inputType, -1); + if (inputType != -1) { + setInputType(inputType); + } + + a.recycle(); + + boolean focusable = true; + + a = context.obtainStyledAttributes(attrs, R.styleable.SherlockView, 0, 0); + focusable = a.getBoolean(R.styleable.SherlockView_android_focusable, focusable); + a.recycle(); + setFocusable(focusable); + + // Save voice intent for later queries/launching + mVoiceWebSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH); + mVoiceWebSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mVoiceWebSearchIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, + RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); + + mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); + mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + mDropDownAnchor = findViewById(mQueryTextView.getDropDownAnchor()); + if (mDropDownAnchor != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + mDropDownAnchor.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) { + adjustDropDownSizeAndPosition(); + } + }); + } else { + mDropDownAnchor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override public void onGlobalLayout() { + adjustDropDownSizeAndPosition(); + } + }); + } + } + + updateViewsVisibility(mIconifiedByDefault); + updateQueryHint(); + } + + /** + * Sets the SearchableInfo for this SearchView. Properties in the SearchableInfo are used + * to display labels, hints, suggestions, create intents for launching search results screens + * and controlling other affordances such as a voice button. + * + * @param searchable a SearchableInfo can be retrieved from the SearchManager, for a specific + * activity or a global search provider. + */ + public void setSearchableInfo(SearchableInfo searchable) { + mSearchable = searchable; + if (mSearchable != null) { + updateSearchAutoComplete(); + updateQueryHint(); + } + // Cache the voice search capability + mVoiceButtonEnabled = hasVoiceSearch(); + + if (mVoiceButtonEnabled) { + // Disable the microphone on the keyboard, as a mic is displayed near the text box + // TODO: use imeOptions to disable voice input when the new API will be available + mQueryTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE); + } + updateViewsVisibility(isIconified()); + } + + /** + * Sets the APP_DATA for legacy SearchDialog use. + * @param appSearchData bundle provided by the app when launching the search dialog + * @hide + */ + public void setAppSearchData(Bundle appSearchData) { + mAppSearchData = appSearchData; + } + + /** + * Sets the IME options on the query text field. + * + * @see TextView#setImeOptions(int) + * @param imeOptions the options to set on the query text field + * + * @attr ref android.R.styleable#SearchView_imeOptions + */ + public void setImeOptions(int imeOptions) { + mQueryTextView.setImeOptions(imeOptions); + } + + /** + * Returns the IME options set on the query text field. + * @return the ime options + * @see TextView#setImeOptions(int) + * + * @attr ref android.R.styleable#SearchView_imeOptions + */ + public int getImeOptions() { + return mQueryTextView.getImeOptions(); + } + + /** + * Sets the input type on the query text field. + * + * @see TextView#setInputType(int) + * @param inputType the input type to set on the query text field + * + * @attr ref android.R.styleable#SearchView_inputType + */ + public void setInputType(int inputType) { + mQueryTextView.setInputType(inputType); + } + + /** + * Returns the input type set on the query text field. + * @return the input type + * + * @attr ref android.R.styleable#SearchView_inputType + */ + public int getInputType() { + return mQueryTextView.getInputType(); + } + + /** @hide */ + @Override + public boolean requestFocus(int direction, Rect previouslyFocusedRect) { + // Don't accept focus if in the middle of clearing focus + if (mClearingFocus) return false; + // Check if SearchView is focusable. + if (!isFocusable()) return false; + // If it is not iconified, then give the focus to the text field + if (!isIconified()) { + boolean result = mQueryTextView.requestFocus(direction, previouslyFocusedRect); + if (result) { + updateViewsVisibility(false); + } + return result; + } else { + return super.requestFocus(direction, previouslyFocusedRect); + } + } + + /** @hide */ + @Override + public void clearFocus() { + mClearingFocus = true; + setImeVisibility(false); + super.clearFocus(); + mQueryTextView.clearFocus(); + mClearingFocus = false; + } + + /** + * Sets a listener for user actions within the SearchView. + * + * @param listener the listener object that receives callbacks when the user performs + * actions in the SearchView such as clicking on buttons or typing a query. + */ + public void setOnQueryTextListener(OnQueryTextListener listener) { + mOnQueryChangeListener = listener; + } + + /** + * Sets a listener to inform when the user closes the SearchView. + * + * @param listener the listener to call when the user closes the SearchView. + */ + public void setOnCloseListener(OnCloseListener listener) { + mOnCloseListener = listener; + } + + /** + * Sets a listener to inform when the focus of the query text field changes. + * + * @param listener the listener to inform of focus changes. + */ + public void setOnQueryTextFocusChangeListener(OnFocusChangeListener listener) { + mOnQueryTextFocusChangeListener = listener; + } + + /** + * Sets a listener to inform when a suggestion is focused or clicked. + * + * @param listener the listener to inform of suggestion selection events. + */ + public void setOnSuggestionListener(OnSuggestionListener listener) { + mOnSuggestionListener = listener; + } + + /** + * Sets a listener to inform when the search button is pressed. This is only + * relevant when the text field is not visible by default. Calling {@link #setIconified + * setIconified(false)} can also cause this listener to be informed. + * + * @param listener the listener to inform when the search button is clicked or + * the text field is programmatically de-iconified. + */ + public void setOnSearchClickListener(OnClickListener listener) { + mOnSearchClickListener = listener; + } + + /** + * Returns the query string currently in the text field. + * + * @return the query string + */ + public CharSequence getQuery() { + return mQueryTextView.getText(); + } + + /** + * Sets a query string in the text field and optionally submits the query as well. + * + * @param query the query string. This replaces any query text already present in the + * text field. + * @param submit whether to submit the query right now or only update the contents of + * text field. + */ + public void setQuery(CharSequence query, boolean submit) { + mQueryTextView.setText(query); + if (query != null) { + mQueryTextView.setSelection(mQueryTextView.length()); + mUserQuery = query; + } + + // If the query is not empty and submit is requested, submit the query + if (submit && !TextUtils.isEmpty(query)) { + onSubmitQuery(); + } + } + + /** + * Sets the hint text to display in the query text field. This overrides any hint specified + * in the SearchableInfo. + * + * @param hint the hint text to display + * + * @attr ref android.R.styleable#SearchView_queryHint + */ + public void setQueryHint(CharSequence hint) { + mQueryHint = hint; + updateQueryHint(); + } + + /** + * Gets the hint text to display in the query text field. + * @return the query hint text, if specified, null otherwise. + * + * @attr ref android.R.styleable#SearchView_queryHint + */ + public CharSequence getQueryHint() { + if (mQueryHint != null) { + return mQueryHint; + } else if (mSearchable != null) { + CharSequence hint = null; + int hintId = mSearchable.getHintId(); + if (hintId != 0) { + hint = getContext().getString(hintId); + } + return hint; + } + return null; + } + + /** + * Sets the default or resting state of the search field. If true, a single search icon is + * shown by default and expands to show the text field and other buttons when pressed. Also, + * if the default state is iconified, then it collapses to that state when the close button + * is pressed. Changes to this property will take effect immediately. + * + *

The default value is true.

+ * + * @param iconified whether the search field should be iconified by default + * + * @attr ref android.R.styleable#SearchView_iconifiedByDefault + */ + public void setIconifiedByDefault(boolean iconified) { + if (mIconifiedByDefault == iconified) return; + mIconifiedByDefault = iconified; + updateViewsVisibility(iconified); + updateQueryHint(); + } + + /** + * Returns the default iconified state of the search field. + * @return + * + * @attr ref android.R.styleable#SearchView_iconifiedByDefault + */ + public boolean isIconfiedByDefault() { + return mIconifiedByDefault; + } + + /** + * Iconifies or expands the SearchView. Any query text is cleared when iconified. This is + * a temporary state and does not override the default iconified state set by + * {@link #setIconifiedByDefault(boolean)}. If the default state is iconified, then + * a false here will only be valid until the user closes the field. And if the default + * state is expanded, then a true here will only clear the text field and not close it. + * + * @param iconify a true value will collapse the SearchView to an icon, while a false will + * expand it. + */ + public void setIconified(boolean iconify) { + if (iconify) { + onCloseClicked(); + } else { + onSearchClicked(); + } + } + + /** + * Returns the current iconified state of the SearchView. + * + * @return true if the SearchView is currently iconified, false if the search field is + * fully visible. + */ + public boolean isIconified() { + return mIconified; + } + + /** + * Enables showing a submit button when the query is non-empty. In cases where the SearchView + * is being used to filter the contents of the current activity and doesn't launch a separate + * results activity, then the submit button should be disabled. + * + * @param enabled true to show a submit button for submitting queries, false if a submit + * button is not required. + */ + public void setSubmitButtonEnabled(boolean enabled) { + mSubmitButtonEnabled = enabled; + updateViewsVisibility(isIconified()); + } + + /** + * Returns whether the submit button is enabled when necessary or never displayed. + * + * @return whether the submit button is enabled automatically when necessary + */ + public boolean isSubmitButtonEnabled() { + return mSubmitButtonEnabled; + } + + /** + * Specifies if a query refinement button should be displayed alongside each suggestion + * or if it should depend on the flags set in the individual items retrieved from the + * suggestions provider. Clicking on the query refinement button will replace the text + * in the query text field with the text from the suggestion. This flag only takes effect + * if a SearchableInfo has been specified with {@link #setSearchableInfo(SearchableInfo)} + * and not when using a custom adapter. + * + * @param enable true if all items should have a query refinement button, false if only + * those items that have a query refinement flag set should have the button. + * + * @see SearchManager#SUGGEST_COLUMN_FLAGS + * @see SearchManager#FLAG_QUERY_REFINEMENT + */ + public void setQueryRefinementEnabled(boolean enable) { + mQueryRefinement = enable; + if (mSuggestionsAdapter instanceof SuggestionsAdapter) { + ((SuggestionsAdapter) mSuggestionsAdapter).setQueryRefinement( + enable ? SuggestionsAdapter.REFINE_ALL : SuggestionsAdapter.REFINE_BY_ENTRY); + } + } + + /** + * Returns whether query refinement is enabled for all items or only specific ones. + * @return true if enabled for all items, false otherwise. + */ + public boolean isQueryRefinementEnabled() { + return mQueryRefinement; + } + + /** + * You can set a custom adapter if you wish. Otherwise the default adapter is used to + * display the suggestions from the suggestions provider associated with the SearchableInfo. + * + * @see #setSearchableInfo(SearchableInfo) + */ + public void setSuggestionsAdapter(CursorAdapter adapter) { + mSuggestionsAdapter = adapter; + + mQueryTextView.setAdapter(mSuggestionsAdapter); + } + + /** + * Returns the adapter used for suggestions, if any. + * @return the suggestions adapter + */ + public CursorAdapter getSuggestionsAdapter() { + return mSuggestionsAdapter; + } + + /** + * Makes the view at most this many pixels wide + * + * @attr ref android.R.styleable#SearchView_maxWidth + */ + public void setMaxWidth(int maxpixels) { + mMaxWidth = maxpixels; + + requestLayout(); + } + + /** + * Gets the specified maximum width in pixels, if set. Returns zero if + * no maximum width was specified. + * @return the maximum width of the view + * + * @attr ref android.R.styleable#SearchView_maxWidth + */ + public int getMaxWidth() { + return mMaxWidth; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // Let the standard measurements take effect in iconified state. + if (isIconified()) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + return; + } + + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int width = MeasureSpec.getSize(widthMeasureSpec); + + switch (widthMode) { + case MeasureSpec.AT_MOST: + // If there is an upper limit, don't exceed maximum width (explicit or implicit) + if (mMaxWidth > 0) { + width = Math.min(mMaxWidth, width); + } else { + width = Math.min(getPreferredWidth(), width); + } + break; + case MeasureSpec.EXACTLY: + // If an exact width is specified, still don't exceed any specified maximum width + if (mMaxWidth > 0) { + width = Math.min(mMaxWidth, width); + } + break; + case MeasureSpec.UNSPECIFIED: + // Use maximum width, if specified, else preferred width + width = mMaxWidth > 0 ? mMaxWidth : getPreferredWidth(); + break; + } + widthMode = MeasureSpec.EXACTLY; + super.onMeasure(MeasureSpec.makeMeasureSpec(width, widthMode), heightMeasureSpec); + } + + private int getPreferredWidth() { + return getContext().getResources() + .getDimensionPixelSize(R.dimen.abs__search_view_preferred_width); + } + + private void updateViewsVisibility(final boolean collapsed) { + mIconified = collapsed; + // Visibility of views that are visible when collapsed + final int visCollapsed = collapsed ? VISIBLE : GONE; + // Is there text in the query + final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText()); + + mSearchButton.setVisibility(visCollapsed); + updateSubmitButton(hasText); + mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE); + mSearchHintIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE); + updateCloseButton(); + updateVoiceButton(!hasText); + updateSubmitArea(); + } + + private boolean hasVoiceSearch() { + if (mSearchable != null && mSearchable.getVoiceSearchEnabled()) { + Intent testIntent = null; + if (mSearchable.getVoiceSearchLaunchWebSearch()) { + testIntent = mVoiceWebSearchIntent; + } else if (mSearchable.getVoiceSearchLaunchRecognizer()) { + testIntent = mVoiceAppSearchIntent; + } + if (testIntent != null) { + ResolveInfo ri = getContext().getPackageManager().resolveActivity(testIntent, + PackageManager.MATCH_DEFAULT_ONLY); + return ri != null; + } + } + return false; + } + + private boolean isSubmitAreaEnabled() { + return (mSubmitButtonEnabled || mVoiceButtonEnabled) && !isIconified(); + } + + private void updateSubmitButton(boolean hasText) { + int visibility = GONE; + if (mSubmitButtonEnabled && isSubmitAreaEnabled() && hasFocus() + && (hasText || !mVoiceButtonEnabled)) { + visibility = VISIBLE; + } + mSubmitButton.setVisibility(visibility); + } + + private void updateSubmitArea() { + int visibility = GONE; + if (isSubmitAreaEnabled() + && (mSubmitButton.getVisibility() == VISIBLE + || mVoiceButton.getVisibility() == VISIBLE)) { + visibility = VISIBLE; + } + mSubmitArea.setVisibility(visibility); + } + + private void updateCloseButton() { + final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText()); + // Should we show the close button? It is not shown if there's no focus, + // field is not iconified by default and there is no text in it. + final boolean showClose = hasText || (mIconifiedByDefault && !mExpandedInActionView); + mCloseButton.setVisibility(showClose ? VISIBLE : GONE); + mCloseButton.getDrawable().setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET); + } + + private void postUpdateFocusedState() { + post(mUpdateDrawableStateRunnable); + } + + private void updateFocusedState() { + boolean focused = mQueryTextView.hasFocus(); + mSearchPlate.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET); + mSubmitArea.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET); + invalidate(); + } + + @Override + protected void onDetachedFromWindow() { + removeCallbacks(mUpdateDrawableStateRunnable); + post(mReleaseCursorRunnable); + super.onDetachedFromWindow(); + } + + private void setImeVisibility(final boolean visible) { + if (visible) { + post(mShowImeRunnable); + } else { + removeCallbacks(mShowImeRunnable); + InputMethodManager imm = (InputMethodManager) + getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + + if (imm != null) { + imm.hideSoftInputFromWindow(getWindowToken(), 0); + } + } + } + + /** + * Called by the SuggestionsAdapter + * @hide + */ + /* package */void onQueryRefine(CharSequence queryText) { + setQuery(queryText); + } + + private final OnClickListener mOnClickListener = new OnClickListener() { + + public void onClick(View v) { + if (v == mSearchButton) { + onSearchClicked(); + } else if (v == mCloseButton) { + onCloseClicked(); + } else if (v == mSubmitButton) { + onSubmitQuery(); + } else if (v == mVoiceButton) { + onVoiceClicked(); + } else if (v == mQueryTextView) { + forceSuggestionQuery(); + } + } + }; + + /** + * Handles the key down event for dealing with action keys. + * + * @param keyCode This is the keycode of the typed key, and is the same value as + * found in the KeyEvent parameter. + * @param event The complete event record for the typed key + * + * @return true if the event was handled here, or false if not. + */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mSearchable == null) { + return false; + } + + // if it's an action specified by the searchable activity, launch the + // entered query with the action key + // TODO SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode); + // TODO if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) { + // TODO launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mQueryTextView.getText() + // TODO .toString()); + // TODO return true; + // TODO } + + return super.onKeyDown(keyCode, event); + } + + /** + * React to the user typing "enter" or other hardwired keys while typing in + * the search box. This handles these special keys while the edit box has + * focus. + */ + View.OnKeyListener mTextKeyListener = new View.OnKeyListener() { + public boolean onKey(View v, int keyCode, KeyEvent event) { + // guard against possible race conditions + if (mSearchable == null) { + return false; + } + + if (DBG) { + Log.d(LOG_TAG, "mTextListener.onKey(" + keyCode + "," + event + "), selection: " + + mQueryTextView.getListSelection()); + } + + // If a suggestion is selected, handle enter, search key, and action keys + // as presses on the selected suggestion + if (mQueryTextView.isPopupShowing() + && mQueryTextView.getListSelection() != ListView.INVALID_POSITION) { + return onSuggestionsKey(v, keyCode, event); + } + + // If there is text in the query box, handle enter, and action keys + // The search key is handled by the dialog's onKeyDown(). + if (!mQueryTextView.isEmpty() && KeyEventCompat.hasNoModifiers(event)) { + if (event.getAction() == KeyEvent.ACTION_UP) { + if (keyCode == KeyEvent.KEYCODE_ENTER) { + v.cancelLongPress(); + + // Launch as a regular search. + launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, mQueryTextView.getText() + .toString()); + return true; + } + } + if (event.getAction() == KeyEvent.ACTION_DOWN) { + // TODO SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode); + // TODO if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) { + // TODO launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mQueryTextView + // TODO .getText().toString()); + // TODO return true; + // TODO } + } + } + return false; + } + }; + + /** + * React to the user typing while in the suggestions list. First, check for + * action keys. If not handled, try refocusing regular characters into the + * EditText. + */ + private boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) { + // guard against possible race conditions (late arrival after dismiss) + if (mSearchable == null) { + return false; + } + if (mSuggestionsAdapter == null) { + return false; + } + if (event.getAction() == KeyEvent.ACTION_DOWN && KeyEventCompat.hasNoModifiers(event)) { + // First, check for enter or search (both of which we'll treat as a + // "click") + if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH + || keyCode == KeyEvent.KEYCODE_TAB) { + int position = mQueryTextView.getListSelection(); + return onItemClicked(position, KeyEvent.KEYCODE_UNKNOWN, null); + } + + // Next, check for left/right moves, which we use to "return" the + // user to the edit view + if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { + // give "focus" to text editor, with cursor at the beginning if + // left key, at end if right key + // TODO: Reverse left/right for right-to-left languages, e.g. + // Arabic + int selPoint = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ? 0 : mQueryTextView + .length(); + mQueryTextView.setSelection(selPoint); + mQueryTextView.setListSelection(0); + mQueryTextView.clearListSelection(); + ensureImeVisible(mQueryTextView, true); + + return true; + } + + // Next, check for an "up and out" move + if (keyCode == KeyEvent.KEYCODE_DPAD_UP && 0 == mQueryTextView.getListSelection()) { + // TODO: restoreUserQuery(); + // let ACTV complete the move + return false; + } + + // Next, check for an "action key" + // TODO SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode); + // TODO if ((actionKey != null) + // TODO && ((actionKey.getSuggestActionMsg() != null) || (actionKey + // TODO .getSuggestActionMsgColumn() != null))) { + // TODO // launch suggestion using action key column + // TODO int position = mQueryTextView.getListSelection(); + // TODO if (position != ListView.INVALID_POSITION) { + // TODO Cursor c = mSuggestionsAdapter.getCursor(); + // TODO if (c.moveToPosition(position)) { + // TODO final String actionMsg = getActionKeyMessage(c, actionKey); + // TODO if (actionMsg != null && (actionMsg.length() > 0)) { + // TODO return onItemClicked(position, keyCode, actionMsg); + // TODO } + // TODO } + // TODO } + // TODO } + } + return false; + } + + /** + * For a given suggestion and a given cursor row, get the action message. If + * not provided by the specific row/column, also check for a single + * definition (for the action key). + * + * @param c The cursor providing suggestions + * @param actionKey The actionkey record being examined + * + * @return Returns a string, or null if no action key message for this + * suggestion + */ + // TODO private static String getActionKeyMessage(Cursor c, SearchableInfo.ActionKeyInfo actionKey) { + // TODO String result = null; + // TODO // check first in the cursor data, for a suggestion-specific message + // TODO final String column = actionKey.getSuggestActionMsgColumn(); + // TODO if (column != null) { + // TODO result = SuggestionsAdapter.getColumnString(c, column); + // TODO } + // TODO // If the cursor didn't give us a message, see if there's a single + // TODO // message defined + // TODO // for the actionkey (for all suggestions) + // TODO if (result == null) { + // TODO result = actionKey.getSuggestActionMsg(); + // TODO } + // TODO return result; + // TODO } + + private int getSearchIconId() { + TypedValue outValue = new TypedValue(); + getContext().getTheme().resolveAttribute(R.attr.searchViewSearchIcon, + outValue, true); + return outValue.resourceId; + } + + private CharSequence getDecoratedHint(CharSequence hintText) { + // If the field is always expanded, then don't add the search icon to the hint + if (!mIconifiedByDefault) return hintText; + + SpannableStringBuilder ssb = new SpannableStringBuilder(" "); // for the icon + ssb.append(hintText); + Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId()); + int textSize = (int) (mQueryTextView.getTextSize() * 1.25); + searchIcon.setBounds(0, 0, textSize, textSize); + ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return ssb; + } + + private void updateQueryHint() { + if (mQueryHint != null) { + mQueryTextView.setHint(getDecoratedHint(mQueryHint)); + } else if (mSearchable != null) { + CharSequence hint = null; + int hintId = mSearchable.getHintId(); + if (hintId != 0) { + hint = getContext().getString(hintId); + } + if (hint != null) { + mQueryTextView.setHint(getDecoratedHint(hint)); + } + } else { + mQueryTextView.setHint(getDecoratedHint("")); + } + } + + /** + * Updates the auto-complete text view. + */ + private void updateSearchAutoComplete() { + // TODO mQueryTextView.setDropDownAnimationStyle(0); // no animation + mQueryTextView.setThreshold(mSearchable.getSuggestThreshold()); + mQueryTextView.setImeOptions(mSearchable.getImeOptions()); + int inputType = mSearchable.getInputType(); + // We only touch this if the input type is set up for text (which it almost certainly + // should be, in the case of search!) + if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) { + // The existence of a suggestions authority is the proxy for "suggestions + // are available here" + inputType &= ~InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE; + if (mSearchable.getSuggestAuthority() != null) { + inputType |= InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE; + // TYPE_TEXT_FLAG_AUTO_COMPLETE means that the text editor is performing + // auto-completion based on its own semantics, which it will present to the user + // as they type. This generally means that the input method should not show its + // own candidates, and the spell checker should not be in action. The text editor + // supplies its candidates by calling InputMethodManager.displayCompletions(), + // which in turn will call InputMethodSession.displayCompletions(). + inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; + } + } + mQueryTextView.setInputType(inputType); + if (mSuggestionsAdapter != null) { + mSuggestionsAdapter.changeCursor(null); + } + // attach the suggestions adapter, if suggestions are available + // The existence of a suggestions authority is the proxy for "suggestions available here" + if (mSearchable.getSuggestAuthority() != null) { + mSuggestionsAdapter = new SuggestionsAdapter(getContext(), + this, mSearchable, mOutsideDrawablesCache); + mQueryTextView.setAdapter(mSuggestionsAdapter); + ((SuggestionsAdapter) mSuggestionsAdapter).setQueryRefinement( + mQueryRefinement ? SuggestionsAdapter.REFINE_ALL + : SuggestionsAdapter.REFINE_BY_ENTRY); + } + } + + /** + * Update the visibility of the voice button. There are actually two voice search modes, + * either of which will activate the button. + * @param empty whether the search query text field is empty. If it is, then the other + * criteria apply to make the voice button visible. + */ + private void updateVoiceButton(boolean empty) { + int visibility = GONE; + if (mVoiceButtonEnabled && !isIconified() && empty) { + visibility = VISIBLE; + mSubmitButton.setVisibility(GONE); + } + mVoiceButton.setVisibility(visibility); + } + + private final OnEditorActionListener mOnEditorActionListener = new OnEditorActionListener() { + + /** + * Called when the input method default action key is pressed. + */ + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + onSubmitQuery(); + return true; + } + }; + + private void onTextChanged(CharSequence newText) { + CharSequence text = mQueryTextView.getText(); + mUserQuery = text; + boolean hasText = !TextUtils.isEmpty(text); + updateSubmitButton(hasText); + updateVoiceButton(!hasText); + updateCloseButton(); + updateSubmitArea(); + if (mOnQueryChangeListener != null && !TextUtils.equals(newText, mOldQueryText)) { + mOnQueryChangeListener.onQueryTextChange(newText.toString()); + } + mOldQueryText = newText.toString(); + } + + private void onSubmitQuery() { + CharSequence query = mQueryTextView.getText(); + if (query != null && TextUtils.getTrimmedLength(query) > 0) { + if (mOnQueryChangeListener == null + || !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) { + if (mSearchable != null) { + launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString()); + setImeVisibility(false); + } + dismissSuggestions(); + } + } + } + + private void dismissSuggestions() { + mQueryTextView.dismissDropDown(); + } + + private void onCloseClicked() { + CharSequence text = mQueryTextView.getText(); + if (TextUtils.isEmpty(text)) { + if (mIconifiedByDefault) { + // If the app doesn't override the close behavior + if (mOnCloseListener == null || !mOnCloseListener.onClose()) { + // hide the keyboard and remove focus + clearFocus(); + // collapse the search field + updateViewsVisibility(true); + } + } + } else { + mQueryTextView.setText(""); + mQueryTextView.requestFocus(); + setImeVisibility(true); + } + + } + + private void onSearchClicked() { + updateViewsVisibility(false); + mQueryTextView.requestFocus(); + setImeVisibility(true); + if (mOnSearchClickListener != null) { + mOnSearchClickListener.onClick(this); + } + } + + private void onVoiceClicked() { + // guard against possible race conditions + if (mSearchable == null) { + return; + } + SearchableInfo searchable = mSearchable; + try { + if (searchable.getVoiceSearchLaunchWebSearch()) { + Intent webSearchIntent = createVoiceWebSearchIntent(mVoiceWebSearchIntent, + searchable); + getContext().startActivity(webSearchIntent); + } else if (searchable.getVoiceSearchLaunchRecognizer()) { + Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent, + searchable); + getContext().startActivity(appSearchIntent); + } + } catch (ActivityNotFoundException e) { + // Should not happen, since we check the availability of + // voice search before showing the button. But just in case... + Log.w(LOG_TAG, "Could not find voice search activity"); + } + } + + void onTextFocusChanged() { + updateViewsVisibility(isIconified()); + // Delayed update to make sure that the focus has settled down and window focus changes + // don't affect it. A synchronous update was not working. + postUpdateFocusedState(); + if (mQueryTextView.hasFocus()) { + forceSuggestionQuery(); + } + } + + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + + postUpdateFocusedState(); + } + + /** + * {@inheritDoc} + */ + @Override + public void onActionViewCollapsed() { + clearFocus(); + updateViewsVisibility(true); + mQueryTextView.setImeOptions(mCollapsedImeOptions); + mExpandedInActionView = false; + } + + /** + * {@inheritDoc} + */ + @Override + public void onActionViewExpanded() { + if (mExpandedInActionView) return; + + mExpandedInActionView = true; + mCollapsedImeOptions = mQueryTextView.getImeOptions(); + mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN); + mQueryTextView.setText(""); + setIconified(false); + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(SearchView.class.getName()); + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(SearchView.class.getName()); + } + + private void adjustDropDownSizeAndPosition() { + if (mDropDownAnchor.getWidth() > 1) { + Resources res = getContext().getResources(); + int anchorPadding = mSearchPlate.getPaddingLeft(); + Rect dropDownPadding = new Rect(); + int iconOffset = mIconifiedByDefault + ? res.getDimensionPixelSize(R.dimen.abs__dropdownitem_icon_width) + + res.getDimensionPixelSize(R.dimen.abs__dropdownitem_text_padding_left) + : 0; + mQueryTextView.getDropDownBackground().getPadding(dropDownPadding); + mQueryTextView.setDropDownHorizontalOffset(-(dropDownPadding.left + iconOffset) + + anchorPadding); + mQueryTextView.setDropDownWidth(mDropDownAnchor.getWidth() + dropDownPadding.left + + dropDownPadding.right + iconOffset - (anchorPadding)); + } + } + + private boolean onItemClicked(int position, int actionKey, String actionMsg) { + if (mOnSuggestionListener == null + || !mOnSuggestionListener.onSuggestionClick(position)) { + launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null); + setImeVisibility(false); + dismissSuggestions(); + return true; + } + return false; + } + + private boolean onItemSelected(int position) { + if (mOnSuggestionListener == null + || !mOnSuggestionListener.onSuggestionSelect(position)) { + rewriteQueryFromSuggestion(position); + return true; + } + return false; + } + + private final OnItemClickListener mOnItemClickListener = new OnItemClickListener() { + + /** + * Implements OnItemClickListener + */ + public void onItemClick(AdapterView parent, View view, int position, long id) { + if (DBG) Log.d(LOG_TAG, "onItemClick() position " + position); + onItemClicked(position, KeyEvent.KEYCODE_UNKNOWN, null); + } + }; + + private final OnItemSelectedListener mOnItemSelectedListener = new OnItemSelectedListener() { + + /** + * Implements OnItemSelectedListener + */ + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (DBG) Log.d(LOG_TAG, "onItemSelected() position " + position); + SearchView.this.onItemSelected(position); + } + + /** + * Implements OnItemSelectedListener + */ + public void onNothingSelected(AdapterView parent) { + if (DBG) + Log.d(LOG_TAG, "onNothingSelected()"); + } + }; + + /** + * Query rewriting. + */ + private void rewriteQueryFromSuggestion(int position) { + CharSequence oldQuery = mQueryTextView.getText(); + Cursor c = mSuggestionsAdapter.getCursor(); + if (c == null) { + return; + } + if (c.moveToPosition(position)) { + // Get the new query from the suggestion. + CharSequence newQuery = mSuggestionsAdapter.convertToString(c); + if (newQuery != null) { + // The suggestion rewrites the query. + // Update the text field, without getting new suggestions. + setQuery(newQuery); + } else { + // The suggestion does not rewrite the query, restore the user's query. + setQuery(oldQuery); + } + } else { + // We got a bad position, restore the user's query. + setQuery(oldQuery); + } + } + + /** + * Launches an intent based on a suggestion. + * + * @param position The index of the suggestion to create the intent from. + * @param actionKey The key code of the action key that was pressed, + * or {@link KeyEvent#KEYCODE_UNKNOWN} if none. + * @param actionMsg The message for the action key that was pressed, + * or null if none. + * @return true if a successful launch, false if could not (e.g. bad position). + */ + private boolean launchSuggestion(int position, int actionKey, String actionMsg) { + Cursor c = mSuggestionsAdapter.getCursor(); + if ((c != null) && c.moveToPosition(position)) { + + Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg); + + // launch the intent + launchIntent(intent); + + return true; + } + return false; + } + + /** + * Launches an intent, including any special intent handling. + */ + private void launchIntent(Intent intent) { + if (intent == null) { + return; + } + try { + // If the intent was created from a suggestion, it will always have an explicit + // component here. + getContext().startActivity(intent); + } catch (RuntimeException ex) { + Log.e(LOG_TAG, "Failed launch activity: " + intent, ex); + } + } + + /** + * Sets the text in the query box, without updating the suggestions. + */ + private void setQuery(CharSequence query) { + setText(mQueryTextView, query, true); + // Move the cursor to the end + mQueryTextView.setSelection(TextUtils.isEmpty(query) ? 0 : query.length()); + } + + private void launchQuerySearch(int actionKey, String actionMsg, String query) { + String action = Intent.ACTION_SEARCH; + Intent intent = createIntent(action, null, null, query, actionKey, actionMsg); + getContext().startActivity(intent); + } + + /** + * Constructs an intent from the given information and the search dialog state. + * + * @param action Intent action. + * @param data Intent data, or null. + * @param extraData Data for {@link SearchManager#EXTRA_DATA_KEY} or null. + * @param query Intent query, or null. + * @param actionKey The key code of the action key that was pressed, + * or {@link KeyEvent#KEYCODE_UNKNOWN} if none. + * @param actionMsg The message for the action key that was pressed, + * or null if none. + * @return The intent. + */ + private Intent createIntent(String action, Uri data, String extraData, String query, + int actionKey, String actionMsg) { + // Now build the Intent + Intent intent = new Intent(action); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // We need CLEAR_TOP to avoid reusing an old task that has other activities + // on top of the one we want. We don't want to do this in in-app search though, + // as it can be destructive to the activity stack. + if (data != null) { + intent.setData(data); + } + intent.putExtra(SearchManager.USER_QUERY, mUserQuery); + if (query != null) { + intent.putExtra(SearchManager.QUERY, query); + } + if (extraData != null) { + intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData); + } + if (mAppSearchData != null) { + intent.putExtra(SearchManager.APP_DATA, mAppSearchData); + } + if (actionKey != KeyEvent.KEYCODE_UNKNOWN) { + intent.putExtra(SearchManager.ACTION_KEY, actionKey); + intent.putExtra(SearchManager.ACTION_MSG, actionMsg); + } + intent.setComponent(mSearchable.getSearchActivity()); + return intent; + } + + /** + * Create and return an Intent that can launch the voice search activity for web search. + */ + private Intent createVoiceWebSearchIntent(Intent baseIntent, SearchableInfo searchable) { + Intent voiceIntent = new Intent(baseIntent); + ComponentName searchActivity = searchable.getSearchActivity(); + voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, searchActivity == null ? null + : searchActivity.flattenToShortString()); + return voiceIntent; + } + + /** + * Create and return an Intent that can launch the voice search activity, perform a specific + * voice transcription, and forward the results to the searchable activity. + * + * @param baseIntent The voice app search intent to start from + * @return A completely-configured intent ready to send to the voice search activity + */ + private Intent createVoiceAppSearchIntent(Intent baseIntent, SearchableInfo searchable) { + ComponentName searchActivity = searchable.getSearchActivity(); + + // create the necessary intent to set up a search-and-forward operation + // in the voice search system. We have to keep the bundle separate, + // because it becomes immutable once it enters the PendingIntent + Intent queryIntent = new Intent(Intent.ACTION_SEARCH); + queryIntent.setComponent(searchActivity); + PendingIntent pending = PendingIntent.getActivity(getContext(), 0, queryIntent, + PendingIntent.FLAG_ONE_SHOT); + + // Now set up the bundle that will be inserted into the pending intent + // when it's time to do the search. We always build it here (even if empty) + // because the voice search activity will always need to insert "QUERY" into + // it anyway. + Bundle queryExtras = new Bundle(); + + // Now build the intent to launch the voice search. Add all necessary + // extras to launch the voice recognizer, and then all the necessary extras + // to forward the results to the searchable activity + Intent voiceIntent = new Intent(baseIntent); + + // Add all of the configuration options supplied by the searchable's metadata + String languageModel = RecognizerIntent.LANGUAGE_MODEL_FREE_FORM; + String prompt = null; + String language = null; + int maxResults = 1; + + Resources resources = getResources(); + if (searchable.getVoiceLanguageModeId() != 0) { + languageModel = resources.getString(searchable.getVoiceLanguageModeId()); + } + if (searchable.getVoicePromptTextId() != 0) { + prompt = resources.getString(searchable.getVoicePromptTextId()); + } + if (searchable.getVoiceLanguageId() != 0) { + language = resources.getString(searchable.getVoiceLanguageId()); + } + if (searchable.getVoiceMaxResults() != 0) { + maxResults = searchable.getVoiceMaxResults(); + } + voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, languageModel); + voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt); + voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language); + voiceIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults); + voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, searchActivity == null ? null + : searchActivity.flattenToShortString()); + + // Add the values that configure forwarding the results + voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, pending); + voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE, queryExtras); + + return voiceIntent; + } + + /** + * When a particular suggestion has been selected, perform the various lookups required + * to use the suggestion. This includes checking the cursor for suggestion-specific data, + * and/or falling back to the XML for defaults; It also creates REST style Uri data when + * the suggestion includes a data id. + * + * @param c The suggestions cursor, moved to the row of the user's selection + * @param actionKey The key code of the action key that was pressed, + * or {@link KeyEvent#KEYCODE_UNKNOWN} if none. + * @param actionMsg The message for the action key that was pressed, + * or null if none. + * @return An intent for the suggestion at the cursor's position. + */ + private Intent createIntentFromSuggestion(Cursor c, int actionKey, String actionMsg) { + try { + // use specific action if supplied, or default action if supplied, or fixed default + String action = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_ACTION); + + if (action == null) { + action = mSearchable.getSuggestIntentAction(); + } + if (action == null) { + action = Intent.ACTION_SEARCH; + } + + // use specific data if supplied, or default data if supplied + String data = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA); + if (data == null) { + data = mSearchable.getSuggestIntentData(); + } + // then, if an ID was provided, append it. + if (data != null) { + String id = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID); + if (id != null) { + data = data + "/" + Uri.encode(id); + } + } + Uri dataUri = (data == null) ? null : Uri.parse(data); + + String query = getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY); + String extraData = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA); + + return createIntent(action, dataUri, extraData, query, actionKey, actionMsg); + } catch (RuntimeException e ) { + int rowNum; + try { // be really paranoid now + rowNum = c.getPosition(); + } catch (RuntimeException e2 ) { + rowNum = -1; + } + Log.w(LOG_TAG, "Search suggestions cursor at row " + rowNum + + " returned exception.", e); + return null; + } + } + + private void forceSuggestionQuery() { + try { + Method before = SearchAutoComplete.class.getMethod("doBeforeTextChanged"); + Method after = SearchAutoComplete.class.getMethod("doAfterTextChanged"); + before.setAccessible(true); + after.setAccessible(true); + before.invoke(mQueryTextView); + after.invoke(mQueryTextView); + } catch (Exception e) { + // Oh well... + } + } + + static boolean isLandscapeMode(Context context) { + return context.getResources().getConfiguration().orientation + == Configuration.ORIENTATION_LANDSCAPE; + } + + /** + * Callback to watch the text field for empty/non-empty + */ + private TextWatcher mTextWatcher = new TextWatcher() { + + public void beforeTextChanged(CharSequence s, int start, int before, int after) { } + + public void onTextChanged(CharSequence s, int start, + int before, int after) { + SearchView.this.onTextChanged(s); + } + + public void afterTextChanged(Editable s) { + } + }; + + /** + * Local subclass for AutoCompleteTextView. + * @hide + */ + public static class SearchAutoComplete extends AutoCompleteTextView { + + private int mThreshold; + private SearchView mSearchView; + + public SearchAutoComplete(Context context) { + super(context); + mThreshold = getThreshold(); + } + + public SearchAutoComplete(Context context, AttributeSet attrs) { + super(context, attrs); + mThreshold = getThreshold(); + } + + public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mThreshold = getThreshold(); + } + + void setSearchView(SearchView searchView) { + mSearchView = searchView; + } + + @Override + public void setThreshold(int threshold) { + super.setThreshold(threshold); + mThreshold = threshold; + } + + /** + * Returns true if the text field is empty, or contains only whitespace. + */ + private boolean isEmpty() { + return TextUtils.getTrimmedLength(getText()) == 0; + } + + /** + * We override this method to avoid replacing the query box text when a + * suggestion is clicked. + */ + @Override + protected void replaceText(CharSequence text) { + } + + /** + * We override this method to avoid an extra onItemClick being called on + * the drop-down's OnItemClickListener by + * {@link AutoCompleteTextView#onKeyUp(int, KeyEvent)} when an item is + * clicked with the trackball. + */ + @Override + public void performCompletion() { + } + + /** + * We override this method to be sure and show the soft keyboard if + * appropriate when the TextView has focus. + */ + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + + if (hasWindowFocus && mSearchView.hasFocus() && getVisibility() == VISIBLE) { + InputMethodManager inputManager = (InputMethodManager) getContext() + .getSystemService(Context.INPUT_METHOD_SERVICE); + inputManager.showSoftInput(this, 0); + // If in landscape mode, then make sure that + // the ime is in front of the dropdown. + if (isLandscapeMode(getContext())) { + ensureImeVisible(this, true); + } + } + } + + @Override + protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + super.onFocusChanged(focused, direction, previouslyFocusedRect); + mSearchView.onTextFocusChanged(); + } + + /** + * We override this method so that we can allow a threshold of zero, + * which ACTV does not. + */ + @Override + public boolean enoughToFilter() { + return mThreshold <= 0 || super.enoughToFilter(); + } + + @Override + public boolean onKeyPreIme(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + // special case for the back key, we do not even try to send it + // to the drop down list but instead, consume it immediately + if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { + KeyEvent.DispatcherState state = getKeyDispatcherState(); + if (state != null) { + state.startTracking(event, this); + } + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + KeyEvent.DispatcherState state = getKeyDispatcherState(); + if (state != null) { + state.handleUpEvent(event); + } + if (event.isTracking() && !event.isCanceled()) { + mSearchView.clearFocus(); + mSearchView.setImeVisibility(false); + return true; + } + } + } + return super.onKeyPreIme(keyCode, event); + } + + } + + private static void ensureImeVisible(AutoCompleteTextView view, boolean visible) { + try { + Method method = AutoCompleteTextView.class.getMethod("ensureImeVisible", boolean.class); + method.setAccessible(true); + method.invoke(view, visible); + } catch (Exception e) { + //Oh well... + } + } + + private static void showSoftInputUnchecked(View view, InputMethodManager imm, int flags) { + try { + Method method = imm.getClass().getMethod("showSoftInputUnchecked", int.class, ResultReceiver.class); + method.setAccessible(true); + method.invoke(imm, flags, null); + } catch (Exception e) { + //Fallback to public API which hopefully does mostly the same thing + imm.showSoftInput(view, flags); + } + } + + private static void setText(AutoCompleteTextView view, CharSequence text, boolean filter) { + try { + Method method = AutoCompleteTextView.class.getMethod("setText", CharSequence.class, boolean.class); + method.setAccessible(true); + method.invoke(view, text, filter); + } catch (Exception e) { + //Fallback to public API which hopefully does mostly the same thing + view.setText(text); + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ShareActionProvider.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ShareActionProvider.java new file mode 100644 index 0000000000..71143c64cb --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/ShareActionProvider.java @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.widget; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.util.TypedValue; +import android.view.View; + +import com.actionbarsherlock.R; +import com.actionbarsherlock.view.ActionProvider; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.actionbarsherlock.view.MenuItem.OnMenuItemClickListener; +import com.actionbarsherlock.view.SubMenu; +import com.actionbarsherlock.widget.ActivityChooserModel.OnChooseActivityListener; + +/** + * This is a provider for a share action. It is responsible for creating views + * that enable data sharing and also to show a sub menu with sharing activities + * if the hosting item is placed on the overflow menu. + *

+ * Here is how to use the action provider with custom backing file in a {@link MenuItem}: + *

+ *

+ *

+ * 
+ *  // In Activity#onCreateOptionsMenu
+ *  public boolean onCreateOptionsMenu(Menu menu) {
+ *      // Get the menu item.
+ *      MenuItem menuItem = menu.findItem(R.id.my_menu_item);
+ *      // Get the provider and hold onto it to set/change the share intent.
+ *      mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
+ *      // Set history different from the default before getting the action
+ *      // view since a call to {@link MenuItem#getActionView() MenuItem.getActionView()} calls
+ *      // {@link ActionProvider#onCreateActionView()} which uses the backing file name. Omit this
+ *      // line if using the default share history file is desired.
+ *      mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
+ *      . . .
+ *  }
+ *
+ *  // Somewhere in the application.
+ *  public void doShare(Intent shareIntent) {
+ *      // When you want to share set the share intent.
+ *      mShareActionProvider.setShareIntent(shareIntent);
+ *  }
+ * 
+ * + *

+ *

+ * Note: While the sample snippet demonstrates how to use this provider + * in the context of a menu item, the use of the provider is not limited to menu items. + *

+ * + * @see ActionProvider + */ +public class ShareActionProvider extends ActionProvider { + + /** + * Listener for the event of selecting a share target. + */ + public interface OnShareTargetSelectedListener { + + /** + * Called when a share target has been selected. The client can + * decide whether to handle the intent or rely on the default + * behavior which is launching it. + *

+ * Note: Modifying the intent is not permitted and + * any changes to the latter will be ignored. + *

+ * + * @param source The source of the notification. + * @param intent The intent for launching the chosen share target. + * @return Whether the client has handled the intent. + */ + public boolean onShareTargetSelected(ShareActionProvider source, Intent intent); + } + + /** + * The default for the maximal number of activities shown in the sub-menu. + */ + private static final int DEFAULT_INITIAL_ACTIVITY_COUNT = 4; + + /** + * The the maximum number activities shown in the sub-menu. + */ + private int mMaxShownActivityCount = DEFAULT_INITIAL_ACTIVITY_COUNT; + + /** + * Listener for handling menu item clicks. + */ + private final ShareMenuItemOnMenuItemClickListener mOnMenuItemClickListener = + new ShareMenuItemOnMenuItemClickListener(); + + /** + * The default name for storing share history. + */ + public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml"; + + /** + * Context for accessing resources. + */ + private final Context mContext; + + /** + * The name of the file with share history data. + */ + private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME; + + private OnShareTargetSelectedListener mOnShareTargetSelectedListener; + + private OnChooseActivityListener mOnChooseActivityListener; + + /** + * Creates a new instance. + * + * @param context Context for accessing resources. + */ + public ShareActionProvider(Context context) { + super(context); + mContext = context; + } + + /** + * Sets a listener to be notified when a share target has been selected. + * The listener can optionally decide to handle the selection and + * not rely on the default behavior which is to launch the activity. + *

+ * Note: If you choose the backing share history file + * you will still be notified in this callback. + *

+ * @param listener The listener. + */ + public void setOnShareTargetSelectedListener(OnShareTargetSelectedListener listener) { + mOnShareTargetSelectedListener = listener; + setActivityChooserPolicyIfNeeded(); + } + + /** + * {@inheritDoc} + */ + @Override + public View onCreateActionView() { + // Create the view and set its data model. + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); + ActivityChooserView activityChooserView = new ActivityChooserView(mContext); + activityChooserView.setActivityChooserModel(dataModel); + + // Lookup and set the expand action icon. + TypedValue outTypedValue = new TypedValue(); + mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true); + Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId); + activityChooserView.setExpandActivityOverflowButtonDrawable(drawable); + activityChooserView.setProvider(this); + + // Set content description. + activityChooserView.setDefaultActionButtonContentDescription( + R.string.abs__shareactionprovider_share_with_application); + activityChooserView.setExpandActivityOverflowButtonContentDescription( + R.string.abs__shareactionprovider_share_with); + + return activityChooserView; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean hasSubMenu() { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void onPrepareSubMenu(SubMenu subMenu) { + // Clear since the order of items may change. + subMenu.clear(); + + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); + PackageManager packageManager = mContext.getPackageManager(); + + final int expandedActivityCount = dataModel.getActivityCount(); + final int collapsedActivityCount = Math.min(expandedActivityCount, mMaxShownActivityCount); + + // Populate the sub-menu with a sub set of the activities. + for (int i = 0; i < collapsedActivityCount; i++) { + ResolveInfo activity = dataModel.getActivity(i); + subMenu.add(0, i, i, activity.loadLabel(packageManager)) + .setIcon(activity.loadIcon(packageManager)) + .setOnMenuItemClickListener(mOnMenuItemClickListener); + } + + if (collapsedActivityCount < expandedActivityCount) { + // Add a sub-menu for showing all activities as a list item. + SubMenu expandedSubMenu = subMenu.addSubMenu(Menu.NONE, collapsedActivityCount, + collapsedActivityCount, + mContext.getString(R.string.abs__activity_chooser_view_see_all)); + for (int i = 0; i < expandedActivityCount; i++) { + ResolveInfo activity = dataModel.getActivity(i); + expandedSubMenu.add(0, i, i, activity.loadLabel(packageManager)) + .setIcon(activity.loadIcon(packageManager)) + .setOnMenuItemClickListener(mOnMenuItemClickListener); + } + } + } + + /** + * Sets the file name of a file for persisting the share history which + * history will be used for ordering share targets. This file will be used + * for all view created by {@link #onCreateActionView()}. Defaults to + * {@link #DEFAULT_SHARE_HISTORY_FILE_NAME}. Set to null + * if share history should not be persisted between sessions. + *

+ * Note: The history file name can be set any time, however + * only the action views created by {@link #onCreateActionView()} after setting + * the file name will be backed by the provided file. + *

+ * + * @param shareHistoryFile The share history file name. + */ + public void setShareHistoryFileName(String shareHistoryFile) { + mShareHistoryFileName = shareHistoryFile; + setActivityChooserPolicyIfNeeded(); + } + + /** + * Sets an intent with information about the share action. Here is a + * sample for constructing a share intent: + *

+ *

+     * 
+     *  Intent shareIntent = new Intent(Intent.ACTION_SEND);
+     *  shareIntent.setType("image/*");
+     *  Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg"));
+     *  shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());
+     * 
+ * + *

+ * + * @param shareIntent The share intent. + * + * @see Intent#ACTION_SEND + * @see Intent#ACTION_SEND_MULTIPLE + */ + public void setShareIntent(Intent shareIntent) { + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, + mShareHistoryFileName); + dataModel.setIntent(shareIntent); + } + + /** + * Reusable listener for handling share item clicks. + */ + private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener { + @Override + public boolean onMenuItemClick(MenuItem item) { + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, + mShareHistoryFileName); + final int itemId = item.getItemId(); + Intent launchIntent = dataModel.chooseActivity(itemId); + if (launchIntent != null) { + mContext.startActivity(launchIntent); + } + return true; + } + } + + /** + * Set the activity chooser policy of the model backed by the current + * share history file if needed which is if there is a registered callback. + */ + private void setActivityChooserPolicyIfNeeded() { + if (mOnShareTargetSelectedListener == null) { + return; + } + if (mOnChooseActivityListener == null) { + mOnChooseActivityListener = new ShareAcitivityChooserModelPolicy(); + } + ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); + dataModel.setOnChooseActivityListener(mOnChooseActivityListener); + } + + /** + * Policy that delegates to the {@link com.actionbarsherlock.widget.ShareActionProvider.OnShareTargetSelectedListener}, if such. + */ + private class ShareAcitivityChooserModelPolicy implements OnChooseActivityListener { + @Override + public boolean onChooseActivity(ActivityChooserModel host, Intent intent) { + if (mOnShareTargetSelectedListener != null) { + return mOnShareTargetSelectedListener.onShareTargetSelected( + ShareActionProvider.this, intent); + } + return false; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SuggestionsAdapter.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SuggestionsAdapter.java new file mode 100644 index 0000000000..bd5cbd718d --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/src/com/actionbarsherlock/widget/SuggestionsAdapter.java @@ -0,0 +1,733 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.widget; + +import android.app.SearchManager; +import android.app.SearchableInfo; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.database.Cursor; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.widget.ResourceCursorAdapter; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.style.TextAppearanceSpan; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import com.actionbarsherlock.R; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.WeakHashMap; + +/** + * Provides the contents for the suggestion drop-down list. + * + * @hide + */ +class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListener { + + private static final boolean DBG = false; + private static final String LOG_TAG = "SuggestionsAdapter"; + private static final int QUERY_LIMIT = 50; + + static final int REFINE_NONE = 0; + static final int REFINE_BY_ENTRY = 1; + static final int REFINE_ALL = 2; + + private SearchManager mSearchManager; + private SearchView mSearchView; + private Context mProviderContext; + private WeakHashMap mOutsideDrawablesCache; + private boolean mClosed = false; + private int mQueryRefinement = REFINE_BY_ENTRY; + + // URL color + private ColorStateList mUrlColor; + + static final int INVALID_INDEX = -1; + + // Cached column indexes, updated when the cursor changes. + private int mText1Col = INVALID_INDEX; + private int mText2Col = INVALID_INDEX; + private int mText2UrlCol = INVALID_INDEX; + private int mIconName1Col = INVALID_INDEX; + private int mIconName2Col = INVALID_INDEX; + private int mFlagsCol = INVALID_INDEX; + + // private final Runnable mStartSpinnerRunnable; + // private final Runnable mStopSpinnerRunnable; + + /** + * The amount of time we delay in the filter when the user presses the delete key. + */ + //private static final long DELETE_KEY_POST_DELAY = 500L; + + public SuggestionsAdapter(Context context, SearchView searchView, + SearchableInfo mSearchable, WeakHashMap outsideDrawablesCache) { + super(context, + R.layout.abs__search_dropdown_item_icons_2line, + null, // no initial cursor + true); // auto-requery + mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); + mProviderContext = mContext; + mSearchView = searchView; + + mOutsideDrawablesCache = outsideDrawablesCache; + + // mStartSpinnerRunnable = new Runnable() { + // public void run() { + // // mSearchView.setWorking(true); // TODO: + // } + // }; + // + // mStopSpinnerRunnable = new Runnable() { + // public void run() { + // // mSearchView.setWorking(false); // TODO: + // } + // }; + + // delay 500ms when deleting +// TODO getFilter().setDelayer(new Filter.Delayer() { +// +// private int mPreviousLength = 0; +// +// public long getPostingDelay(CharSequence constraint) { +// if (constraint == null) return 0; +// +// long delay = constraint.length() < mPreviousLength ? DELETE_KEY_POST_DELAY : 0; +// mPreviousLength = constraint.length(); +// return delay; +// } +// }); + } + + /** + * Enables query refinement for all suggestions. This means that an additional icon + * will be shown for each entry. When clicked, the suggested text on that line will be + * copied to the query text field. + *

+ * + * @param refineWhat which queries to refine. Possible values are {@link #REFINE_NONE}, + * {@link #REFINE_BY_ENTRY}, and {@link #REFINE_ALL}. + */ + public void setQueryRefinement(int refineWhat) { + mQueryRefinement = refineWhat; + } + + /** + * Returns the current query refinement preference. + * @return value of query refinement preference + */ + public int getQueryRefinement() { + return mQueryRefinement; + } + + /** + * Overridden to always return false, since we cannot be sure that + * suggestion sources return stable IDs. + */ + @Override + public boolean hasStableIds() { + return false; + } + + /** + * Use the search suggestions provider to obtain a live cursor. This will be called + * in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions). + * The results will be processed in the UI thread and changeCursor() will be called. + */ + @Override + public Cursor runQueryOnBackgroundThread(CharSequence constraint) { + if (DBG) Log.d(LOG_TAG, "runQueryOnBackgroundThread(" + constraint + ")"); + String query = (constraint == null) ? "" : constraint.toString(); + /** + * for in app search we show the progress spinner until the cursor is returned with + * the results. + */ + Cursor cursor = null; + if (mSearchView.getVisibility() != View.VISIBLE + || mSearchView.getWindowVisibility() != View.VISIBLE) { + return null; + } + //mSearchView.getWindow().getDecorView().post(mStartSpinnerRunnable); // TODO: + try { + cursor = getSuggestions(query, QUERY_LIMIT); + // trigger fill window so the spinner stays up until the results are copied over and + // closer to being ready + if (cursor != null) { + cursor.getCount(); + return cursor; + } + } catch (RuntimeException e) { + Log.w(LOG_TAG, "Search suggestions query threw an exception.", e); + } + // If cursor is null or an exception was thrown, stop the spinner and return null. + // changeCursor doesn't get called if cursor is null + // mSearchView.getWindow().getDecorView().post(mStopSpinnerRunnable); // TODO: + return null; + } + + public Cursor getSuggestions(String query, int limit) { + Uri.Builder uriBuilder = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel() + .fragment(""); // TODO: Remove, workaround for a bug in Uri.writeToParcel() + + // append standard suggestion query path + uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY); + + // inject query, either as selection args or inline + uriBuilder.appendPath(query); + + if (limit > 0) { + uriBuilder.appendQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT, String.valueOf(limit)); + } + + Uri uri = uriBuilder.build(); + + // finally, make the query + return mContext.getContentResolver().query(uri, null, null, null, null); + } + + public void close() { + if (DBG) Log.d(LOG_TAG, "close()"); + changeCursor(null); + mClosed = true; + } + + @Override + public void notifyDataSetChanged() { + if (DBG) Log.d(LOG_TAG, "notifyDataSetChanged"); + super.notifyDataSetChanged(); + + // mSearchView.onDataSetChanged(); // TODO: + + updateSpinnerState(getCursor()); + } + + @Override + public void notifyDataSetInvalidated() { + if (DBG) Log.d(LOG_TAG, "notifyDataSetInvalidated"); + super.notifyDataSetInvalidated(); + + updateSpinnerState(getCursor()); + } + + private void updateSpinnerState(Cursor cursor) { + Bundle extras = cursor != null ? cursor.getExtras() : null; + if (DBG) { + Log.d(LOG_TAG, "updateSpinnerState - extra = " + + (extras != null + ? extras.getBoolean(SearchManager.CURSOR_EXTRA_KEY_IN_PROGRESS) + : null)); + } + // Check if the Cursor indicates that the query is not complete and show the spinner + if (extras != null + && extras.getBoolean(SearchManager.CURSOR_EXTRA_KEY_IN_PROGRESS)) { + // mSearchView.getWindow().getDecorView().post(mStartSpinnerRunnable); // TODO: + return; + } + // If cursor is null or is done, stop the spinner + // mSearchView.getWindow().getDecorView().post(mStopSpinnerRunnable); // TODO: + } + + /** + * Cache columns. + */ + @Override + public void changeCursor(Cursor c) { + if (DBG) Log.d(LOG_TAG, "changeCursor(" + c + ")"); + + if (mClosed) { + Log.w(LOG_TAG, "Tried to change cursor after adapter was closed."); + if (c != null) c.close(); + return; + } + + try { + super.changeCursor(c); + + if (c != null) { + mText1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1); + mText2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2); + mText2UrlCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL); + mIconName1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1); + mIconName2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2); + mFlagsCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_FLAGS); + } + } catch (Exception e) { + Log.e(LOG_TAG, "error changing cursor and caching columns", e); + } + } + + /** + * Tags the view with cached child view look-ups. + */ + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + View v = super.newView(context, cursor, parent); + v.setTag(new ChildViewCache(v)); + return v; + } + + /** + * Cache of the child views of drop-drown list items, to avoid looking up the children + * each time the contents of a list item are changed. + */ + private final static class ChildViewCache { + public final TextView mText1; + public final TextView mText2; + public final ImageView mIcon1; + public final ImageView mIcon2; + public final ImageView mIconRefine; + + public ChildViewCache(View v) { + mText1 = (TextView) v.findViewById(android.R.id.text1); + mText2 = (TextView) v.findViewById(android.R.id.text2); + mIcon1 = (ImageView) v.findViewById(android.R.id.icon1); + mIcon2 = (ImageView) v.findViewById(android.R.id.icon2); + mIconRefine = (ImageView) v.findViewById(R.id.edit_query); + } + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + ChildViewCache views = (ChildViewCache) view.getTag(); + + int flags = 0; + if (mFlagsCol != INVALID_INDEX) { + flags = cursor.getInt(mFlagsCol); + } + if (views.mText1 != null) { + String text1 = getStringOrNull(cursor, mText1Col); + setViewText(views.mText1, text1); + } + if (views.mText2 != null) { + // First check TEXT_2_URL + CharSequence text2 = getStringOrNull(cursor, mText2UrlCol); + if (text2 != null) { + text2 = formatUrl(text2); + } else { + text2 = getStringOrNull(cursor, mText2Col); + } + + // If no second line of text is indicated, allow the first line of text + // to be up to two lines if it wants to be. + if (TextUtils.isEmpty(text2)) { + if (views.mText1 != null) { + views.mText1.setSingleLine(false); + views.mText1.setMaxLines(2); + } + } else { + if (views.mText1 != null) { + views.mText1.setSingleLine(true); + views.mText1.setMaxLines(1); + } + } + setViewText(views.mText2, text2); + } + + if (views.mIcon1 != null) { + setViewDrawable(views.mIcon1, getIcon1(cursor), View.INVISIBLE); + } + if (views.mIcon2 != null) { + setViewDrawable(views.mIcon2, getIcon2(cursor), View.GONE); + } + if (mQueryRefinement == REFINE_ALL + || (mQueryRefinement == REFINE_BY_ENTRY + && (flags & SearchManager.FLAG_QUERY_REFINEMENT) != 0)) { + views.mIconRefine.setVisibility(View.VISIBLE); + views.mIconRefine.setTag(views.mText1.getText()); + views.mIconRefine.setOnClickListener(this); + } else { + views.mIconRefine.setVisibility(View.GONE); + } + } + + public void onClick(View v) { + Object tag = v.getTag(); + if (tag instanceof CharSequence) { + mSearchView.onQueryRefine((CharSequence) tag); + } + } + + private CharSequence formatUrl(CharSequence url) { + if (mUrlColor == null) { + // Lazily get the URL color from the current theme. + TypedValue colorValue = new TypedValue(); + mContext.getTheme().resolveAttribute(R.attr.textColorSearchUrl, colorValue, true); + mUrlColor = mContext.getResources().getColorStateList(colorValue.resourceId); + } + + SpannableString text = new SpannableString(url); + text.setSpan(new TextAppearanceSpan(null, 0, 0, mUrlColor, null), + 0, url.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return text; + } + + private void setViewText(TextView v, CharSequence text) { + // Set the text even if it's null, since we need to clear any previous text. + v.setText(text); + + if (TextUtils.isEmpty(text)) { + v.setVisibility(View.GONE); + } else { + v.setVisibility(View.VISIBLE); + } + } + + private Drawable getIcon1(Cursor cursor) { + if (mIconName1Col == INVALID_INDEX) { + return null; + } + String value = cursor.getString(mIconName1Col); + Drawable drawable = getDrawableFromResourceValue(value); + if (drawable != null) { + return drawable; + } + return getDefaultIcon1(cursor); + } + + private Drawable getIcon2(Cursor cursor) { + if (mIconName2Col == INVALID_INDEX) { + return null; + } + String value = cursor.getString(mIconName2Col); + return getDrawableFromResourceValue(value); + } + + /** + * Sets the drawable in an image view, makes sure the view is only visible if there + * is a drawable. + */ + private void setViewDrawable(ImageView v, Drawable drawable, int nullVisibility) { + // Set the icon even if the drawable is null, since we need to clear any + // previous icon. + v.setImageDrawable(drawable); + + if (drawable == null) { + v.setVisibility(nullVisibility); + } else { + v.setVisibility(View.VISIBLE); + + // This is a hack to get any animated drawables (like a 'working' spinner) + // to animate. You have to setVisible true on an AnimationDrawable to get + // it to start animating, but it must first have been false or else the + // call to setVisible will be ineffective. We need to clear up the story + // about animated drawables in the future, see http://b/1878430. + drawable.setVisible(false, false); + drawable.setVisible(true, false); + } + } + + /** + * Gets the text to show in the query field when a suggestion is selected. + * + * @param cursor The Cursor to read the suggestion data from. The Cursor should already + * be moved to the suggestion that is to be read from. + * @return The text to show, or null if the query should not be + * changed when selecting this suggestion. + */ + @Override + public CharSequence convertToString(Cursor cursor) { + if (cursor == null) { + return null; + } + + String query = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_QUERY); + if (query != null) { + return query; + } + + return null; + } + + /** + * This method is overridden purely to provide a bit of protection against + * flaky content providers. + * + * @see android.widget.ListAdapter#getView(int, View, ViewGroup) + */ + @Override + public View getView(int position, View convertView, ViewGroup parent) { + try { + return super.getView(position, convertView, parent); + } catch (RuntimeException e) { + Log.w(LOG_TAG, "Search suggestions cursor threw exception.", e); + // Put exception string in item title + View v = newView(mContext, mCursor, parent); + if (v != null) { + ChildViewCache views = (ChildViewCache) v.getTag(); + TextView tv = views.mText1; + tv.setText(e.toString()); + } + return v; + } + } + + /** + * Gets a drawable given a value provided by a suggestion provider. + * + * This value could be just the string value of a resource id + * (e.g., "2130837524"), in which case we will try to retrieve a drawable from + * the provider's resources. If the value is not an integer, it is + * treated as a Uri and opened with + * {@link ContentResolver#openOutputStream(android.net.Uri, String)}. + * + * All resources and URIs are read using the suggestion provider's context. + * + * If the string is not formatted as expected, or no drawable can be found for + * the provided value, this method returns null. + * + * @param drawableId a string like "2130837524", + * "android.resource://com.android.alarmclock/2130837524", + * or "content://contacts/photos/253". + * @return a Drawable, or null if none found + */ + private Drawable getDrawableFromResourceValue(String drawableId) { + if (drawableId == null || drawableId.length() == 0 || "0".equals(drawableId)) { + return null; + } + try { + // First, see if it's just an integer + int resourceId = Integer.parseInt(drawableId); + // It's an int, look for it in the cache + String drawableUri = ContentResolver.SCHEME_ANDROID_RESOURCE + + "://" + mProviderContext.getPackageName() + "/" + resourceId; + // Must use URI as cache key, since ints are app-specific + Drawable drawable = checkIconCache(drawableUri); + if (drawable != null) { + return drawable; + } + // Not cached, find it by resource ID + drawable = mProviderContext.getResources().getDrawable(resourceId); + // Stick it in the cache, using the URI as key + storeInIconCache(drawableUri, drawable); + return drawable; + } catch (NumberFormatException nfe) { + // It's not an integer, use it as a URI + Drawable drawable = checkIconCache(drawableId); + if (drawable != null) { + return drawable; + } + Uri uri = Uri.parse(drawableId); + drawable = getDrawable(uri); + storeInIconCache(drawableId, drawable); + return drawable; + } catch (Resources.NotFoundException nfe) { + // It was an integer, but it couldn't be found, bail out + Log.w(LOG_TAG, "Icon resource not found: " + drawableId); + return null; + } + } + + /** + * Gets a drawable by URI, without using the cache. + * + * @return A drawable, or {@code null} if the drawable could not be loaded. + */ + private Drawable getDrawable(Uri uri) { + try { + String scheme = uri.getScheme(); + if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { + // Load drawables through Resources, to get the source density information + try { + return getTheDrawable(uri); + } catch (Resources.NotFoundException ex) { + throw new FileNotFoundException("Resource does not exist: " + uri); + } + } else { + // Let the ContentResolver handle content and file URIs. + InputStream stream = mProviderContext.getContentResolver().openInputStream(uri); + if (stream == null) { + throw new FileNotFoundException("Failed to open " + uri); + } + try { + return Drawable.createFromStream(stream, null); + } finally { + try { + stream.close(); + } catch (IOException ex) { + Log.e(LOG_TAG, "Error closing icon stream for " + uri, ex); + } + } + } + } catch (FileNotFoundException fnfe) { + Log.w(LOG_TAG, "Icon not found: " + uri + ", " + fnfe.getMessage()); + return null; + } + } + + public Drawable getTheDrawable(Uri uri) throws FileNotFoundException { + String authority = uri.getAuthority(); + Resources r; + if (TextUtils.isEmpty(authority)) { + throw new FileNotFoundException("No authority: " + uri); + } else { + try { + r = mContext.getPackageManager().getResourcesForApplication(authority); + } catch (NameNotFoundException ex) { + throw new FileNotFoundException("No package found for authority: " + uri); + } + } + List path = uri.getPathSegments(); + if (path == null) { + throw new FileNotFoundException("No path: " + uri); + } + int len = path.size(); + int id; + if (len == 1) { + try { + id = Integer.parseInt(path.get(0)); + } catch (NumberFormatException e) { + throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); + } + } else if (len == 2) { + id = r.getIdentifier(path.get(1), path.get(0), authority); + } else { + throw new FileNotFoundException("More than two path segments: " + uri); + } + if (id == 0) { + throw new FileNotFoundException("No resource found for: " + uri); + } + return r.getDrawable(id); + } + + private Drawable checkIconCache(String resourceUri) { + Drawable.ConstantState cached = mOutsideDrawablesCache.get(resourceUri); + if (cached == null) { + return null; + } + if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + resourceUri); + return cached.newDrawable(); + } + + private void storeInIconCache(String resourceUri, Drawable drawable) { + if (drawable != null) { + mOutsideDrawablesCache.put(resourceUri, drawable.getConstantState()); + } + } + + /** + * Gets the left-hand side icon that will be used for the current suggestion + * if the suggestion contains an icon column but no icon or a broken icon. + * + * @param cursor A cursor positioned at the current suggestion. + * @return A non-null drawable. + */ + private Drawable getDefaultIcon1(Cursor cursor) { + // Fall back to a default icon + return mContext.getPackageManager().getDefaultActivityIcon(); + } + + /** + * Gets the activity or application icon for an activity. + * Uses the local icon cache for fast repeated lookups. + * + * @param component Name of an activity. + * @return A drawable, or {@code null} if neither the activity nor the application + * has an icon set. + */ + private Drawable getActivityIconWithCache(ComponentName component) { + // First check the icon cache + String componentIconKey = component.flattenToShortString(); + // Using containsKey() since we also store null values. + if (mOutsideDrawablesCache.containsKey(componentIconKey)) { + Drawable.ConstantState cached = mOutsideDrawablesCache.get(componentIconKey); + return cached == null ? null : cached.newDrawable(mProviderContext.getResources()); + } + // Then try the activity or application icon + Drawable drawable = getActivityIcon(component); + // Stick it in the cache so we don't do this lookup again. + Drawable.ConstantState toCache = drawable == null ? null : drawable.getConstantState(); + mOutsideDrawablesCache.put(componentIconKey, toCache); + return drawable; + } + + /** + * Gets the activity or application icon for an activity. + * + * @param component Name of an activity. + * @return A drawable, or {@code null} if neither the acitivy or the application + * have an icon set. + */ + private Drawable getActivityIcon(ComponentName component) { + PackageManager pm = mContext.getPackageManager(); + final ActivityInfo activityInfo; + try { + activityInfo = pm.getActivityInfo(component, PackageManager.GET_META_DATA); + } catch (NameNotFoundException ex) { + Log.w(LOG_TAG, ex.toString()); + return null; + } + int iconId = activityInfo.getIconResource(); + if (iconId == 0) return null; + String pkg = component.getPackageName(); + Drawable drawable = pm.getDrawable(pkg, iconId, activityInfo.applicationInfo); + if (drawable == null) { + Log.w(LOG_TAG, "Invalid icon resource " + iconId + " for " + + component.flattenToShortString()); + return null; + } + return drawable; + } + + /** + * Gets the value of a string column by name. + * + * @param cursor Cursor to read the value from. + * @param columnName The name of the column to read. + * @return The value of the given column, or null + * if the cursor does not contain the given column. + */ + public static String getColumnString(Cursor cursor, String columnName) { + int col = cursor.getColumnIndex(columnName); + return getStringOrNull(cursor, col); + } + + private static String getStringOrNull(Cursor cursor, int col) { + if (col == INVALID_INDEX) { + return null; + } + try { + return cursor.getString(col); + } catch (Exception e) { + Log.e(LOG_TAG, + "unexpected error retrieving valid column from cursor, " + + "did the remote process die?", e); + return null; + } + } +} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/test/com/actionbarsherlock/internal/ManifestParsingTest.java b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/test/com/actionbarsherlock/internal/ManifestParsingTest.java new file mode 100644 index 0000000000..47475c5746 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/library/test/com/actionbarsherlock/internal/ManifestParsingTest.java @@ -0,0 +1,37 @@ +package com.actionbarsherlock.internal; + +import org.junit.Test; + +import static com.actionbarsherlock.internal.ActionBarSherlockCompat.cleanActivityName; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +public class ManifestParsingTest { + @Test + public void testFullyQualifiedClassName() { + String expected = "com.other.package.SomeClass"; + String actual = cleanActivityName("com.jakewharton.test", "com.other.package.SomeClass"); + assertThat(expected, equalTo(actual)); + } + + @Test + public void testFullyQualifiedClassNameSamePackage() { + String expected = "com.jakewharton.test.SomeClass"; + String actual = cleanActivityName("com.jakewharton.test", "com.jakewharton.test.SomeClass"); + assertThat(expected, equalTo(actual)); + } + + @Test + public void testUnqualifiedClassName() { + String expected = "com.jakewharton.test.SomeClass"; + String actual = cleanActivityName("com.jakewharton.test", "SomeClass"); + assertThat(expected, equalTo(actual)); + } + + @Test + public void testRelativeClassName() { + String expected = "com.jakewharton.test.ui.SomeClass"; + String actual = cleanActivityName("com.jakewharton.test", ".ui.SomeClass"); + assertThat(expected, equalTo(actual)); + } +} \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/pom.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/pom.xml new file mode 100644 index 0000000000..1cda497a9e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/plugins/ActionBarSherlock/pom.xml @@ -0,0 +1,212 @@ + + + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.actionbarsherlock + parent + pom + 4.2.0 + + ActionBarSherlock (Parent) + Android library for implementing the action bar design pattern using the backported + sources of Ice Cream Sandwich. + + http://actionbarsherlock.com + 2011 + + + library + samples + + + + https://github.com/JakeWharton/ActionBarSherlock/ + scm:git:git://github.com/JakeWharton/ActionBarSherlock.git + scm:git:git@github.com:JakeWharton/ActionBarSherlock.git + + + + + + Jake Wharton + jakewharton@gmail.com + jakewharton + http://jakewharton.com + -5 + + developer + + + + + + + Apache License Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + Jake Wharton + http://jakewharton.com + + + + GitHub Issues + https://github.com/JakeWharton/ActionBarSherlock/issues + + + + UTF-8 + UTF-8 + + 1.6 + 4.0.1.2 + 14 + r99 + + 3.3.2 + 4.10 + + JakeWharton + ActionBarSherlock + + + + + + com.google.android + android + ${android.version} + + + com.google.android + support-v4 + ${android-support.version} + system + ${basedir}/libs/android-support-v4.jar + + + com.nineoldandroids + library + 2.4.0 + + + com.github.rtyley + roboguice-sherlock + 1.4 + + + junit + junit + ${junit.version} + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5 + + ${java.version} + ${java.version} + + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + 3.3.2 + + + ${android.platform} + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.9.1 + + true + + + + + org.apache.maven.plugins + maven-site-plugin + 3.0 + + true + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.2.2 + + true + + + + + com.github.github + site-maven-plugin + 0.5 + + + site + + site + + + + + Creating site for ${project.version}. + website + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/pom.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1 @@ + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/proguard-project.txt b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/proguard-project.txt new file mode 100644 index 0000000000..f2fe1559a2 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/project.properties b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/project.properties new file mode 100644 index 0000000000..47f98ae9d1 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/project.properties @@ -0,0 +1,31 @@ +# +# Copyright (c) 2014 - 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=Google Inc.:Google APIs:${platform} +android.library.reference.1=plugins/ActionBarSherlock/library diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_bookmark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..d14f46de0c4228593c8424026ed63ffeadeb4c03 GIT binary patch literal 4960 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_check_selected.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_check_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..319b7124de17df057156773195b1b458bab382b8 GIT binary patch literal 8100 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 a3?Q#Vrbx+U|F6G(_ZaA!AWIQWQU3w%ka@`f literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_logo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_logo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..5ac68d8a294811b395c9dd35996be3a36a415130 GIT binary patch literal 4699 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 a3?Q#Vrbx+U|F6G(_ZaA!AWIQWQU3w%ka@`f literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_stat_gcm.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/ic_stat_gcm.png new file mode 100644 index 0000000000000000000000000000000000000000..71ce86772dabb592fb1dcfc6080f24c0e460c022 GIT binary patch literal 1135 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 YLpCP`4=;TDy-p&I6P$r6+w(X62e#%|Q2+n{ literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/repeat_bg.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-hdpi/repeat_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..1282b9cde88b41bf74076f55af2f7a6f03332133 GIT binary patch literal 7114 zcmV;*8#UyKP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^h$ z3OX)$eSHxC02@k4L_t(|+U;C-d{kBTKj*&presnPLI{L3Itqj$xD*i)=`}#IqOiJ_ zRcRJbTxk|`Eh{2Lb`eFFwIE0+0R)lWds`rZ5FivuV@hUTx##!Cof#&RAp}JB_t}r{ z1M`{8yY+j|J>`4udq_m^`*o)-R+U0xNp5{%i2O}dy}Q64z*qO$E%B$g1yuDmgBt&} zQ@hCvsmc%_qWJXw>1_Zjtp)_XiU8iqm8^=dO>cMJ9}$5AGXIY#0QQdo(Em}%u*FP+ zXHntqZwj|ub*#06S;mQ<5hbujnS1_Kh{TOXM+m@6FR-XuM1W9v4HW27=|y$LR506s zxT((+W(p%fBtS&%*cyIjH#rJ1x|ZC00IQLT#L0_Nh{pXma?TlJ0C4E=;jLS?p2<5+ zoY$_K*rrvhw(Z*9F=cWS(haK1Ik7%4i8POG!Y+(XK*nxVivu#xq8H>A1Lf2|5HO!~ zUT-fDAbPSUs$1qEGC;7sl@G`O!9AzHab^!70&%Z=6F_vFb@&3QRudwQfZ&r^Kh}Pr zH*eWG`L)+_b8`c=hgb|EN=i*#m$KQ33)mGyn!nL3^R| zoi?7;?*g(wi58G?&H-S{<}Ka2KGe5+_q;P_7-O<50f0_SCq@K{A}fkgaQ^(LXP-@L z-eU3hi-QpVFG)8L64#HfFPl3AEs?;`Hsu5`*{d}%L_ExS}+g?Xx zL=A1%LicwsFjE-GX4{nikXGiJ)DVyX0dO7T8Y(IGK|~FH;i!IU2e^s>kyMwt@0&`; zrvfKKM2xX_roHpY^ywChg>%jUCB{;tS<^ZZDd9RpI^!}OI#Y7mA(eSli6H{0s@kr7 z`>((Kh9L$n-kpZqzx`Zqw<2dD=(^>}ujP8}i32hWxj0Awh^`MiQ(+z%nyLGErPK2W z2rQIc6T?7szSjXt&JqBt+s69zBG=S=xW~>2NRq5ie9e;D0OtrmfXL7_cQDV}35et@ z3V-Jun8J}Up&uAy&p-Rzs+B7^CjhjWrDt24|I*CmcIq0JeOnAA;9+6<_ork2wq3n! z*AR&ztDBUxX6=uRF@g1MR4nW!Rt6COB3r&lgtE?m$Nts=J%H6BfN*&U>F2@s{|I&%F^h`^CK%9L(#&UO8@ zw>w+h8WB<6sZ;lN>?BOR<~KBc}}lGJp`nW2p235n!nOK|sjKv*2-1tiX_n zn4$3tM+gz1qSE(z58B!f(NGB`DY-Q$R{A9ukq`iFF><4a5X#$GL`D?;Mo#$OE@Dgq zA`l`Xa?Ten{CCz5OAxV4qmQ~rj&EAZxzKqG5gCxub&TAiKahcl0N(A{FQF`ZsI62* z#_(Kz{^W_1g51PAE8Ro@Al0bH5?ce3a5;dXh+@h^hX4SK>1PizWI%vGM5L~H7lm31 zHnWHTVCd?O1t7`fEH-r>g+#`cJkbH&C2bHn3W<|&mJpEx)DJ6LJiwyrB+K%wPd+(&_M9-e zcU-!CGbGN@Be{2i_z!s1sX|0`T|2SLhG~vr2FpkhB#@V$&1Sg7$iu&V_A$|>h$Km!)5?OLP@Yo3m35@^zez#A2Q1~I{;qw6iB}HBLp|Eo0q!rP)bP`-8K*)>FnR`qy zb$o_^2)KLRF!JFGzE1++1xJxFK;&wf(k2s#3+F?QO$9Q5DcZWfm(3Z#HPtJ|$h{f~ z1C=@M*}cbp)s6^VQ_NPi1bwCbQL9w1BeO=;=5D-z{`6Vy~5LmTDDWL@cAVVUuj9!b;@c;y}ndk3yO=+lRzb!}xWt zxrY!ylC*7Kc=ZqZ$v#qlo(TkC7?xq53b_^r067nPd7IKElT;@lLjrBn9OtCQp4D%o z@LGIvswkhGy^1l0vbjZ!N&rkqrPr7fM%4sK(T}X+Mft{|l?Z@wjR~2r2m$9n00ehQ z?!+jWF?Q_eVc}T@1tGUaCEhgLfQSgl(E7x`gn%14o4Ch`KK}#(^*!H7(Q(89&EZnr zR$_pb#}@)O5WqOGo;wSLuP6}LcP&Iq1R@6@jBOy`^QuyYKx7{9j`f+vEVcnJD?uic zQKtPo)A4G8w(cWD^zk1^L?@0NMZ{>uh%p(6UdP$1w>8!J%u+<=$$o>$W(v zGe0mAbT z;c?!qp1FCrec?IA)+faZ$UrO8x6Ttz2>}p*`r~`V2@y;Wk4H)I+E7ab$R;8JrfBPD zkZ?3O0iwF@Bajv1Ah&%K&9(qm6+whjoJ%R~Eu&XkpI!u!aiD1+nSe>2AK!PpQilpp z`J6y9nM?qnNGwbyFg#?aqmkZl%=_A5Q{E%+!5?x_lx^ine!= zsrO{Tnj0rKQ1LmCEx^Fsdvb^%)f-6za$@zn$m6@}r?z;$9YduTQIZkCIk}1T*=16b zZb)Qs4gg%SnBF>K4&_^^i(mGRpCP&J+Wy5#^MO*mKk$O1rVfAR?yK6yIe=)gm~{IU zzvQO1YL%Rv9A>kf%FSJ!y(%&)YT|?m7YZ&+cx}Q>A%3gzl5k;Fr|YdWFmzCzVN;GV zOAImQUNC~6*g%}Kgyvy?$s*s{5D+4BzFv<=2Te5(`ao$j6p)oI_>=LUb%>0U5&qWM zaty6MAiBmCkoXmd8>hFI&FqQR7ytlWH4mGs+}-Q$ruVoUc2)Ik-Fu*Je9hodyRSMY zHv(oth9Zu|u!yh;`;9{@F(yH(o93F?ho3))h@7zVVk|A=4wvg}!FgGh{i;;g^;2Be7y=mkml6>GnbSYImh=HY z4nTyl^??9ole%RtA>*7Ixmy4w@;Ggy*J6+w42)k807aUCApjtgQrd@4%>|SI5M-0K z?(cxuw_jh*xeBI(f9+s@rFPIi$CM^0nS8c^0FXOM!O*2l*?A4uMcmRMGo*}OH>(>teBF!u-Phw0)Sz)rt`%f}4rU(~PxF3js5_5m~1R@fm zx@0_>ZJfX`V9rrFO4bd-==xCCKtTNz%Dm4$yL9Q&xpU{>#wo2|3Aaz^2vKg@1FcaA z2xMq`zBY2V0F%JrN|OhXa|}!~AQAwJh?P?RfB?WXeb-l>6>p+q1w&O@r3*I5SDt`# z@;b{Qlf{DTLbTn55pjq}?yI1yZSK7{JUoH`R-Duniz4cJ-8OFp^tSJ7z&N&+JBy6t z>-7^GfQTVPh0&s8sv=9WEdTkbr_gr=%6M{0a$K!A061~{1XP*Bx>aT3WqSaKOg&yB z&VfK(F@;=3005+$`@c(w5V+BVI1UCghV`K-Wa_^F-KA?Jb$-m$#}F?69XN$ zBhp@`0YKfv#F{l@1HEi47sN6EU=pjksl0XF?G;!erDZxfuOJhFJOQ9oucJ5h9+aGP+$?!6sEMv5JE(RWWQwU`vwMZPvw+8L$pT9&HEFg zNX?VSp|t-qaE<{79{>Pj5?DkH#+bJD1N1jW2m zEiIK0o?qoY>aHdMCxQU(I-o1@UotU<1fVj@1K%19QB~E^FTQYBwU|J@`&!Z&;H4K{ ztW~R4ty;By}uN zi?qo?;SuLz_fR?dmq0<kt!Nk00dyQo3UyM1PGj)9(plA)sX*m3fij6Ee8P* zFiFjxrfpv!*ln-bLp1Ccoga1v(g_ebH}{z$AQ7r|`p45db$&oqRg=WVuXPSsZP|In z91$j2Bu)gJfOF!U6y)Jybj)skcB3WzhcX3;6D6mltX!4Nxe+p7%NTofXr?4dJ$v_l z=%KE6B+LmO1sccKx)(f7Wmj!)=CZJA*F9h*b|s>byVX4}gAC2~$}Wtq9YB-%bISmT zj*0a_*M#H4%;BbfZ(~FaFf?t~Lj7PCn!X->-%3zdcs22NT)@Y0JfE&Apg#u!6% z>jX^tQ<|kqyc(qdA~gPlJO$x2e7`wYsW4GHa z$@2EyyJMoGZYp8_tKs&!SX}owUr#l)Og9giPMkud=Yx*2sV?WFMpz>y?8OaOp0+M` zm=Do4^&ajnWhikVhDh8%lmWPJCm5CyUq}tRKm`#KEo|MkedJ%BExPgxlO%7nKwQ%a zfE1beX)ImSY!MOTUU_Bsh~a?;g97nE#Qy#IAKJg)<#KJ_zAY&!>1K01w=3yMoP%fn zBc?u6r0S_b*{o0;7Z8B^pF_+8-^Z9be#>7GaRLI)wRInOmQRr)Yl6Ya+cx8xi^Vs! z{AH~!s;*eQx>>V(ZsAzrZGqcsE%=qwSS=BlgjK6UWhH11N0gv^GN}B@2osB3bx~m+ zKX;H9<)N)Qi@%#yPiB!d!Kcch!WIcKVu)B$QgZpy<=j)J&YjJ7yFIlN>fGI=NldkB zHEPrl$J;8hAAU^7j2^RO(IUezW`6o<< zssyznzFel)0jXxS=*@zax7+)4yxi zuAbexg@;G<>DPbO>{;G?Xa!q(Q%^qpF5RI;`_iS$ty`p7trj9OTP%jIhb*ZZ#-qcB zPnc#*Ulr} zs6u39Wc9nM-MTXQ?Vd~tZ2u<0r{8QO*Ml2;4?o;+w0?fdU;ZZGzTTs7ztOC!(sD(5 z^Vf_ga5|N&W!1Y2dQ|YHJrjSTNO+f(45gA&Ta`R2dd=al@cZ@J@qdamO33P!uWMlH z%OAW164}>_dTu!JkXT>uk=f9W;FVvltY81L-_!<9FYrqxoO;k4DhjDMe-xM{2^?!h z9Es?gufGwsLQb+0(1Q?Xj4{TxZrS4R$gQe*d3pYkZ{NP%GB(He`~X6&GsYi za5#j}5s}B^5s6Ai`Mz{rPfAGFHe` z>N=?Zz?Q9B6%-WAoHf%+)q0;F7SDte0C+r}fBth`{+WEI(~*>%e6_T+`dxR89y{j1 zzP;6|#SDM+vF2%MEz(-1B-K59dAllJY~JMNWN+-`TL zP96L9?vu5A*~LqjPaOZxrVSh2Zck3m$!XS=bwEhXtu(_LRD2~ zO#e7HCpW2f9m6nY&zh5!m1P*l*|TTAT(BTxXy*Cz1%__CF!qHNE3+MTI}v4NE&J!( zxkRLC+OlQK_w3$d7@Tv%(A-zYL|q*d>1UW+F4y;qmk`m!*I&PQ;UW>;-?1|hE&S@M zv7^Tb4rJxZ>|;ld4jw#IOlsWA%&t zTSU~aPv7F=lI6=+a?bbe-B(mplsPoBsHo`Zkt1Jxu|QQdyTg(7!_tbzKn_VVBO(H2 zEzQz2Ev;pmrfE|rPx<2`k6bLcaQ8jUA|u1Sn&{f02Bt0=%VO(mTj!e|dP$tlxma+1 z<%$)YQ^Q7$N{WjT6B7a8u4>VSF9(>Lle2o&YDA2$Q`>AYC#BXyM32XlkdOcX;o;#2 z4<1rv*%oF61j8_T_UQh@;w9_WuW!-3nceAHwQ6-qafvLml++aOgHEmzDXEPVn`-22 zWT_p95Qu8kiU)wOuy7_z0H7!`05B$rV}FR)<-rGYb57Q+Q(KIxbC)jMFaW^mbm|2c z7v(MjfNl?W%gMjJ-c|x;`H=Ed-m=N3$uE4C4gaY zf7ok!Yyn2swhaH=udw3MMe2*i3JCMKMosqf9K8_nHl+K@?&CR zbX^Aki`BYu!$!tfUS8hA4?k@9yb;FOci(>3f8c-_Gd|w9VPm644S^^lbLhEq=L-u9 zK^!2oRhJvwkMYe|y-whJ=F?}^{9`tRk_nFpw>w>k_{@_}B7omozC3oUEXxMxP4B*Y z|GvE$nHedmsb}-g_8&NK{L3#VCns;)x~*5AUU_+E+P1wnJw4rScSw?K7@PsXwsyycxo+3eM^%kPY!k@0jyT**cZlr_`!#}ckk)br+32!4JN%l>G<&zLo$XI z6r69=uu=U6^@YV~k(TC7hbd;Ic|VMb7stUkQI{?ceDMAU2M!$U*r7wsnl;U4Q%XvT zFj{+u996Xqql+>VpeOZ=Uq_x<(WsBKt-n@BBetv#tW+nhMZqi7W zWdi8ax6j*ey|rV<&Y_tZojP^;@y8$c?%h{2Hnu~@4&Wn@SpECuq&DKjmKdSLSX5Lb zAk|`u1tmsFA14oz^m~WviCWn>UY(i`%(l=dPW*l9Q7+Zrpg^eeF_G zlB-p#CQIz6pVsG`$Qd$paK+dsILz@rqJijtBZZJk|98K8B-*<6q7q@YeO_5m3;s3( z>4lK3P5wA!8>D^LiT{qDmj zM;P0HAPfk}l8gc&K!9!VCx`vT;s5_9(C+T4%FFVa(| z>z3E?`=5M$`+e=MGyL}V$1nBG&X4(5UB-U0*Trk~pZ-T)*8a8E-M{UA>EFj2>hX_X zp}xH6>94i_@Aq%|U-0SAALsWSujwz|UnnkeJZ9bZ`t4KeZ@s^J`|-~F*WO*3pYlfh zp8LDr>(74iJPEb_>ig8s)6-j_mv8!m?&Sde{;TfaufIqW`=9g6-cEn}=lkbA z{qxQEcHflVI(NfTo=53FcNXid)wDMPc}aBryLFb%_rtpd)qusI1T%@+ilD)vSsQr!w%MIB$nC)9?e;)JZKEDTk$zLV?TOFI zZCrg=c=my-wO_WeWnk0CvDG>1HM@IC?FDTvrfKFwiB>dp{`Ryo3{pQqF_lxycwLPZ6`jDDi7E`kyV!R+xYnmGH)i*rf#MQ_<-wLDFnMs)ny#0|b9?6Y@P?CEr}4OrVa>}fYN z6uvw*eVy7MjJW~_jhjtY+oWyc`qwirvG1ye*B`un({8POVmQ0yxTV+ynpq#Qc86i# zj?LTcXj?Puy0mr5)K6h=`C_cvy|tHRMnPj}cQO~-v|CzaHYbCU8@pYxK1CA8&ga80 zVW-oyEcT+J>$E}1yJW9ou}9rYUO62s%vsvd=g^}voy_k%<+f>;E&X#oANV%ATz%WI z1w-B#&!HQ@7VKNWe2mOPT+r=pyIS53c3Hz>$5Na|&zqHHZ5DaVJ7+2Eaq(iqzV|nu zD@LDU=Y>9HWTB8rN<*1Z4WGX>!?SL&uy{@8qpAqX})E!j~h)-PlBEG${x(3Py9V50d#iR+I9W0WoEEaDmc7gPL;?TE zUY%v5V{o6`cn$+i_L#2B#xB<_aW>!)Xf1Bxgz~56(~Z-~?u0+Z((HW7uwWWXTLAsH4iH3Gy9BTF5(0;>Fujx2^a8|GxZn>fi_;%Q`-mUc1 z9ZxjLXI$mO=WTb#^Gn9rJXyJleQ?QC+WW${+Bk7v5=;C~UU@Sv&6!yD{U_lXu^P*O zMaDAVf*Rlwr`4zcY^O-T8yR69p&giVZ>R2VYg#Nmonj@Zoyzin;1f9({X1V49k;ux-CMxY&XW+B$hCfjcQ zK5=~0ZeW&2)918oU}d^S-wSE%rtmsf4%BeccOR3dT<`8%wY_p|XV^+a#EY6aA~NGG zy^}6$qk!J_ zz+nbsYhixe^VNzhT5mRmL^0vV$(G4rwK-b%hsU{c3bcZ&HnUsp*=Bv>;kO8NtA{pb z3P&>*K6xIPYh)%_Zp?9-{*6^&v%9@yl`|ib;iOG}m^dE!a+;45YasDr4;vAd&Qz`1 za5J$Hdsq28{6cr^_O=JincBO8PvkcS_XKT$yG`Nu9C(w>Lj4vt)vz)PLOGwjC+!)iwAjf-;(UhT>Iv2GtPo&zkGVNQ|q3;)Y1N*S`MRWd?*KbSW zY<6UFZ=z;Uy!Dmd_A#rR!-0vL^v`(Y=sX`{wh-%5Irg-M?N`gPkb2Us#$=RZMm8HA zhU@oEoUFuSS@xHFWO?#q=7}h0%%XQ#JzvsZv~;6(tW~qi8VhsMEwe#vZP|_H2Cxj; z_k;VVLq5(nY8Gi8aJ(_Khs6EwD1(rmY0Jeo1| z5gB88%Ck#5JRZxYTxaGb6{+o!lCvApfG?5r#WoF5%iep>D_3D>Osj{SN{?gUs)CQp zX~IF^qlsx^hCEQNezyKGSmXx_&QID!ZB@u}a#3J!jE@v!2yk0;V(9-sIz ztTWC=-u(`bh2=t8VrwF3jO<0)N+s_GJXyRO-tN|UJUnH9JD9C5_Hy6=kty?g(paUn zZp%B|)k(8sDUH~Thuv?7#jf;w`w&gsksAz8#jSG=(7yYl$yBjjRdiYS}*fyIDA?6*pwBBV{hxzpU0L6>(rO}sRr3zX4kh@njJI) zG>wY_ip=p@1hgL$qcPw2!-N+$u#bqxUqd+R6DPL4Ub(Y$NLlm>TkQXeMSVB#IO^?E z=3tt+c|0ENrpN$hrE&B)Jlqx{$~HjjzAknxt>7sFr9G=k1bRyU&zOLO!I5hnJRa10 z6rr2-AIkZ1N>rhyxpY<1Jj3=VpL)JCX9Im?UKvNGR(up5IAF^GR%1yP&wHl#^jtMIGGT`(ClJMmCm^e-{xf&)7!W>yL`-=@-`ykl|ZXrsTecjt# z=JtX~6&`LZ{o?KzDBrLaMIUVgqT!idP#EnKn*-M#Ay3U*(IrxO{KgU&nw`jj5b&M) zQa{rn&*>-V6ykufOi`%Zm8zZszp9c6X{`2$=g|(pT?^E1RBt9}P)DyIz%;a^T=S&#t%lc2bg|Zfx?l<>U_@I0whQ z=y}My+2FUZQO9=&*l-)flD}Nek)SMDSWjo4kZG3xMXol}vl(xWCDSPW_=^?d?IxRz z&Jorw9lOd;QJINsWAmwp^)Q7~qUcBMBlCO4GCZMP`wW=pVTg#yoIXcmd-`h(m*%=e ztv|C*Te!2hN+nV{;Fm@VWIdf_Z_J6?!=voj2}6Q^*fsXZ6}J>`>?rN3*5IZV504WC z$EZI!xU8)o2Ow14WE-DNi$8J*l`6O0ZL=F*qmr9clz{ZQG(J}#Z_HHxXVU(NiKDVr>rq~2)*@!zz3kzq!a#DTe2YGGsMolM(i`roQi){< z!avyrE*d>&0OG#R3YtjXw@uN;X!XI(iXpWER)G8n7Q9{Bl6q^DGKN5Xk;qfc@O)}+ zU@lF99sGZ?EjWysvT2{t2B=LrIpWDP)H@5BrN*L+q~Vd#OGiNFJBz#?XXJvmd2MTM z8Y6+&Z1kQL_RLfaiYmfGBv)k%u?3{K54!l)1+%0kYZ_F32jRmGPYaiOwp`)Vt6 z%UK@WQzvHKEo_P+P^6xh`VD01Nv9qc;676iGOmfhBX`6xb9}Tr_@0{3#>wS3bjk6( zbS}7%MrO#z4%!$ytM=KIO;+Q4Ie%wIWuYsxMkx1QzQW_jeH4?cW z8Hs>afqdwn>+$d`*X*Q9 z(oiENv1T%-nM5KKtsV>5+Z7qsYB##|yedo0*wCCG%|3({M8PC5B=!Wcn2r!JOn@f=_N~Kmgh7d_u0!95(%Dg7oX=xfE++uGmwHGN zSbEo$d@=i{t+93soH0a{PxI6^x%(aN=-?l*G)Y+!=VCo4Rhi6nTKAp~y@PlynW-GW zc;4^#=U}Qlr#?y?VGg<+0r-qlhp_Ibw$E(7gm(0vNLMHxu|bUL4o5~SxE)AIZ%G_j z+eMMi+5!fr+BEfgg(>#>z`E-6s*&%)3RiMaZQ<QKwB5hLroE;S&MXr;SG8id8G6Oh7W+Ss7ioo(HEkHuOycs!)RaunbrxT~OlRPX= zTNSQLAm|hSu)mOjpORMr5C1lCI|ai{o}h!k3XC&PGB8Kr4rN~53gcAbs5ReqX(#jE zV(>xfL`Q?E$TlYO0Z)#ieY--Kyg|QN+VwA&6EEQUWAPF_Pk8UBNhBDVSwdT#5VNw5 zncC{-y5z_(zYbZ`2)8?lI$7xvfMsu}_-$SG8jV1|VPEERkk?=^uAg#2UUsbIsa^y5D+k(NM7Il0l14 zt@ABGOHYO7j$qb@hg+NBVu$A=;$6q z9im>M;{;&V02cTKw_EyvO9-cFQwg&7!ICTO0QTzDzyzPZI0f2)r7!MvWRQ|oU-=&n z7fA$YP-N-7+}N2u3;5a*Lg}x*q8&O! zZFOg5WsUu8;zmdNFz$dmI{;RVsB3)DBS{AnZ#%r1gW5AhO?a5f>}k*=rzLODKwX@I z?Kh`6hcO?jdTvxZYYVncGiubCGF|E5(6IoqZ#U3_Io#x=fi&w(eTz*;)mQ(OQxeWH zPEvO`aT_c3!#>*(FRQ%}1<*2^wQW-(WX5qdIBy5Cp$Lh?ex4KS;>BuQZ$0?ruMJPU zSsrEEg3UF&Ku6sB5rA)SZmj!Eab)V$Zx)j5vAL%TLiQ)+6A|K?f7fe_DD^pw4*5Px zqB=diu+R*n()0GF6^{jHwGIav(hQczXaOg*8by0o^8pv(V=VIZbV|GCSrm&Y=_Hg& zluR(=rP}MU5!%DZ%ihv$3@>ksteU%{q@=^FJb52J4Q&*rIf$COGme}_G38S55`0u_ z0xviu)in-z&+#RXMkBM4Q&y?np4~k%gG06dtsNv|z!8cVv!^8CXU#8^oEM3qB$Z^@ zho$COygG!^Q-bO}>CZWlEbW5?-9^%vdWsrE2`oNg`F5N{XvYQ;H+t8WU}0Aw7?tah z7fc`!@Tc_anUMSbEyS7*LMz@z4M$J>@#G zK0a~EeU0f4p3m+3dC`t{n=a$N^>?L3n5m48Fs6@dM#nBve>!npDP`|y#CGtJ#TjAx z`NSP5!OaX%(%hLipYEQKk+(4n!2;J>s;V!w=Q84gkjs;kCcKc-&D)U38Bedvd!XV{ zkK860iJeLhHyJ5PvukZ|RFtZb-YitDChZij6O>-~An+tRfbPjLb3+M{B`*|vNW`)2 zo7KpfIX-@JQ{jbdWta%N2gPT{!KN^4P(F6|ryk@nEPI>(>*eg&UxM9Qk}Q+FR?;Sk zb3Odmu|S@1t&4W%smisjizCC#x$;XwkB)@rjnIwbM7ENDcL`20onAIsaCJ|cBz#y!6!q<0{?!<16=K20DwA<`pJF& zvt^dnZQJ|QM5q&VXGsk>QSz#v0^0yx9;e8~wJaqhJoT@KwG(})z9kH+bD`v(&*Rtb$`pg~RMu3kvQs zPdRa9eWyU9669NLFfoC2#1P`lSVmh?@+~eJS=p9q`kK@=)du(0anL`Z(sfLTEEM+pd|??z@{cxOjss z|D-f&bK#8%5mtiarwh@{0^3e}mUw+bAZ8TpO!K;lFfxr%nQ61SfyQmaaTey$SWO1% zNDK@&ohf{GOR1HKvj=U@Qx9#3@3+TT_Kvigm8}$QC_<}EZoN5sk4pDJcFkDZ%K~i< z&Zo!SFg*4=7J55|dQ*)RzJum>ZElJ{T`v z6~I3?dtdDC5iO_yo@RGRZ_>*=_DtjmF9x9 zz1>z!0nq}8X$~K|%kl<*ChBa~Km6)%9RXMD>`2WZMlc z33F6X3dS2BC5zZmSy8bLfTZGAMfV0t9LW?{XB)O>X@`CLT@eJZJ&R2ND1rq24o^U! zNUxXRJ;#o4I|eAIQdsU7A~nPt4qQKlH63_6yh6}tjhuS@=A;Fi4j0!;Ks0FqM&8kxb zj~dqM82JKRVLEVGLnwysogVZwX1*!1oMXi4q~t74yk5_QKY*8O%~Q0Zg4P3o6ds=2 zwh=^R@Wea>3TJS-l#HH1;Kb9ctmEbgytX=4N70fw;9x0Aecf(%)qj26lSXjUT#qC* zb*kcON)&mwWpRnPwk6DeQMQVwZr6V-YbF+zOP!KGO{gXLh*eCdiH$LfDc%mS&U-Se zu|yU(GV-polPZfH&ezW7S-IfF>*hm(7mJT)?KD~``);AjGjPw6jjgw@`yQ@Da|Ba? z%m>g_P!2SJIiyj%O{I%1*yOCM_955HDZnHiP=m}dXqxKdZ8X|$BHly@g4}{_{AHhH zpeGSlcf*{q4>T-u>9swg6-eYdD+ zbD>ekK@FbJZ$?KDj~dnJdT65@@(*4{Cg=0LG$MPlCQ7|4S&z?13}U$oT0fG=Rdkg- zln)doS3j_@&Vt{adhSvufn7<^wdH3{&FR$9tcMhwO5!nj9sv0G{qhbI1n0u7+z;p! z@_rUL3TgsPw?7{2@o|03b2<&luq%`kQ{&9H6&2B$MFUM!{>7}r!A{Mrk`+N|9d{8i z6{|@e$Amuxzm_>;4%+J1tX4-{8dhy{9}<|aHGu@^jr;dN*iN0vq~(9K~BV3E~Wc7Q@;LyDbjVGPTW z=+q~c6zJ%r)v05TLcb_*^m5#u-ZwtASV#}0t#s~26+C5F+%?w3<<`bMOc8>PD70s` zJ;+nZxS=BF8V}#J|I15@1o;h1#N~&OI0*NoJ}BGlc~ONRa}+#=o+QbbwU;)Fe^%7l z(`zFy>ewIbOa<#H!BXLf&hqQM!0NKPEzM^ASRFEV;SNXDF1& z(xyHR{#vurRwfRbtqVMMF^cjtX@XuSPAD-y=A()@r2q@|G4UH1CdBiCG~uIB!0q*j|x8<}T3|s2VEY&JZG%3yAPb8C`@KzVt5f-R@1lAda22~7_+tvJ)M=11K z#N6%>0}8Kt3~ve4gz*fFgF}UBmY!N@;me>SU=pI(&arYTd3*KXIJABbfr{BYWoj1b zdbtz_1r3VKypj~cDSl*%dB45AT>@28oKjz0k5 zCEK>rOF@8jPbTi`>sF%a&Pa1iex5s1(uW!)ggj5JEiWAWwOMJmU(sm zl-HApD2ML=UD%n#Sef2BduCvFmw5{f+?0Ms7LF+iR&+@X#$X=|FD)3N^n3`=m9BGe&0&Q0ML*k{qK(FP%2yhN56F2m%bd~ZKv+4Rwky+-a ziK}}&(jmkgFzV`(;sXsLPSGjDfrHAb0ez(gJ?x&YwMl$v1*RMVfJTMzhXQ2ZjAm5b zOi9T>hy5D7IM=6DEWDuhn++w%wq-J^H+qujD@ihbp16Zk-j&&N;=F$Fed4mMW=@>X zR4`JK5!y{#@{;=%TD+=Ot4`AyH{+-Mm=e=g+|{r{V4Mm?*N!b>Caf8kZa9XcPyTGw))|tg{N7 zk;6L8x7!23y%3f*XQu?Y01KF<8$BKP6)(n@Bfi@uvoK{;Xt;rrazz${paP*%n4~bO zOFfZrKr3SuSs7Vp9ed`W3H3~YFWD}3I-M`4DnHa}n8Ji62*w<>+I5eRhkoQ()jq}5 zsH<)4_DfEJOnZIZZrlBkYGOVdZaBKIP87#HZ?Kxsz(e&dh+;z;V$0CkVLpfnfF6@o zEY^@A=F@GC-y}(5jyp9~# z00w0s9l76b=KeGXYO9WmDl*e;*^G&<+fCAmX#no-gfw&LN>qB6)MiN-Mk>;kpweMH zt$4MsIkT7RJhm(r!SNd=+8%d{q?K!q_8l%+Sm6NAmhhd)0sQnP zWgK^4e>S9L4o9J8$&I}3wmMU%-BMC3S+ovqKFW!XWhUxxS3kKpPhN8;ff=>Big1Ua zguT=^dG5$vMas)A2BQ5{+Kp33wU7H>{-?h(XT%=BJn+R}3Cq(O`9vl__O}qan)w=bmya6F*?K&M|&qFV5^qj-co%1$z8IG@Z1Cz3~6pgq&=v3zflI9W(_N|uN5uTGxIr>h}>OfP3H z&Xu?A@e0^((syW$x8YTt+Lwi45`^BM(uKs}ECE>QAeYPaB2@UAbfb>sl6~G>tDeea z=qRp;v>6!lNGZI8xv!%~%4drpnppMsbh>s5T5zsI!p8aN zvH^ed#BBkxW2~b(SAKimp19+wDA_eO+LbS=$YGnU(e>NND3I8ws7I1e`}Axe*Q^gc zAK^8N$&YTzns>B2X~MZ+zuQq%cz`Tfsg*ptOdf+2repD=&kh9Z+rRpQb zF-m#apTT5CARIKSlDyVXdFH&YS!lr-rP))n(IKeXHRS|rAyo=>NQs8-Eqd4wk)8RFKn@9y zl%#|*O_4gO@@%Ku{SMRLkEN);W0>yug~ANr*(B`6VypD%k+(I6&f$^V#1bi28z+;g z6O8-e-S&CQ5*?eI6k~_8j*Ug&iRQ>CTUVYsvV@w_Q!8lQ0l>=rkOUj9ZGy()`)vRe zKECX_aDKDv+Wz%*--Pba#GN`8a>3z!SQ$e!mQK{Y>jfp?yb9C=!fizaRl%I%R1xZH z_mZ6}poX$q+Y2k+@Ar1$VAx3x!xxUhG>#zCLX4f~PE9!hwk^U8jhoJ|_p*n}et_++t1qo|w4u-O#(X z@NhKxlLFC>BP>5=ca08(UtB>%llf>ow(qz5Ln`ePZeX&*j=^b>y2i5|ifs?}OwsIE zm~_y-J++yc$3g@@l+u$_Lj~8%?*(D?2&Jixb zbm`NMV>71D0uqj!XZTg2Rm`M<*&I&sFg&$B2-1dkI&JpW(XOg*m4EkF|1y<^Sk3Lv zZPc(SW_RS$QVxn3Kb`-SDjz(_pky4OC}C_eAfsn(2~wh~D@+OrKfi9-9%AV94Z!fZ zo>`QwM2hMAW){lsCUP&g)S}&a+M*0?iHO-1nWN*00|Qd@59v1sLaGap&?anEiZoI9 z4#1Y zIS@;3jMx|%VYPcc+t;aAV@M5RR6Yhzk=vd*@@9dv6cTXi*~uYYR;b?w2U@s}F&p~X zqBjbJmbw8>|q@gAi-h85aiu20MfQ?O*-nOG~)W;_&WR6d@ESyL^Kdx9aKo!1kk^ zRO8h4A)0}+HuUmX_JAeLVsny$#Dz4PjnMKf_w>uF0m|<*4|8 zf8a}|uF%86=11ojj8}s^7bjQOY%FGmTPJ7fCp(!qeaHCBpJWLd#-M5`;!P=@P0_`n zgNXKmScxUi?LrEI3}aV=?K*7P@;znyt8A^^0c<=M43G;;0o~U;g_|Wzlw3RU?CSQy zAvCBP+0?b2-<0EWJVVBVDEAD%y?L5v@#$9hRJ?|>WwHyLf8V-|2Sb?|MJFYc@7#ue zsB!{T07s}LSi^P^dm5F7qIuvhC4<+AYrk*TBw3tH0X%@H;8S-gNL*z%xs*aD2?Qq3 zv&=CH^xR7yxfg5-G+qf+%o44&$1Xk@@}8kG#}N6Z70_r<+&#j*+@j8GT`s(H2iW{V zb&X{cnXBq7v+=iuck9s3fV-SK+$q53VkFJ*KdU!N-?NKVl(I`7vb4d$HnjyHNW+k8 zHLWCfPVT~vlly{|hwwvTLK|7d@p&JUHZD2MN-`&n$Oi#w+QjhF|hWq}=x|;BX%jC*gj(m+K>y8cuAfVLc z8L{Q0jM;ts&;R~ktBQK=YXvOmX6BGi9v#U$xj8V(mhvX>0JXNLhqSwIN9Z|JflO^f z)aq<+XpZ)J^tepY3eMd_5nZ-5$#HKNgiVy3nl!0LU=lJnqe;H4#5lznrOri6@rzLf zCDoM1{3uiHkdmquAIg}TmhI`<5Vc1eT}TB#x1=nr-L1lbnBDh%cXY@uDVB4c5Xg_fj55UiqPWN?p z)6TV;N{8(#H0o zhG0Wq*Y788^v*u*zb*bvdmX9~sZ&}yB<0BAgzw@UaU~_2j|N&fG>H9_!U1wSt}@A4 z{#x3IXX^ZSE9SX~hq@YNb`IAP5tY%K_&8l6k`?8rneLlaWml<#Dit&Km8zqmUjhN5 za&zhn4=J(jBnHn4N(Vx66sJxMcJLl)erK)qbAqto9K+T`n|d2-2Sbm{Xcfxorae+M&T>q(aM&Eh04mA8vHr_ZD* zTmfKB<$w3s$AK8ZYF6!tKo8U4j!wI17ITw^2K7LZ4hPlfhvp41>QatRAk zg>j&!{CS&uBXPASS7le6pD%5>K>$n6CGd=@!>Ijws&8ofh3FChkEt#0udj!FRvicO z7s}<^z0}Bto5g=<#Us1gwsaeW$Jf`r9wMr3C?0M2-rg>Y*cRTV77$w~ezf1*&4btz zqwZp(Dk_>PnG2OvGA%;<9N}R!Irg>#Lv^L>t0o13c}To;R;2*t``P)j%Soyu?N0`V zmtaK=y|)LhP}jhcPQH@AIgndqtB{&(YaQPg6BW zI#lo^At%rnIx4bZrb%$Lfl~sFQ!RU<7x%LJCO&r2>*f5^o1&DyA`g}vJc$mftdUf2 zY`Cs2PoM|iLQ=Wi|Cf0;kB~+v??2v(YZCY}tKnD--np^RBCfd1Tg4KY#nDZwWW6Ou zWIvjGS=#NPOz}y(0MhU7aAP&aii}zM^|Znny`4g3$H@ZRVR!;&r|AriNj>D7D%LO? zBwZYuR{7B4DxlF3jwF(0MV5ASK_6w~3?0AZ2&19JEAQI2fTxlY*BHtn$>5dh?1=o+ z=$j~HPsM{{mC^|=#mt1ESbzL@H$w#YFH0KQ6wB(w-F5W>;~bgQ>}$gJaF|g{8#D{P z_NYD&DOWtqOv&aTf5W*nCo1|K7t_8nTF2dT%K9){F}oj zb`acDBgAo~D9|JKT)e6lYR1BX4iU zP*^1sW!reDN}$KQEm9E}-OyjgGwn4rAT_t2cd?0doI6Bq;_i=w8!3q>jt6gurM(1d zZP>`16pXjfA{QFm*?!S)9;{Zda;1WboqFEj4W*d*rk#K+^l zfWxs3?tPr;`(EIYD0yfbISQDChCwNhM>TE|DUrKsM!iUOB71t$0!;)(9hv{}Km1#B zlW%udHA626tY0+3Y*%||CT8`+rYEL?lnJQ$LjWTZ>&*nVohHo}X(bqhNVT8{8O};m zTGDD+y%Vqm+NTlWa64iYFP~~O3#aD-xf$W3H>qMe_=Kt&MK`^ZWZ76;1?|bXOa4PAl*&O#zommPa|dL3qQtEj$;Ciki3O zT`Rpubu@}B&?i=@bF$Mjti0j?tmUiPxU2%tmX`X9sTg zkjNtuqiVqao+hq+zK-y@j7O`$cCC-ko6#TWD5&MPsbk1V;7Hc8BdLp{PU#UW;$H#4 zyk<~1x{il*aYd=$>hEvf)-LV!6`j!SiQA_O2H+TE0xa@cOac4L;Dd_mOEkWUBAVwg zIJ6v9riPqIcV?BleO#N(_WHN?D;QZ1#iD(%^4HRAL7r*1p2*6?%!Ai^vzO0vc|#}> z3&RChw>W+*Ltk5qAb?VkkR5A#Y6}+Qa6KBvQ-L>~Tfcccck4`KNu(>brA9mLj?+_9 z!odItvcGR{*J*N5Nmv>sdW||}Zl{UNl=r!9TW($#@>RrX0zUV9oBg-9H^=PPA^RrV zCu)(DfBSF#q8(_6u1VbaK%0g--3Y_=^Yf%**B;=x*Mn)9Mia_uTU!`ebjl@zY54)=bN1`yQsr$8^&t38BPczNYCnR|HZ#!~ z+dSuK>f3L7k`c)|385MGF=)H)<#`hz2&*ydK-T2wO8y17xMQL}3kHO=cZp^Rd*DV<%i)IiXe*I0k99SJ(C(8>dUTj08&F9Pnjvn(cz@gh zv~jf420Ke)U_sb8$(D49Y;n!P{U|k->NqAZc(Z(7jlb3p6YV)=)OuuR; z=P`tm53!MIrj4M}{ML252O>ZF9o>dVa3l1wHkTA@yB%6R2fpQ*{8Dw?u5Go` zmpK^TjwcEF#YjVK6-Yu;MLoFNrzA2Yq&5nLhl_okJ4Giz#;elkn&5x)um43l4%wx& zdh=TIk;edCpanGw&FVg2HrbW6x(f}KfRfwSZ86pAsdz5ZeEXBJ1Zj#|(P6+wY);&q zkmm6shJT{Nk6frI$e`pCB{jL_Oo(4}M)!_h!NFm*q$7H4{hu0vG}uK8LN_0r?X|~ zBY!neXCtY?EbQucr=+UesS_Pyh^B|Z;+uVwjQF(n;mMKRJ!u=)clR#|}z;_og-xBOF zPQ7`&1vjpFB)_5WIQMtCGy7MO^1SfMMjv%aFPj6Ll0&^AdS~P(??WkcFETsY`Sq!dD<$Sqk)a zHyFk|9}SYU5nSy1&^oF7zRmC3n;jQ?IvNHT#u|MlHsJ``z96H`Ss{A!98$MxkhX%j zm9)k@HTSu6RN#>K*iXtc+i?B+fA^Oxbj`|-qO(D>hKxZZ zS+X_DE7^)vZXC09Be%F6ePRaWjA4Y+2dn*AG>}T)7SH+WQSk>kzFx$70{5x2A9c{9Jz4gACuEssGh*NhP ztV=J*;=sQ9GC0KBx-U-NDK5GuORb;gxtnK%R|PZe#b-jT3ac1=4^VKzN!k>HYk~Ewn)(uIAf}3BnYe*MC8Qo zMIPXY;t+-43=E^O=bMp73Xav7Qx9y)b1W<>deLq!eoN*t>t5*wzI1=0QrF3KI+p2( z8#GpUEty@}qYG*Xh~M{)f5E$i44HyczPJ6=mJJ8LR1m;B*>bwwOq1xBU)}&sK(fDS zFpXV<8IXZaA0SZAI(h4*EssyOA(_u)=rxNWd5tGs9jD{dOnx`%T9dPYn`cF`k`g7^ zkrJLu=y)8EjJ6Bf;6UlFolBay)x2?M8f!qB-*$bwrif!wmf|h7&|T929+zyrhRj~F zUE)j4;iMk*{{G%W{mA3VeZIKrdNa`f>M#G?RKb*Lm{mzklx~DeM>`)!8B0wH7?Yi` zYqTaAy&|8<>-PJP&##1+60lA)J?rY?Z8R;GvGX~Q|5DG%Cex;gVY(SgFd5{~5?+8E zL@U>hjbi%tsk9(#+^U+ATV$!9LPCV(40leduC2W{BTUYCA2nn*>fW&eqHkvLr04#) zFWke3fJxxQy-$>kW{pzvOGFpKBO~IxOix=i76y(bI0Djx*NM%E5+vFhy5S`Oa{^k; z)WY}dkr)gsJa-+31^$uIJFUY>y$Y+7dhp&zTM7nQzGsMbr4g^v3^A|VTPq#OGaR?P zB@h%4rHt8RmVHKN>J(+tbe)8P_YH!_z2cJ&V^n5#ozPqR>q8KGypngZxoqN8PsYM$ z(VTM@{?rf^_V!{^MX_3?h3-i(^r?rZ?0EU|Lbt&qmiI2; zxH*7E!mI}a^^lG#BTzUHP#}dAE$tVpnt0oU9VM2@%O2peUQ$M>4$lH`E`>}ESi2JR zoW6M*+y#XZGk#Fl2g_!yt&m<;6k|PNbBHA9uA=)?m)=z>pqF_bL&?$5`YlSix)~jM zU?ORQDKr&SyIM)>TSiEzl3mH1K3=KO1EEc~XZ-ZQ;q#rH9A__hP+O)E-H#vdS<+0i z`MBS`2~kLrmp}jKf6~UJ4P{&OLOmDf?8`GHN0BLZulv&Aj>YQvBZ-EBb3>R+E zhQ~4YB99UyWW#+?K1X&n%rPZt7ds7g&?#G#%NGVcMz9tl!NmxE-zVpHo=g7S1$cF$_`PhIsqEvTax&zEg7S?7)&pyik+ zXONuQ-L}6%G#H|1d9OYS1>D2NRPue+#cQ9{e3V^ms06^GP@#z4&I}bx?P#NzDZ=6H z;P~jnp@wG{QHvslfE3GVCl|q}W=r4fMyQcFWfP{vV#-Xn!}a04U7+%}PtguHt*ZOd zX015{U!V6S!`?0#oarx|a69ePYY{J1buDl2ZwAR<7HO`s?*_UziL0^&j0zcxW062dmy+jJed2??TJd?Nu}c!s z1u3biH}H17&;Y1!zRZwwd|JLvaozR$_8ZCfW7X_xaowIsr6Z*svcWAK+M=(@EC;Kt zU%6cN!Oi5!U8{sUrf1uN41tAI*lcmY8@LAcMO$F)0pEYTF`4))YO7{hn)cx254`i4 z!lU+a@9)=CR;e8mDy1(7sp}4+#vH75F^M5P&O{Gyu&11$?Q`GX-%xQ0GQr?y?XsS| z0EP#!Q@XKGkY5>ANpXic&h3G}48k%jo@<%4@j#^7Gp}fgTTe4VO-oKcJ|3=jyC(TB zNCJB#^3P_!uH5$)IY*v*y|3U>jhd+6vsIKflFxFz82G`S_Ayz0b%hGt=IQ-|0e#Q8(Mqv&46>ETfd9W_4>t zl*>vA#^7k@%1qSxqQKi8w~fFF;Z_`TOL#3vn@b77JoF!C<;|qLC?}YRmENl>8@7hS zk&XpuO|C-AoP>)=9}qD=lA#ofQ!T^^16%DA4kfayU$^afQy(b>uU4tS>8={`OWsMX z+4txqViBsAhj)-^5!jFSt2!v`Ni4qI9=H2a0<*!(up=lS8!k`)*y7OOwy0>iGO~4} z*}~eMNSX1mZjNNC0=x^HGrF{mK3@Ck1Z-Ah7JrHQb8BTaQtrq|)TD@vDi=nIn5Klv z1eraVtrwlr+R4>>MvQL1{VPY|BME}BYxdE*_p6;xE^-qsT~;A~i%x}8G*YMpH!J;; zU=vb7)oPb{J)ITF9Z3dN*yK@;-YNyN>xt3jMjh#Zh)csF&D2GNB!EtCoRhRCv8jKYxWxU%)wJeIs78VJ> zE7U%)Fn*X9c-(etDapsC}I*?|z}7DoGsF)>X<^KQsr`o>KG(?I$|tItp6{U^)h%*0ULy zqKa8*ak+b@A82rWj4Wf=-txnU1|zywKSbZWNE$x4^!&ozW?Mn zmS{Dw51oiUDL*o}T->~d_czg&)NrRLGUPk`y@#4-CwlGHP^dTxo4a?{ zt+c=J3S>UDKA!Tg4#KNfK|7>SrZfQ~HZP^!?OjzC(XWixdX_jPG6N`izQ0{Z0VJfSwtT7d#|)OJ{3-`;5Qa=$&=V>bh}yW_s6 z>SQr~=|#O*Lm$xoI|vM6LDIWn7OnZ8HLgPz=3o8AKPQYuMXEW259xmrT#U*;%#ss) z2u?q%Mo9@CZS`i^jTlXt@ib-NOeHiLiLW0YHwsqGa`}^YJyk_49O;jTuC|pjw(JgP zk7*<>htdqRo^1a%xR0J((ha8oCRc*`i}rI`##97elzKkNlUb$I1D`c}ivRlYNsb>V z`yf}2rEgYGX^sE6eObYY_QXZbAR1O44I@*&lJgvRiY6sPWw-}c3>^TP-au;LjKj;U> ziL0o8DnEmUWj^6I1s^?p+m#bkeuItxamu!dgL!q5e-w#b3jpWv_t(&2G@};DL9^!O zZ5b>_5`FU=iNAJ{Uw{3i7<(1~$tEs18kBLSP;k9y;w=57^HSqr#?C=n4uQA!ak7cg zWL;Ki4=@kRg6I}DNiCKhLGHZU;GbtKBPRyLuIH9Weyr~MD*}*1as|`frPW8rmDWJP zZ)nb(1LO6bhEYSPnR>XytA_}V}<9GS1Y+U<6;+k3kJe6mrx zwSVqyJ-jvBc1X6WMWmVR^A3sWG}ogIqx&&*-44Y*PlUS2#_TE!oSKqvo1rytL=Sw+@|@B=v5X1&d~A3DiEKnQ|9qax(Bbx|3QRC!_Pe zIUDb8`l2QoCK~w4^=feh?KkP{)vSE^%fI-u5)fDL)pw(lTb=4lC(;K7AAX$=7eW;W~u7`qCO8h14_wQ*^*771Y)vE`~jP|62gq0 zdw~Si&bM`4>yc`(+xSu|TQ-&JIPcZ{?zA$>@1via9C24E6uy`R8gfW3iFfg0%M*tx zqmyVu;Z*Xz_uX^BO%NI-YM`{}w4HqUiHL|oqxmD&d0>_DHRvce5Oo*WR%stsfKu7y zMc)-uO9VqemiUlTDUWmwab*LN3danoPM*Wz}6 zsO%<3b))3#RnX|valF9Lw`OxAHM#>%Z?Ac~UMKa$Nq~S0?HexeP%O$cG|~mjgA5q$ z&0PA%q;%T`k9MF#ca%W^r}RP?EpxfRbZ^Vg#2h3dZW;Esw`T4f90frdSdncSlM?&o zmv`$fErkOr-Uh9kMsLAkY?8BF+c9gg5aMS{P=qUEgaxAAFKRz>Atw$a%ubZ{;eYlg zf5?i(pb|5hM6daVP7?DDDbw`p#|PTVWM}B@`1N^1lupEJ7nh^JuUN7>H5)Ux z{d{ys-#y<4;<6oFyFuR{*o84V#+H&A1vR%B=;m#8)bjQ8Uk!qG%!`H>2HH8gAOnVR08kV?-rnC*4Ot1IMH}f9)V@Q*c+stDQTY?ujj1m! zBLI(O+m87?OLlyBb2dn|WyJq&e_DlUr7R{SsQJ^owDa3KsYm~(Lr~Bgcsl_MdH4ZY zsJ4gIz~Ob`Cgm_;n;g=%rNW{GyXp?*fD$7_%z%hL%?D9q2#^DN^?ocB%|lz?q@S7( zZlO(3S4bmVCD>-3G`*j>(a55fXf%m1-d!RuphV80;MKnW>%abR&R(Gt<%^UnA>Kd+ z4M2i7FdhkP3w;B~-%ZLa6LI%|ttSt{+4C-fF4uCRih_`)cd`)IzCd>$>APO(V2i?z zi%Cz&R;27R*lDZJ3B>kZNy zfdgjOBT2{o*sv)0HEi|Q9RR;41VR<>WEsHo0oRR|d4eGuB2$fjHlF3<eQH1@7$(NP|wW9@^Z!S*CA!@l{>kfJ(2QKlaf6|UIPWzfBChxL9rp;eGgwej(@ zm*y^q}gy1I=B(& zwg5`0Yx7wr2Y8-^F;O>ywb=_#z6%3rSO6pM*||53Q-bf9xSMHg4uV3JM8f>~>qnai zn95EC2=%X3G8$^O(p>vXamv&{vu5=+LM+~s$Zf171~Q`c$Y$6#nrm-ra5QEJCC2I5 z`h||ukov!}EmlrcqiP}~*T)#W?3SHTb!J@cd{Q2q;@P=tj??ZR4zu}ZGA0( z@n`MHC7lsXK7@#B2L+G@B%XurWjAf5Ip8384Jx*Xv0Zxx6gGA28*5)1={%yLt9)uSC;P0Q zM^C{s4jWa7;(hD-M*iON%y`)Cp+LVmez|#AVXteCBJxhXL$(MZBGK_MJXVL7Kx`$K z?d>?_e@e0U?j5iu@*(cgK*}(Mdz~(A(Fms9maL`TPJ;SZZ+#;9$WE0}+E}y|ALSj` zGPN~&I_vps=jhoGS$zAMgVjSz}v2qH4DGC?mjR~1&m zB5l$kj|x>aE`oO5Bxaq^mtIT0b`#f6If;L$}5QjwNZM3B*J(FsOpe)Yu#Z!4&W2y-)1YuB!W$4g5 z+=Y%ns?^d`B>IO?{v$Y;J?PE1`q@ZG@1Q3F_n{Gr}^Q5rL$ zgk+hic-_BDMCymRw4nqi(6=e~pHI?RT%dHd8+)^?@%h<*b3PxZyV~YXSx7Va+?%ac z_JXbGTbKflP$;~`3QVf|39Bh0HIaN6oeZrB#VI1<~of&G%S zB73zxEN2BL%!6Y5>H@4lqe4Dy?^Sn03ecq|S~v`(f#1Hpohjp*e$5#{nFXGC0f~!sJjgaO={fyyIQCR=@xG8}!ZUMej2f{ObWIXjz z20|;+b3^d`{tG6qE#9}wWr{{W&>UD@MM88VN_EcXwj9VqP|hVJy^?#T5{RIpmLU?` zNTAwzbj|*UNOE&-LvsO6wt^=NkVN&YqME42Tq(PJiRX z!IIdOhurb4NnYV)Lu$8N@N_6vmuL_1`T5z*nqX05bP<|TuHe0Sg&|~$BBRXf3Z24a zIZ4wSnQQv^{H%umeHZv_yWMXj@irCNYP5@&J6R;!gBMJEISChg3ZVi&>byIFt&n^B z+#m1nWVCV2sr=8D-_g-NG z&mgoA$3q2HGMMYSy%f8>BzXjc@Nz=-U>{X9n_Y8lujG#D zO{ENvWksjRTuZ>debB1juhD867kYm(D}pN(X?Rvr=bj`LMOe9u!U|sH#Nozph5@lk zsh74U5`TRJ+QU(SSwaThI~6z=aVu`7qq`a^4KUHyHDx*5N(jKBjS_es)aF3W9o_Pb zi0F`qc9yHseT^<$F2dJ#!m>V<#au0R+j;@2x5KzC|IY+5UQZhw>lDdFm z)-yXrEp-B2=k43=<1O_xiiwB*oP63{J$ek{{o@@c9TkM;a&gCM);Cc%TLQ(n%D7v> z8BDs~h|q$B>QC+MTXx%_VT!f}@+^JgK55CpuB4gEDlwMHOV&CdRg^jj6D>a740QcW znM5IlYx&oXzObqDI$KO1v5~@VuKV|f6(thQ-rjfd&V2X#+E&@y``adW*!4A|-7x1I zD&%TcJzhj(zN@>b$2zKe*_HqNfBa)34XTnTnDD$uk%B643T$P1A%xO*r;WyO-Qo+9 zq;2SLU!KG$DJ2nv{rD=hP-%X5CK1NSMdIq?%UsWHP@H!wLlbghwkk06QX-xu>a;k6 zfZE!&ebKOLEI)qvK}8sr&S46pI}Q!;F42h*5116B!|Y@G3FEbblif}4>1G~KbJaCI z3Zh+^Gulw@KXu02Cn{eNiT;w!?vB^|kPbjn@L|N5o}8e{uB{c|Un1EeKfQSlyKg=R zlK*(WdhaW#1W}`>V2u;e{%{jG#}hu^994M3(X41l&nrdI%vv>nu$>%H6V8sD(2k@u zazh=0{d^J#ZxdmmhUDk6JTS*6(>{F%EU`tiTqdrD-#w{=8sT%MLtHQx!5UKVLW3Cf zLp4kqh@d!3_QbG~vQL}yyXsFh3uzyYPQWp7drCLc(E4;iiBuB)95%9&HMLN(@vHX( zlMhtYZT7&DYmk2^3E)i8s=~|w#(y8RMmM#~>jk@B`yWc?41qeIxFo3PT8=@QXW}+X zCumr*1CEZgFFH>{>)EV9TYe$)Gz4j5OHGUHjEY&f%aHz^-~Dd#js%qmX_EngZ{dP;A{S|_RCH~( zdP)+>z~huZ{-b|9%BYCCy+@tVV&`H){@#W)y3E#8`N-Ww;t1;`u+Xt zTpJ;;c|nQR*TqHXpMXkEn)cPaQ)(BS(Q7Z9j_P=1xmP4+1o;}9(O0v_f`77t)7;F_&szw^DS8k3VcGU=8wC2l2q`~itpfkZ`vvPXvedasNiHoW zctE;!L|4JbIjD3rGmS1AmLawJeh(imLjrHq>vDGP>s~vdk4i1boNmRoR_wW)aMc0u zi2z1vG1{=Hg$jFEy+yY@ijTyy)PX2WK^3XrCXQ1u(lVpt0 zvDCz(ZMEwP0T@77x5&jX>lLE#%nH=m`t z=FOk7=oBuWL^w|uu|=#r>0&gHzftyDDQ2EebnLc+iYC9sTmIAl`B62UfyWrj|FH-P zjcDf%p){KqaTpWY@6x(rG*Y6Ihw?_zAtPR#3AXJa1@-I4m-8XLebOi?cc*cNw5YAv zAyn9jH0d@82fbGiMq63grx~J(xC0Xp3#kD$kK(8yBtyL}O;64x$o*o9HIr%+Hz?7! z2l|2>8pu@Lu=fdRqjGUd_=NAD8uUVW`ZhzBlfKlE3OJfZE9}^m3K!tnEPdwpqH)go_z z@N1DUAyHz$|Muu^VXp7T$LAz%G-*B3ufRiC%%e^?s$wSv?sK*!Y#vox#P3q)$o-zp zP}=0m%RcApO*}ck6)D8Bh>SbCT>54WxgY^&qjB)sf>^XU00I3#sZ024yvd3BZ?)1q9ifIGj2d25wFOCUk13Vl{Zobr zbV%L4(FaJ#C+0LNzymyOWW_%}z6gWGoSYC8B(FlVE0Y9iD^J`!#q73JyyKB2PZ8DJ znys_r(}VYd&Ph}+E$1+aL_5Z9khR35LU5;4!peA4daJps=(;Wv_VfBf!2@dVdZ@*9 z+r3|@W+}4eNG8T0-bVSe>}m_0CnfvjXE}1FjencCgYlt42>BwZtS#QiZK#s0BhjbE z_E!5u9e5@RAs}=7qI!kL2BtHwu_3H=rxy|z+?41TGHfBj*Y4pesU0Oj7l^*e24eJR z*)Bko+P_6$C=T$p#>AaXOY4o~6~fRrV+*eWzh1~ov{PU5xpbF5x_u^wkFvj1WkOa= z;S?3`7UQeRQA5jm8`4Ugi`w;nfrejLC9Jnq}aEk7{RP=Ph+>eAlxu zMVo|B7I5n{Vd>iSBI>)h)k<>Dpw06s!Yq^FZMV_v!$k-m5Ibty>UGX^n=+*XlB5pR zbz05oAM^07Rc2MLG>UJ$@jG9mazMZML_pZ@VbMMe*S zoXo# z6QK9fr{PBI?Glcm&SU-{q;ru+HtLOnf40Rv{`%{uG^j?QTu#D-FPTKn9tG@1HT@uo zVRhSkw5)|#aSD%>DG9ihH+XenOrbJJD87l+O37=3Z(8ez6gAlxlIGusA%v@GfPKA) z>9;4miYzDNMw^0*i1kM5{JN`&mt|4*g9@BlRinh0Pv8g5=@S)GsyeP|89h@BoMWkH zx;{E|-C`s35Wrvm!eUht*aHW$o2Uqj(MjotcH0n5X&njq>0BpZ%UfY`>1O_Tmu1|VQBI343K3XnR zaz3F2Z;OYqO>c@1P0rNa!j26X_-0L|?dX-7@%9bfC^h-ndox8}1q)q6@WAuWv^1pJ z?5ZG{aS|$@J8vJP)j0N)`T$2dK*BK?G<;CcrXTT^kjH?(Z6NyQdEhBW|6(JoNi5J` zuT^U3qaVNg7(xRY3K4?Y?XFtL`=(|Hh#wsU4#dOuJ*89W(bXpM7XwEZ>)$6CB938) zdl9X+uYdFhe{XlfRRQS?p{pE_JD(WhI8HxyMLTCq4@}+)E(E>8z-eUk_wn%|=ApMB zX%8-sa;51gC-#~Rke|8y)OoLOZ|$~eo&=%FAq|D6?OEx;HG0Homx_?<=14?M&D^8d z)pog~>m)j(BgDC8)oB#jMuy7gj45`sX{wTTdN-u~ zJlPUn*{;@nVZv>1kNpgte$|}_J5EgV`T1#_!$Vfc1%QZ%y<2WPDVaTqQ=57j{r$#% z;=-mxir;D0@}sw-Az#-KOVZLO^}C~u!wB1}m*_~b3$@5Oqb}+2TT$sKFczUL&(Z)A z4|A1&wnsZ?z-oJ-hV7{(yff3VDzZth69EeY+iv&f+)$7cn@hETT0-E+6x%xTcj5$ zE8S=c(PH1TS?8L1{6o+_DKd)TyO^K%CdRD7N9AzV;MQBB2|qFt4>fzX4bgQNb!pdu z+V=Lj&CwSFpwhY!FBaql4`TcMAN;-lCL0xd6Eg`65^-l`L_XAxCfs43(U6FzPH0L9D0>mc2f4(;~$@Q^X*d5cG75sZlQOsRp5(izHAb z!D@FHYI!M7ksR4H2ZDo_@HMJ1$P-k|7qeUR;M;fIo#(?306(@PZ_m;lQNLEqYcM_< zZREk;x0MRaiI1dkhBL7?@^YMfsW%U^7FsiCS>40v@pu9&MO?!DodB3e_W<;oAJOo8 zid9F=*^zvv#q-GH{=m!k!pC}QlW;NT>6A?pnt=m4Qqq9Bv+SbPO8S{=?+W8GCGA}X z;~C+<1!LRocnKQh5KfcaFxoR=qHx6Ci3a^b5%~;!O<_=t*;e4H$kOW*1EH((_2jn2n;E8ta19#RP@Hm{ z9lWLpbRheY^|52Dpf~9Xk$>lR@00gqYW8j+4?yi25e&4V5X3f@?#p_|7~H_l#ifLk z1bm_@m1Hb%y@-fRZQxn59-L93nE5!qBcm`u?);}5cr(wjW>ULC1O z8=xOQ-X=B8Am*lc=9e`sHXB2Gz<>A;{@WD!L|#(WRcWA{=IpSyDVeA>Gz}iP+d`y~ z1fud?InGk=kzBI;cRR;EKJTicG#}ow*zX~3P&;K70Fs|Ac%Me9|7{p8T2#+EquxE1 zbeRt!0$FF`R@E#4Zy3Xei;#Ta4zrlEIoF_Tb<_2kX!rT!y}9kX0qmpMC@GX+84W2F z540|_T`SL>dhLBfxr-5sDsG_gJnkM65v%8gG4#w5ZP~A6$SzK`KDDQ#080p>se?&j z3v>^Pa4#yB;!y6t#C4>!xl(ykPQ$N!l1iKsxV3n$zZYBYN@|p4&Swu442fJ&&yjlE z)&|2q*CqnJ5bq0<9kl}oUFgtCR+rJ^{7YW}kv~Cf*CRm?mr`EuEIa!kOHfl5E`&`; zJ{mc2o}Nmz#=jCzCF_oM%?1mt8x6Q&;6b2Ara4 z4UPP0EbLA|0Q0e$v z9%J9mDxHbgCn>a!z7$8}1R53b%K#VbKxn*snT~?<*_*3*D6;R8S9Pbp9gXlI2iGB~ z2k}j{{gY-P)5?@UiE^ZoIdSUPmK;WkG#vL-oO*ms|HygYL9AIpq!~Nh2+JEM{cIA<2+i^ z4?26FT`cCO>G6AeK)XZr)8mxH)Cz2Ga0N7C1k4(dak(o~Uz~1j$x4%|k@LtHVwmWm zMN?)FO+R&_LIGMpsSn7`hzs& zUG+*f^hcQDdfkF=Bn1DEmSI-3e`wl8q|`5xdls6p@2O$8HX@sOFYX z%AcE=ZqZMR?U*=~%5ckJW@Df>Exq0OIL1m!y5;<${Vgq2yG8bF@ zEit1S)i>4uC%_)xyAGzukl%nHqVTAd*vH89%tjtnV&gLcrUF5q(wU>|nM`--Vgapui3GwYNPWjF~RnO1dA zo)N=yHj}BWjKD(~5J{FlWIgs!E}Y-4=Mu~&s)*P}(brGe^93IH?w;uQGT_WC65bCT z@PjGUU7?B5FvL|fEMH`OT`m0Ovg&$42Xyf4fOcl_nEW6VS?}ZXi&hV`;+x%r6qZqD zO;qxW#2bX~`qTg655*Swq8}IO4h-(6f^@gt(e}yRWC?M!n_J8PJ=(XE)xmZEXZLmz zMpTpSVhtu7P^~Cv`np*_-$+yDVvHSc7nE?$?6&K|y9yk(pyhFX1^$7`;iAyo>1}G+ zU`?TsEco@;k2ZbnK~1i{IwufrDB1rpv`2tawn6{vUq9h)4CRRipdft~cij4$P>mr9 z=EQcOw_piC?q-Cig^{>f@@0dPlsMKTbGx{pM0v9QnJns=0$@bqG>v`M>ZSLc)L*AV zhfHLFyB1LKhSv3|ukaYn4B2h2`>KfxnnNW|MLQm9fK)&3XvgS`rz?W=S~r+`2wg>2 zkvWj6^H|0gP0JV%2SGN!zXJmdnGnO&QXoNlw_W*{U*7F`Z7!ByB^TZc6!&dSz?Nyz zZjz%Z)E;5(%0#P!qTS#KHwV1@-Ozwr-vJ9y$_`k?dsGggg)jk$p<6|0NG0cR%h~Bc za^x9;pD6~A9XWTDD!017D3H8N9ET@|F%zfh8Wc1X45rX8^liB#3r_MUdjfEmpwKc9 zAzx<%V@t|pKYe^luPcLVfWmRtv zv~bCE15(;tzI8(%`2Foou#KHWzZ@fDNW2@+;zDa+bhJwtmfb^ydY7;HyI+3LDjM7% zvSn~Z-rg>1=;b<1Umu^7P>Lo|La#pUP;cvMXP$jrGb74}yvZ7`67+Dq9FWYfTl1C6 zFY+7ik{Kxf^q>4gI^Ze`aYKBg4gU4*A{5cWW^)eA;K>czq>j^=g#wg!6oc$bqzGSx z$=X@*9wLz`h%64`3J4;Nk#=6_3fN%Rf#(SUEG z!%YmeMVG9H=qjDQzDb+IXrXzBT2ahLXNSHYvw|&F8@**wd!_IqM`Jlf)S1~#+`Ze^ zZQ1sYCPUYlbdB9wMVn;rW^yQUxe}%;nilVbVwMj5To5XWuw;%<PM zO)o0{hm^h+UpuBx)~a>dU6XbbVvLEycWyqM0PoQq$xD|Z2`d?Z^$YBUpHN$h2>&+K+Mvy{is__!Omn_q!j^yNJwkVIzH^4tXcEx7wxb zAo=_M-QN|I_0pdC>-Ino5O=RFP2pzN#3a(N0Hd6}wAWB;Lxt99{-b%0NDh>idmuk%V0PLw=a2FCI>`Cw5jlkY% zqK~rhT}yN>ceHY7;?y=2DGorUslDan4gqx+`f^#!QIexymu9RBT||zE**3~ z3G`SNcKGOO2t)R)dMHT(+-*YP*PE+CgY*oV;lAmpH2Hu@SNBAx(OvmI0PGB}Ga@=$ zj0(1;P^Kxl~ zf|9bkJIuN~(-aMpwLF)hg|^+!)eD_J*7 zyJM<{L0?LU$gADNg0{VhatJ_@Ylf5*^Wt1c+oVo|lxnVL8&+xHVj_Nde?MKGD1}bn z2z;gMEZ!fSOeHwD*(xlTougf3qrzEVt;>Xe`5NsK0)G zfHQ0VB7QW$^5gD}UJd3Vc++x7)$Gqgjsys%arJ&hALLys6Jns_BB+h-R4&uG$~S+J zf^55N7Tx?m{rZtW-J)jIA>uWW)HX;4Vq?ogHfwyJuJqQW``PEsljA9M9j&@ufY5r3A^p)7+8fK1yUg0C&L7I%3oAQ*7H7sU@`$U%i(NC#_J;LgQ&P*8+MPz9lXM`c&{oQEtLe@d4*%;u zB2%XpRYkPT_YQS+8(ezR z)w5&rER}Hp%f+A5H0xN#?>K2a_r2-oO~BC!BgKE7Gl~NNep$YhiF6Ltx3; zdNQ_%1Zv*i->aAvQ9Cbnb2x-Eo&}0X6bhFjeVyv{qZPWgR3oAb)Kwi=vKyhrte4Xf zQMF-=Mp;9on3Z6oo0Qs18W?;7>A*?1v@p^I!Q2=8<;M@=o+GxTj2P9A}lU{_rLzHJdb1T*Jjaa zD$RxwKclK%)Q@}cb7oKR0lE_du3|kACAAM$i^l0@49gV@5_~g@J=-3v5!ajA!1YW5 z*X!8I&9xxo1Tbq^v;DRwh~=EN0H;|Q?+_xRLKB4p25 zvIC18c%fex;#oqQWlPP|8Fqya0!rgV2(FZ>hOosPJ1aQX_wR3% zZZSRQ4Gu2xv9finRxtG>&iEbH$vpJZdakZF*~G9wDbbt)^8sj8U#@oB;UMMD1>raJ zCxfhCvk`|fC#jnzbJ;)LL{>DogK*b93-7qwfzt-l6Zffd=tG^0mLK8RWMI9IwL{B+v$^2_7!|LFu&nHjfv~l^o;#O9H6cE&q*LvvwH#{{YD$2qof%}FZ9|9x z22jMRi$|MdyF!3scwRu0+~Ft&U^`+(G6b-{NK(r3^N%fJI9;Ef*-@x>6GQ?@qUn+m zH?{*@a(At{KamjC?wU!O`7+^vTILZQ7@kE65@ z2bHm`HEH3V+|Np=CBTygZ($-BpOe8M^$Zau2_^c2&7af&7up4xFOq)RWO_t$t=ULKdYpZc zB(&HNd4jRzRUB`ZpqWT`T!22QQWhf)Dpf~gPa%{6A%`XtdfbOfoTqT=7} zb3nVXVmbA+{`@l-IyRjgKZ67tvCyS=&iEwWg?=B}5 zr8$MwhAc)t2|+}5jU_afrfe;QXN*OK1OBmD9S9AKK_3sR$It4k|-^54iECf$-K6&Sz3GcuHV# z4YRR>KnIwdxeioV5J*Y*m>R7#mMH!0oRX}jImr(wypks0NcX1!40Kv?9;tbU~*UUXnD&iHM`qK5kL3u#j9j znJ1I_YZ2V7Gp@m-cezbp^!WOG=SVRCq3iij50Hfqy6Aw9gk@YTFG-ALBTgUgb3Ld5=psT^@W9Sw6eqvCr;IwrUR+nsJl zj8tXt)0zW^NCiZ8b7(d0(Sj0?dD=PTe_g$nSe)rGAe3yYtm4Om_k^W611$qBEvt-S zDIKjHFg%M?)J^T{`2q*s%FSj%Xq%lqhk6EybLAF<=Asvv)&C@}-=5IG|E-ug*wben z0&{dVw`gTr4F}6ntY%AyA(y*6q&LM?gT>!K@M?L>NDSKeWv6uYNp6U`sxBe8 z!Ce0NkKZ$NM2>@7FGHfxkD+K&&g%G)F>(`x)h)nks6V@rxD^TusIqrKAP`U4{wY-X zF#?AVsAwAU)CzFE^w)(AMM&r6avD0|aFs5n?q=H;$_srb+JZj!+&Haz<@h z&qf1jyUp)oBzkMaXhT{2G~M$Ra#qnj$H z=fyXw=n$}-Y~K}eG({L#B+@`1;m1O%b~R^ZnNsp|+h213a^pkRG#9ipD6BS8p9LZd zYd49DFU^X-Xe}MkGV2`Xl#x)dTIj)k$fx7z6`L9odoD|j(L^r6`5cA5M`6v$&@wSa z@}O`bUy(j6XOPm)inXAb8Hr)rJ3=i^3~8CnsnoE(ykH}n`tl|DYrR4MAqDM5z+a~G z{_>3F(1Lz1ivIf6K#zn%OQD^kg01ZwCxH%(CmHxOHrfnVxp{>Xq&?RriMB-y-~RqrUu(L^ ze4FBfx4dNIrgaVDNZvtTZk5~ho8kPdM$P|TXX8JN6zlaWw?F|Y{Z1YfAkPc|+6kn)GGw$^-MUva+7w{lZ2TH+l&3J!%A0?CIj`xT0?agm&*m;IWY6aV9t=0Py zfSgiVIJT=-4ypT2g@B+B^=*XGAn6TEAU#!1XQ?e2 z(kRtgc%|HpIyH9(0|91=R8JRe#*OKoh#le}jsxR&=bD+;GMLs%?;6Y&F01Y=t}Z-V z0+KA-KyP=oC92svADlUPzGJ9|HUgwF+XhTMPU(M0GI`5kmUj`kXOeEde}8w=0J3S3 zeVtf)IZyCaG;$@);BVKRn^Dt$QiVN3uSMMu!pJ0xbf-av_gkZHYyzG~behJHc(!CB zRpd2YNr>^V$H_r{KnC2hs1VmE-JPTqT25(p0qX@6`p}?3FF{OIHx-{VO*X}zZXOMU z4uL4wEIYXSk3WE?GlV?`j-uI*kICG~u2*iLx+=hBHxYL@3UbHL&1aQTi%MuG1Xt|~ ziR!CqyMO%9j6J&1M?i#GWK4!%TYhfV(0{g1K}N2MqM?$Xq_yUbVxq8Oxqu8LDElP< zDlDEf18{0}Ll*i&Y9l-0u6g|}g(8xLFEES+a8}~{-4^H}{hy=_eZ5$@qzcelaE~^v zk4QOiG&y?g4SKLcdd>^rxzOUjKE$V-Viu-e|fW zMR_PAZk|nDvKA`dGGSvRLeWDf^tX={o2ClIu zN#%7xP!JV5ynaY}D1RHO=z7Mogt^T`{cw3}m=~?5)QE9!=@?#+qX z%06((5gzcB9?`?o;;!{*W~Xsza||3248aGI1L$+r45*uE2s zg0Y(QwN-I(x_2|hqWI7d@(}Lq86E`zTO-%8D{pu*6BOY?MZZ|P~<1udEaQXJ_Z`mA!Ll_EV z-kcrWcEmuMTQo5*Yw6@&Y~|gyS&$|*i`To*jB`CK>tCpivYG>VrWBC6$vJDSuZS*P z8B+dyJN}p7UO{~s9%x>B4%HAARiQNRy#f`OP9M(QydlomGB-F!n9-e#!8o~^v%bVc zVtNL&dLpw+S~n|p9;AMPpJwlocnY|FMp0{cpJT{W!+85nzv)pcrv=+WigHa5 z0en|Cfl~#W0CI>dKEt>^H#WSK(({es-mQkVy)c@nDNba$n*ejeZc$pDoTAikzp>`6 zPOnQ;w+OPHwN^&60Ka;D6LCH^GxQMp`EbXK2y2KMtZO3&Srq(qNl66iQ0z2G`Aew2 zQel-xC1xEB*cKI43t9opBvv}b0?}xV9h$`Xr-rqqE72<6bUVb%+%ry`UD5cUfpbx8 z+Wj9|#ae_x)>PltN9AfhaIrjb7BWkpoE?cC_6;@lA66BJDyM2->Pe4U#LH)Efq5)mF zEP^2&E)1AEgv%)EAmM!fIAjSCK7&HJunuh3-Cmiu?SfO=PN_$!W+h$Wyi4^zT{5>@ zbleJ4wvFvpXQsQ|=I(m$*3&Q0wkU*w=n>&|m&=@cv?fCmhPdALICVA~+I% zc4UZSH&^ct_BU~Jq5f|VuO8xmaodk)9&ThPUwmzk-{sJq=tie|&*Aa-Q0~XH6MWs@ zDiP)WMsf8&pJNY(J2%>E{qaO#+%|Q8*6)3UOtuGi)tkTX>EMn3dymWRbg3M?A5e!p z*lsk$+ipUe-UzMx)z+VD`}=k0^UvY-pPp`ic_jY;#?ZZJzm(rtf41JeUGoGy&)2*a zKNgOxEvVOD{_6dy`)k$zbs0Z!^99_zd7eu%`_@Ag_me+AGTeTwhcD8N0z#W0U(;P@ r=tr(Uo~ZmDCz@}S6D<$^SAYQkjh=e#+gb$b00000NkvXXu0mjfoV!*Z literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_bookmark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..77598e5c393173fb8cf6e811659c0a4d3ea75425 GIT binary patch literal 2919 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_check_selected.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_check_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..b44af9284b1e0fdd38a3f03beb19018ebe114620 GIT binary patch literal 4182 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_launcher.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..5219466ac84bea4b1eac8c20238bbfea733b453f GIT binary patch literal 2425 zcmV-<35NEGP)$ z3rtjJ7XF4o1_q>ppwLB8qrnFVBcLeq5YSpgQR5p_6pPjey2iL!H`&-yWmjr^;bW0v zDNwW(ciZf$t65VR+EM{ose%u5f@pbK^XP2lNlBf)Z3)lKitgl-#h<3-+#_` zUcU^#@*(?`%a8vr06LvccIC>ID06f3_n$p`=B(9fP3VG*27jmftWf=?@c&(NdPN(~ z(K_{(mX`l|^ytz4B}T1`Wc{p+j#fmCE?()2Ck>G|P=sx6fxgfX*pt-sE zf53@gc_XZ>tT1xq$V$>`^t^fVF7yXPe*l=DI&~^enbQuX~xT_8h4zRGW&;w)v zA3S(~wzf9?Z$x0?r-_M)AhWZxbJl_d3zpK?&c1@^4*+FSQc@n-ty}jUHq?NjaNPy% z>3h}@{Usi{fD06aZCjf83=8$OqHPH>Aq z-na>RP6$xLhYv?!pg$HbS_E%zZ=>HZ09q5)*4CU5V$7H^`H_*4(rJL)sG1TvRY*vP z5rE3dO2ox|gtWAD3{e6;BdqY7K?=0CYjLfj8AT79U~4}V@q70mGBQFB;`Z&^AYOqJ zItD-{bd^Xfof~BUPoF+j&73(CUS3{;AT0dGO`CD?{CTXIG6b=Kju>gHpq!er6#8pu z?ZA~g^*H!VB{VJO_#`al^ z*}>FzJ+u#t(0TK`-ei9KsTrXsN)Zw^AD^Xu3XTH@4jh23t*wwwj2%0+kVq^YfFnna z2mn|EzP`TLvu7_3{CN-l_TE@{4YTSJR0p|RIOUU#fVnj~i@(wX;CgNS>3g`S>BQwr z|0J`KWB2aeu(PuxZ)MNviL@GE099300tYx2tXds~>cR`iTI&KiZ9gkOHqah&*SYA( z&wzZiKXeV1(EfCTa%MBg%q)rw#}T3c}Q>Q-uwo{7QNgs;HMMa$h1P2HIH$c_Y;Dg;C z;7n!)7P(qunWr7x-d19uLXJ+Y4w|3akbAEI>G^edqHv_hdxW&djt0od$uZIZ)fm#6 z5Cfp-sam*jAvhlr2NxrsQxX@y_fL3OuE975OANO$L(6k5{{5&K_0(es2=Jr0@sUvu z^@{^Ic<^9uNlA%EczC!zpD{ESP7ThU%|dZ;F&Y{gh5W{OgfoK3+=7FHgq+84bO*pB zrc^>Y4p7+7q2A~ucB3&dF+JM4ILZ8wQNzmQ1)SjLn8fT1n8fUbh!>KQSecNJkV9tV zxpU`EY}vAC&Z= zkyy|G)v#W4M!+o)qr(eBVS75%5QXP^Vtf9{lP9=-{W`eQ$7E&`A}=JJ32oiFHJjQX zUfjoglfwW2yHO@_pI^|g_BwfScP=*Vp$d5br*F zs=T~BkXsa5=e-TyeFo9xg`_hf671{J($ZiSOgy~nNic3`aka%Ht*fi+Rd{Y{ab)N6 zlFkQ;wr}4q8Hp8i6dFe7S&4L-;=o-s?&`}R@o zDNT1;P7B+Rmx!Sj$nU6+W6gcgmkG%LM7PS%iY}DrxfjId)zz7+rasdq;?LjdmLz9n z{7y5v?8ubXQ?eF8ZAJ$IVM=p`TP+r4dT@pS3^bx6ZR%(O;PL#LQYbd382-G54# zB&U?(yA|}smaf5cQ706vnf|zAaUBNA7Yo}&7n6mB=Wals$E&=U7w26c(DnJMYw$WE r2tM{_!TY@PBEr{sd7pPl$_M`gmhskYYxV`&00000NkvXXu0mjf1zCRx literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_logo.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..943a716e4f4c7fd0ed2597b9120f1b068eece0a0 GIT binary patch literal 3104 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_logo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/ic_logo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..943a716e4f4c7fd0ed2597b9120f1b068eece0a0 GIT binary patch literal 3104 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/option_icon.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/option_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..004c41b5bf85431a2e7352627329db41bbef7631 GIT binary patch literal 2894 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/top_bar.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-mdpi/top_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..e4a9ebae11198155cacaaf58fd94fb1f63456b18 GIT binary patch literal 20898 zcmaI7Rajj?vn>iCxCD1yxVyV7G`PFV!Zm1ccXtWy?gV!Tws6W zFlTpvV~nbO?2b@UkU~blM}UBUK$ek~P=SDe6#3U@fP?w>!~`1)|9j!N0<~OK z9V}ekjh)RQM9myb%t>YJj4jPo%#F=FoyN=sARwRsAT=#lE&1q5&<6~hV{of7n&ziHD1)qw9 zj&V`g@DcV}{EXL4}1WM<{%<^7Ka8yn+41fz?my{oYYqrD6He=A6s zyO=tI99=;U_N4z&G&XT?a}@;q^Yni$!Orpj$lAO7?=bxf7_*15BQq-#%YT;i-#~f! z|9_~R-Ty(mxT=`{Uw{8UgC7IASdF7E&4N;sIh*_qqB{x{d`|8m*?NA7=8!OroY zWeIa<&<}GnNoNN;(*IgAALxJfh2?+L``=u%|JfJT|B=i5&l%?bZ0!GQqyKyAU-tZ` z`+w5*-{AiwzPbIsYb)*u7&dpV~=(d6Ebr5;L?H8c(P*%o-Mm zJDL+U!d6y=j({c9U88rOpTM~8;|keC2#GkyZ=~LwTT=?|>ckXqgF8Dr37^xSABMtH zw@=*+awmet+1Cy&!jGq)DTx>#OJ2V}S->ytMx3MwT7P7HMd=i zXoL&bHm_PTu4TTVxKu%RlRQR}FfQ42yxVtJ=mw?UO?xidAp3N6Y-Mk`kG%v=5RZw7VMOt)G(zvH9@S+15g_gQW`w0-j#ww@MV~R13W$4c*`CxoVPIDd)~5Y`MP;?Il##&#NM6tm~N-I^Wy63 zCj8Qv(;mv+Xt=&xFmR0@p*?a@zk*(&k$$KDg$*$2d z#%4-;`b3AiivHokT>Q+Xwr7ub*>dn$rrytyG3va!pL4<|l+!k|h9uAJ{rwRu%4xA* z9%jI`i^W~YL%3?K;pJej(c0Mm&1iSG^_1%2eftA1ON9VsYmT4$`Z_zsgdx^V= zE8H)PfLfrf;pqU}A3N>Pk{;FNcRk=@C#09gtkwb>xU>vl@`Zc9ocuPSon+5)Tep)L zSD3leycHbqU~?T-zZ}Y6I~^k0Fd$PHki`S?zv5$;Sa)5x2zpFK~Wy5x4O3t~8TNgK+oCm1_DblQq| zbgMoz-#&NSKn~_D&zz8XsUd=0%N^=i?y?FpRi)Cc5IfX**S^tj!LiHJgT3k?aWN8* z_lzK@mqKGf}5bP-`K-a?bgrSkJo-1L)$I)T+uh~Tiy=wK3L<+ zmG3IQ(8Z3GO#{ZTpa|)LFjmkyDaS{2GCOyo6r`I3Q#i}y z-Y&h*-rgj^(o{5rVcg~LBS`Ry$WhJW4c9JbFM#caK!N`H#A~qb*xXQnIcy0OGXZgr zJ#C;sWf{kF*5P6JN5!B436CY}N;mFw#?8XOP==Uwx7)VXEbi-7`)x_L;S`hh*B#h- z^5)Zwi;G`%unZ;zN!LMJpm~9TI?E^;XI)eMEI_twVgGBYX-Gn2*#gpTvwPfJBOb19 zl%v8L?9+GM*S)_PW#oyaF6?3GQ!KHayXJfm3Ij_3=X;8RIqlu=v4^O!3DXmo$2wcx z>7q&3AufSQ5;NQ2S-hz~F|rLuXVGVXjQj~&#jQER1`Ocb6T=@BE@Arap6T!g%e@rx zwRs`!ci!LB76*sk5WXCl* zLEoJ!jb@#)3k+Geh%(Wm!QwB<62OC_fov~t$^EEwvjd@HEl%|rwU@^D>;;ofsn?C~ zvVZR5@Futf0s*124h*J+;m$hU#&A2J>$-~4-4x}UjyB^{pL7ovYE@(I^^B}aNrXLG zeQy~&@&yS5d)hlK2cXMxwndY*2}kxol-J+$t%&B6)L}w_Z5G+n@Ec4{M#}7@pZs&v zy!{&UxyKSsi{l9U&F|0VTkGrmZ3Y6Dhc0p9#j`A+%cJ(a+*Y@Ufg60$&Jz9yy!IiT z*G#(~j)Fn{do@245eprvkaO{}OMDMre}$4|$Mlp&hP>tjsrJy8mMi(Pv13@1`nqWN zYJDtBH-75Fbb_fzdzY}6Ky_loXdo)vdQ|-QB$qI@+0#NI?0n`*0?O)Cm0wK&r!krAHzc{`uo`)s>zQL8GfkK_!OqP;ps%RUhRk_bJhQf11;1mee* zJx-c}>pxz+US2RvMU&46sz#c1Ir8U63mAksJaW}xguLfX{isn+!}5cjB4{?)rWc$j z@Mm}zGUu8D5*C)f9fTmu;$=m4VdumqPI(b_?H`mQ`nazmojxki?+Unt3a<<=?A-PT`nx* zl+!PMaD*K%+twd?NH+0BD@JzN4X4HSZe#Vc__hR-^x%I#GX&mwY+#q$Shnm+QqX$! z5TY0Cq<|O+(~PZ7$KRLm1k)U6i2GXVFXeW+E17AXxAQ~6Ez7s9uNI;)20@QI{Lrj- z$I)s2NVxiII+G|)G3yeLOSPYO7kxuwSs_c>M$MQP%{GR7!*y3ISS9AfF=qA;NgyhQ zd+;=k!hBLMH!~^w{%XrwbFZR3;giD1_Ekps_}5;T3)pX-DC;A&GHv5y@ti|DOT#wp z26>0dB2h!eOhdv2Zu0Lbv!aA1ou42aw_ zQbhN&9n>j~6uR{+dLp2ij-cJ6x07jG-EwlG%GyU_!EL$HB|rT-H| zpXLZ3J-mqKRXw1{>&z{>lf#RDmLKk-s~>}H3npcaV2q8k#yLanuyHK`q>Hr zp}0UU?Tx>4tUr{+Vg8vj&mDV1URpnXJ~@_}qx?_0g7Iy5_PefSq;6|B5tK@IJ-^|K6$puGiJ$21};N@Gv<# zw-!4WEY#npE&TMnD+2aNUa3247-_7r6_NVzKsPL{O0mR^%h^fNywq4TZk6)opuEEC ztA4)h)BebOz(oBD+Lfev+VEmwtbGD?&9QG!NdEN~v6ee9Iht`+seU2L%J4i~=y#7l z$?(Vw2{vX4bVyL#UX~J8aPTS`yN$Aq>JW{VO;kdq0|k8B?aFoGM|@HUhLc*}cLs1> zMev8}JIqFD2jI@V$nSX(Yo4Ng zJ>k`v1J~M84{w{MnWIUGwt#9sxJj&It??2z`;ioszD_0YfewR%xPFtE867kozd5Di z@KLLoUbfz+nSdQvAKu7sD<|OWCx~IP+3IE(8~Rp2@Oe#wem@U#mJRZz?0hTzYF|vHMoD8D2Q`~na)(wy^YrLLBz zqalTIJp|?sxJ|aYAtGHZ2@*{Q3~RfVgm}~v;8q{ss3c^IltEdY84@wta{BDwM2_`S75BP#G`RUiu2yPjH<4SUWt5an{Hq+RxVT#S=VW~f54nhh z6g}-V>8fUk1^Q}hYo%qrVy;n%Rt$A2w6->;10d$;RTv|g59&LRazCf&S|h)Jj?}K9 zr|t9|$nnQ>Yif6pVVKI|iN7h|g$Ov^3P78JggqsWjwjI!^uf8Esp^bQj^n+aRk$Vw zj{ALtXe)Q&=a7g;Tycy#u{8mDEiR9vKQT#ls`4w0!xIN5bt7WTOr$K{I=t=l_>H17 z5Hp`Gm4&!WQVei!Yy>JUBS!YnKn>k%1wa9eFK2XBe0)TO z8yA-fv*(b)XHRt=2OWo_JEPMUtvcP|gE&m(`3POiIpvS@#Q{NxI(yqS7|eCh!&RIa zw4xqV1;s{NBuHF!evJ1*io15p?2K2UW+cC=7-3Qf8K&C7*U@9sBTii?(`A^YrxDPdZ8RaHG#Xu6pDgLk?-ud@Rkzp7OwD>9*Zt4eEJ1iR5gr&_-|9E z5J8bfD-@63Cx!8Q;JqvMkz<%mvH%;yB8%A7%27_9->1Hw-*NlI94G;_(b2WnI{^-riC;zcR%DWJLyD6A>Q;WqBnn%*IDe3Yl*a0a+l4KPu4R25#d)#1hk-gUInKVO4))`N&+l7`FSP0 zx^ZM*UVKVca{9;cx+l+_S~1;_mq%lEtq}ahm4Ue6w1Peg1gw~Rape^u2S*4O0e;*g zFTC0{w;D|g-!&aAy>jKCtBL;W0c79=oY39+DrRyFg3o2GQWQdElqfqV0*7S8E?$V8 z&h^1^RbRIKgCr~sd!eYn%$!O-Cf1a7=m-Mg1}*k)V>q`HgEs8Q#m@Mk{g4O~Ema$D zTN?EnOeenIIYUsJMG$_7LzUjiI$fQVvQ@&TSS&T+4SJU7HRG`}ehm*s^W)N9vDd$n9GO(!sK4>MB67a2Z{%1ut&*T_;)W~}u`^e$KEKPEv zj8cZYe;;eoWlq(lpHPK+o|Z&+4f_)YP!H&L5bU2*D<|Mkb-ePvqD?I=G&>lBA4Y=3 zUYyqgiipvcg6X`%k{8&Nl%)r-b9G85RBTSBW6qjy4MyRKMp-v#W|$vC_wNNI@L38O z?@01<`<{RZGqVF3+I5`@=LRfHl29ZIc?wSh-E%x$HT>&OwoK9~4B+BUgdKv=)ns-^ z<1d$#0F|SL^DPSi{;vCga zjn9nHq3}DPrBmRmF&Y`5FQt?eE<*RVLE>Xt{=cv_#JR4 zY=ivk)#g(+=g{7~p87C^2tEew27l_y>Gl2F%a9eao+gS!!fLc3KghcWsUJ_Df)+Vj zjRE$+$F=3$Yufzn3|~aXdGi?k+?JaBNg|sa$kByL(mY zc%OAKibE+5t{u;0=b3%cg8k<0UlGBYzaZv?z*(^%|AfkJ!zjq_3c^PqRL$ zr4xx`K|&=el!_k`uikb&r~?hOTXM*kZ2HI`qh*#QyD`TB3h^?bH1?oXDEKD3q{ zy!AFovUG>F1iF5q)hBAxA|yO-E=>hvGyE_Xmf!fnJ6_r6Br&Lx@mj_{*kK~gfqh}2 zBnfCHM}5Ce*zY)88;rZ1bo;*iH~S$vva6I$N{w4sSh(=T*VOc923&i0fL#18#D@5b#mlF&hAndZcU9dh`PrW-wH_J@% zIlW=dmWZC#Yf0wsY|8gAE%UJ-UM2;$zy)(z>4qW5R@rJg*t%}!x)G~c2Bm!$IBuE| zmMXlpAQo)gAEQqrH>q>ezng)zlN5t&_S&Kp2vae`Eg~>1y^~KRvZ=ewvnOojaZ_CJZ)IXZ{R2`x@v&ICXkvTcv5EFBG#3N2nnG^6C-!Z8r|CzU#(&-`%BsJ zb(~En(4xBtPs3hPUHl!dj!rjq8_i^=Q`7ruWYC@6zbi^R@37ZYLNFB_XT&Okm1{1qFCfSZ2<6o$k z2EL&r2C#H$dk&FDu(?HbN@^FV&;lmGY@_2$tPESiOvt zN_%L#Xmv=Wk%MKZFc3Yr(v0lkM*-8*>W)zp*Q=(O-QC>}TCi<0z|rN}ZOToOwJ1{+ z*7Ew5e4whRaeyPdY4F5O)Rs9AH?o?COUK|n97$liD&oxc^$9c25uWBR3sko};Q@XV zj*}CPTd`4(QBu_%F@U+!vKhm%N6}1DvysI)R5O-*$aMkXwV_bT(99gm23HOiNa_1a zHetuU7rz$v;rbdYMJGwW!~W|098KNYNED*nO`dHkkfY^Lh-kAS4Uv4xTkZEDSDA`E#{nh=YGH1uc6m0AR3@G$J;gnx;7-WnxZ8D^G#VK( z!}#m#p-?kvEK20W4>~zfNaS$;P6QX-uVWEAY%==#l?qJhU|Q6O4F}P-oD{bvQQ!-< z>F43J;wyV3Zf~4g%#cgNLwRv$lStoo-z{^ii56WAL73PnOqFBLgSI&s>T@{&gK}Vz z4NU>>7$kx~Va8v2Rp+pAQE5&_uiBrakHf;{5XU{v*$lsSQ>Fz?z5Jd9?#X3-UpbkG z$8e=?lqg=mQs^fHW?Er_q~~0$)<>LgPGWIk_&%YK7=Q0V({d13%bv(NCP(1?#VoJU z+>IkGH)VAEao66mDR`%>Cs>*=!(4#__aG>h*Iilvlrge$1wpQ=QPYE|*mcOirXv~V zsR))Sie!!6+z5=CIMmX|8~sB1_DGR4!s_}eP)XKw^imOwK7-6<*6~J4_!k?)mTb{}}OOGPK*wNoF57ZIKZbtSBZBx4ap$K?7);G-HrJJaA_rz34_FAyfz z1O2X=H2uf=xP35n@8j9=GY_0w!DyS5eldes|3!C3XK^u6Q`1pD!Np^+X><&n9-9O6HRwWj&Ck+Z$D0w|W=%pr1H{>P%ize)D|s=VIBw#VWS-p*jIH&8W|ioHhr}*n{KGWjvG83$6Nvk z*_@nXYL3IRkdT#0Gm&-o&BalCxH>9ODl-w}VhiTyzQhNKpY0Ue49*q?`TeM+VZpXB zHjvMuZc_O%nZ(jJS0+YX2yqEp6G@6kS!Tj{y25EJODhHM7tZ@|1nG8>PN274qOnp@ z81#j}=1%DWqCCWf7v6)wKoA*3URh^==Em9UeEc+(Qfjnxm!Zfs~FjZvN| z0CM`tFBJYTJ-;y0bMpRn4*} zW9QW^6&uo;bnrq-baraKp?FZ&j1c|h+X)oE%f~<|!z|Y-JLJ9Y9(ek56v-eorz?3% zOL$xQGcOP>;)2WBvf9d1*APLAtSGDW<5cMD_n(H8e~u&)moidJfAs$}aq~um+-mm- zzl24EunDo$SfI+9y{u$`FUI*H;%HPG6B-r(tu7Uu`Isc)8k*`J8B;K8V`v295Haj! z1gE%d8KyI?@f%VC>v=Q)F=OX!ljQB=0~ugzxeEV;7f~?rV-(iu9Rv^rIA|UNK8iYIJ+yOFm>n`!BffA&ij`p|dKx4e{R4 zP)p=kUwi;Tr_~;tY~^$m+4aX03KRbMBhoJ#P6B9`P+Lyx?kFGW*V?5ObPwr9$!lNp zF$4eRFv4l6nqx(F+ZQ0SBD*N)MBESRtk((}hj9;nPeLqK$U%aVbCpdLZslBk!K{XN z8P;JwyCx2u%!6i&?f+%w+TuzTz)07XlJNAprW>A!o9Z)*tL!m&Y^JDbohjiR~K1o{r%9zHqE!U@q z&;b2X5Z3ql3vZPB=#(f+VpF#u9u#dwVPTE5J&mV+I>W!yJc*%_T1+t2CPRur(5`R8D zqb*#Ww>%k0L}{WL61DzD6ZchNLjJU2=w&Ppm5q-y>hCJDELCen3+h1gN+8cF{;U?A zMY<&J>JhHB1)dx7;A}Q%;Ptg72vb)~_q(FQVy*N^LZ8pE+_@y)KmL56kP#$cI!~qu zg1N!Rz2n1^yoN&jd=263NSMPnMbs)Xk&C{4)#LaQ+M(-@`54wt??hee5|qH5^JoJH1eh_*@BBB$CrJ9|6Zzt;K7h@u4b(qwL= zM_JMiIFO2YEO3{L^HCt79FKvNy0>i(WZvX^rm$G*3+p8)No0;5Dr74vTXVW0dT2cQ z->ze>QfM1)KOu-R&iO*oSHvbh72B zC`+N6FgeSaTjCy{z{uz`YTPfeOPQ^>BO&;UyW%KMsy^2gwiN23z>Qspp|7g8Ywa^xy8ih;R>P!;syIlqe12R78(<< z-KmAQm=y7II1*H*13+csv@z~J9~}-x$4yWtfF!28WPhD9|3}oq>I6yZmJF1X-1S=u zpI+dk=Y)HH@-m+&#-{0{fzhN=9W<}bRnga2dx2$Q`QAjKVSjST2)M55d0)Gihhu{s zNr9THUR+1tpAWCQn;4%$cw<_{8F$cXewfAOn)hQgL*^%8i|cHqUyFkQp<2&b#s-|T z`jy+W{DoicyEg{H)k~O`5%biTQQTHvRDRtCX;P@2sHFq?6k9mpAD<(vnaP4)C&}B! zi8VDDsQP|r3>^izr^2zVkqyAK3*ax}+59HCfWK~c)Z%}(2T0Jm6Xe(B}1Pu(F*@Do1_ThuM9f~uD`Ux76LoAGwNG=|i@E(=)xDn@{fCsLj!&i0mPF zXxBmegJd6G_>fN(1eXL}p3V~%e->ChNZj-FsPSN&3Zv@7!(xmX{u0E864yoI@E8tw z@4+Mm8BoxhS^5yys0DFiE)sn`kpW6!vVF@I_>E~}HoE7wM&P&}!x(NYV&&HDcc~@b zn|kw0rQEl!4C40D@6pgtFX}}<=Cdxc04AKJy$(Mr45p%2EZR<+sHq!-i;B0p-SmE4 z`Ykb6YGq4}?}5C+6CF9eCfDB$l%I1qL9jpeM}n!Dzziqgh^OLeDjQh2+kn@@u$j-c z{3h0rI?@ek zaSp|HbgBt@O7b{Dl0XMv`j}btYa~_mA(n_AtvGxM5`I#L6#`|Bz%EUyg?8k)w~edh zqPu~!|5?7o1XI{?u-(dSp6gv zM6B5^9uIPvj!;yw==r~vx)x&Z5*xh&UW+Nli=+iMi{ZvoYL~pULtIhQ6_*D1sn+T_ zKye&k${1_U_~Kx`=kY5FtuP_(Dy@TBNk%C$mB|m;grBQfI0}yXqr^EQS%qW0Q?iQr zj~@6M9c$g64-W@PaL{gDa8XLmHot*QwFl7m=!M?UmgkZTTJL=sD+!#==~}X%f}e+< zcih4?M`!#6l(?7-Rpo}buxDmWmnteTv~dT`REZjv_f{C9dPJjs4FC}6>p~Q}_D;Bf zX6iBhq4#K|u=WQRDZwtp(idMe#iXl%+p!;#`leQK6?rFe3y`SABXDzI9KAqUveiK` z)6y9)>fhae6HJI+&q{%Xoy$=TRiN`6h(E+}0hw0|~u|O^S0Z%B{D= z9vh?*F6IE*n)=x0GTM+ATk|$0kigtc6`H@ctdTeGt?qIe3B02L8nHjCPM&jh78&Te zqBnhk<-5X-+DN^x5MCN<4OFxO?fOWk=t6 zDq3y2mRdn8B)%PfCfCR*y$Yelt%nHd3YylSDmepLO0=l}F3r}+yZ7GD1!)|>H&Wu2 zzhI{k!KDjmzX)&Jq!{~%BH3|$U(eUl8!V@8K-0)e;$)Fqw_6`0evf-z;K!KV;wMx^ zG{GB|-pBdCt->|qaFR`47`7ooZ8W-ivLft)R6;_ON)cr@u?DV`Uu~uR3#-d&tb@pV zqJ;(I`eJ$mS;}Ig*suox%uJX+o+{kL-Lln9Nh)g#vva^|>59>2e6(;b5hsK3L&mk7D-H~bc-zFDRX~b{``QN1-I5AbtO2CtPoY_2kCNtYv%}&TLuwUOk-Wgz&-KT%P77}T1}~y# z$;)pijLyU$jdjLaSJQdB#8{2tY;anO2aQ&z>$hxuj6K`6bY3Tprk8fa}Q*2&V z6nS{$ZQEACI30uX5FW5%k=#d@_OfSf`dV;nlSJ7(H!3>R3=dyj={GvJuP2(*Qxe6Zppt_K;7=@)0Q&|1h|8U_~w}`3kuSx^wC8YgeZE39e7u zR=1$^_`69Zn9IY`gV8c$Jzd3!oivB}l~{Gn;$<`@5@T6wd*nQtZ9!#FPA4*mGf-VLV+wQpQZr()98+8p zO~_-%!$DfFcoAw`b3kFd?o(UcSNS&RQqG9-W%l4O*Yq=8bYBm#IP{WX#*L0`@9ORC zS@g&#|N0JvD30a9LkP0TMIv}~G67rju#7HI-=oXkbuB$rnh=Z9xj51tg$_Zga6X|a zyPYlP26Y0J*5eShTFe-6tPS*ycc5bj_o6&X-)!tDHZAsKOv&{gz^ zTo1>4H?+-4XZg*XY{k{cQcH7SMcP)g&uSpup7x zBYmeQ-NyGaxBBQifd^Lir(+5r^WQ~5VcsI<%Q_3o*5>{TNVB*~m`q_vs>t7+%ew*}$>OoMKmgOVxR z{P6P%vi2>l7wGQQ9#lb3Iybn%Nz#GCFrn!p1_3pu&o>PyZMQX36{dgh4 z{VOZSsI%)z&1uOkiK-R%I6^?MWMgELn2z9|$*67&M*;QihT$7(>cd*AyEo(0&wha_ z=yO7dml#==DKgstN?Li0Rs|r8Kza@$`ebI}B|H)U8kRAQu)~w=i!L@hj3oZ%y8*Xz z+z*Xz)lu&K8M;c#oEKlYQD~XK4aaiBrdfRQVrh}lgun~Ae%CUF za2j+a|80R}Oa@-qC%@lH0T$7Wd#bX2ceH+FS`3yoj+Y5vkk>*LW3GfHpdfw1sZIqp zF-d7h#x)9DBuwQ63QuF<(-i6m17mE$P=g{jhkqSWD0+)-V~Zc8c#+Ii;m4uI#D(=k z5l*m{2vqoS!!jLSj<|@s8Q`sr^%oH)=O{{CForla`3IM`9peMyf1#cxnbLd}lz9cy zYSuVe;j*s57Nas5hbTa56HHMtP7J(m_=EyOr_no?;)DPMji(Uc7k-YQ>#jlKej6%F+(-$(U(kq0lr zNa$2^6-n;nNF;@_R#eAqH|Bl zz9*o>*b@qc-ex-O{Q8i@O5_`a)*_{&Kz28gredGA+Uwp}78g(p2kJeX8qmUSeW|oL zYwa3(Q}^O8@A|$@8>2XXq@c^}{J>FNb-z<@9(~1-3s&@`-gNu!0%!q0%8d7pjm}z1 z@vL~IQr_-{2>;g6-M%Q>E?7Sl=|1?GZ5%(#aq3BxAs1Ze^sV>Rfz`Hj__Q;?57~4N zY#Ryhj_s7iq@Vi~K-g)H4w9Q#Cn85fP%lqY!ZTdVU!A4i5RTLOF)P1_!&@y-o}3k^ zLKh7q^}+O&31KM ztM6D}yb6vDqoUBFY?cU_OV&?a{)xRk_Wnk#Tp8&weBUATmE~ln4kjXTOwg8NI5$)d zvRfJHi*mtS7@ZB0+?mv+y|eAx`@0}v%pGUW(#cYzBU3#5H6O{%;~V$CTTGuG>n)el z@8NWYw24Hrq9FfoI=t&|0}R$Bch468zTlj)FvwtWGc!jzikpU@(Dls zPWgLDX(K0$2EGsy`70;@Dcy?VBva(1M9sHwcNmAhDHl-YmvHk@64MqUQi8yAn?Khq zaLmdXQaP=zAgSzvRjrJ7ustYPN{})$I&fGfwn#fx4D(Kaz#M&1cTw^tT1ZySb#F1Q z?D6eD`p_U(l(@4-z>N$kQc|HuA6Bv-Hp5#!OCK$3)+)aD+X)6;$7*@nQ`@s6VGyF# zjKU39^{a{fuO%}H33LuX?Z($yXVX~3yllVUD1{%VuDoL=U`QM5mHH*zMN?~Wjd%|w zh=P!b71;eb4#c6002qjrx$ipx5`{OI-R^!K+;D`8BbpsO8|OmZqhdU~>9iO>RLIWE zVAN=K9EQ_f$(%HQGEL#>Ny2L|WXIUOzP+S6oV8DxBSETKS*z;<+XuI<5x#28R?nYO zyyScGwfUI`vGk_Cn0z1(c?fQ}S^Rlj6O{Cl)!XaH-MaOApZ2@m^BUcv=jFi16|};T zlS1;U=ijOLpeNj>NXqj-p9 zx{PU9q+^R-r!=`k5iI$>@wQr`RUUUfpmW#;Bb17(JvzETL86?XP=uT&DLyO8Y&$NT z0^<-rir6SDe4H<2LGE5#*Lq0$-sl996FXQ=Xz&Q+r+J6-R$gIc%MO*5Y|To^a2tQg z5sbm1bTp=bRNC-2J-3*yuyS>jSI{mr{pkAt@-Oh(Gp z!~j6dAquW0Eb!mGm8zw^$+`5Pt}$ndS0@;5)xesAnsT5YIdEf5))J4bCa zrKowVB5Q+i?(iQ#WfAI{L<$|l0#V4;J2}3Lfw849V`1Xzq-KnvGF$eG-ML_yjxKu? zZ{@S))~lo~-=~kVx@&4tiB%2Tucl-daC|~72D+-2Zo<*LficQAlQ_-GTAS2tJAcCcLPN0MHYcd zp=244JqG@Z+2gFPB~a2(EeXF{t2Pyp3TI6X)FT79Dvnn2i$>~l)#Z|2I1u|;5t;{i zWADs~!BYGOY4yQ>2GyG)_uq*x|A<%9%o-KFWY9KsuwfT_yb?btB7!P8W*69oqdG($ z;`JJ8ViI99w5%8LTLuR9-vS#p@bbi|GVZ^Me8x(17Q<8YCwB1EMJ2bT$m?Lbjdmz&h-i;QFTWIf;-0S;%?3?wM20dD+NGu3yw?r~^DSYWXxsLv0iH z7k0fgxtrj+JIxrWK9QrJntypLcuH{%njC#ct@%RZaD8I8vQFX@+b#Pncl24^XLd6SYa2|(|8Gt4e46jE2kCnSln^gfp}*hA4qqec(eH_~_DG->i; zWh?TJ$$JLBC%zv%y&U=7FXHkXLG1B) zGPmmIOM2|HIW>}tmX*9gwwqm${6%I#sy=)srL&zcXs&&=l3=RqoQrE_v`sB-xy1$F zYd0ii&z6;YY4%{!2?|pe1!dUD4bj1HT+KU{OhT?+Jrb8^STihcV@}7z8sr6E zY`hk<5~2qb@VgPISZb+@$8Icg`W!Q_k2MXaq1cVQbT|nvXRVS2;z`VBzMoBx^9wPE zuTImP2wb!}zBC#Ig_3QgP3nv~v^va97%8YyteZye)7;fhcPDt6DytDY!V0{PjD!(= z=0yHIQSn0k-bH#dXAOSiXmL>!36KWa-Mh+vSRH}bJreNBWku_m_ph0G| zUBsarm`^PA6k8NAPHx}|1vyPc#DN^I=ifB_o)3j<Y*0`8mA(Q`v~5~AdN#Wf=R z8RP+UmGBROh!leZ2+)!a?9mMIYnwM_kSVzeWmUp0StwU#uGoF0P}RY?tU@D0hEkG)dPCI>S&uoetngCDD<0||7?)Rt)A^Lapm639FPmkkPI`igGVShNa zL3F4-c}!3YPG$X4VT^bA*;pAG77IFc$gN}R@^8=&_TG%4m?YYS1SNPKdIp=h?|9Tn zuLjS1eDf`ve}fS$*}X9EKKetjBTajGS8q2orbvH4m4$v%_-9>3-%`43ymO1Ot_*Re zvARGXN|_W`KPHN+Ue*(Q{yt~LXf*P3pyTDszUn&qbKfT#C8y>z%+~8Mp~AI~jo{){ zxgs^;#udA{(`c(;>>o)thFy0;>s@5oymwesXHNvkOj{58l4zJzCU#hfz|GrfVx|Rc zz@UJz^^#49GZU}Z^@{;Z^0i3F?hu7UYV?m8xW?t~$GLd3({6{89g9E9Od^A-7XytL z5qTRAu42*zY(h>UxBTlZ6=UEnf|!sX5IeYtLy+|U2?P-P?}7FA{4f9dpZ~ZP;JeZ@ z)5^mKHdj4fZ=>Z&^K7wb2tgy&C5Y(&<1Lg)T<`A|%z5tPD$)l7y?gY;*A_RS6~ zK0~ccidZ~+FTq;JO@qV>)s@wX4j#qMf)1H2W|~5`nEv21{qe_VaJn|C)mlNLw^05N zC_MKV+ZwQ9g@?2=MSZ(VZMIRM(=n}$EqE03Fe4)gDHk=kS(L4A8DV{$$|K&4zXe8K&n!Wvo?j_Ffn^|RJ##sV7XOHS$*#aj8?iZx)6VCcix0taR> zL$e)xkoZcFyiQfW6l7|T)?A6_k3T-*zPEKa30(8&zwYE}<{)1q&5G;ip)d(2cE#-M z3edccOgvGBxKTS&YA0}Vjh#;^1Q$j%*NbD0l`0EzxFC($6T~#7SR#6iM!n)%QP{EB zH`le|oRul%PE!k?(shffgvBuhEWv&BP7Vbus)!@94U#*lBg(W~Om!abx=fP>$J}F^ zPt0x)3pm(Z;DQ(`wk;Mxj_S8Zl%~LZ?J-M{`S~YX-mFL3h|iBupz&q}jzIe$RjP7ys$QP*{YQVlDTl#Xr|K(|WqCkeK5^>#Lh zigq@p&!?1^=Z+H66%40hg4C(?Q6*llv&))iiYrxU7{MOZP@D zPVn>RN61mNX&$V%^_3WZ7?a+nDT{W!e4o;p*Y@4cK`#q=V=FiB=|=T(B-_oQ3U4Pm z1}>H<-EW4#+p#>ly+!&XuPus>RsN2HT_Mh+v>DKBg5OphwlOsfYxZR7RHjh`BUO6F z@ODMddK5BTs@{17n=NY6v(uW);~iBoRd2Wx`JZthdrv{=)!tO){GdY{V>1(n-oHw1 z&6Rl-@2oA&GM3e!=YB8~@RSWjMN8XGcRZa%nI4i^4lSq!EewrtN0Pj?*KafuU+kCG zK9|~$KjUSH;F7DUIU7>W4i4&Zj&ZM3KRu#eQ(&2jA%|DI zTG4{p#{1<2#1-^D_a#PAAnUqQJzNtjm3G58qrdl8O;Dxjf+0i=3z9YIcbQK4Wcqtu z^Y8iJ{HwqGapmvd#X{GpK2^3)AtU1DZWrea1r^F;|LIRZnMQkq z`GX<)JXGb2m0fHedF72nU^6z8%Eh`Y(Wk74OjF1#<=$OrKnEaZ)}}#LRgp*SbMX4= zMkqYQIk3YPUi0J}3S6Uohk@swMj;AzwUZu|sgN}yHRp_8#S~mLO@NaVP*q(jGdV^D zj4G>!Q29u~;aGGiJdGMdrjV{U6p_NvyaMx%=lTGwF*jGbYw+e$Ara|$_PjD^V(#l; z>JV#5tyFtopU#EPkqZ#^>NnfC0ZqghS+9{O;pxj{){p#9+(c)2fr+ae(}*5^I(Y zrE$bsivHR@jdj)MbgGwY@RZ2$ot!DbJ~z%rUV_8veWy~2Q87hoO6pLU(^EyI)|qkN z%+SbbOUmsy2EKSOlbVUwhG|nO|4wL0xT3)zoOi5AbRPNF=-%lJNaWHDE396*Ma!7U z-|_q?lf!Fa%#5_ph}s|+JL~r-dcpzXnoY-Y+ahZB``HXXR|fP(%1kAJS|fGw{ckg- zugW@|GqM*Ge1)^4K*~23sHFB?nZ+LDIwtS{|Moxq+aJ%b{X1|pqaxh5AhV*8J985K zjTOgE1?iqzv~{W6Un!`V96qoLQDf!G!28F2Qa3n>DNuT z#LDWZmGr4fD;j}{AWi~x3}n;r?(PrRbl1=s!YFpzTv!xd+COKB0YxW!djaekw~A$S zsN`Va_CCg~>{FYgLihXAIe$oHqu z*rfqeKtT+{kIYf7dif6Yu@aASO#>ZY{c8t{h?=I z5&Du{;b?Nc!iUp@6^rupLY|sAm6M3UkZAJ$TN!vcx>Du=S$!Jsxp2=PQREAMUha$elKZ_t;2p>tsSzRQvb|xY_J3kak zHYP>!+14;}U!S|}3AE0tkSEcL+wDH_a>w9bO$Nl+3Z$!eraQ%C4Nfu=_1&(cvkR&) z3YIMq;ol=>uMnf4E54|(*@M~2jk=jvQ1W~JcmMWZ{J3uLJ3b6Jno>VRYCkR2a}fl2 z6lwZfzwL7mwzv;AuR%>v>MY8F$f-BVC|L{I;SrTG{Ai7kp)YDk?8?dFD8!1MNsEB2zd748ZvT5+txDGb)jw!<)19}$oT%W|9 zV6Zl(9O77c<+caSM_PI-BVwt8$f#td!6QXpmW-fu13w=qSFai9bz z(1@?Gj#4#xQd&zy>GTrOr^o~v6`du|HIuNtVW5TZhUD31%8&Zj@0{(t5Mmn9WM_xa zF+HCgR4{kMhZ!qnG*-|g7L9ZC#UV%U?A%CfxsyV(Pv&zz;CY;ps;(9-K4KrJ+sIOX zikaZM2ei%sr^{$E^&;4yD`b9E^Xptcx|iSNkFUwdtvmoJa6IYr7tY;9df^kR+#BJcs6)Z$m9ByJ zo$QW~241Cw#=|s{G5CR|a?3fV?1E5~WTK+i4VcGg=nHHvmk}A9G3R2l$jzJa&rp0( zTB!+Yiei7e!evBwV9SU8pM+M4Q?8tSJPh;@)O;%1V8?|*2cP7156Xxn`_-nkv69|G zwK+w9s0Mr6ctb`2H;FY+CP*}v#>hMlcNs+EJgFnAfP{@`bfLv(J_wB01U{^p2LG74 zwWY|9;8@AP2>h-bUS(Y)j0znT*AVMUE?tZEG8Ko;!+~}u=Ds-ubA8SyrJ7=bU!P>5 zY7b?Vg{14}F*+;ivC2f_e2&RFQ9)XVO_79S3P<|CSIX>F>k_ztM=G6i_8S3n53$9c3e1WW z0v)bo1A*@3j#b0W{537od=(F3E(q1CpB#EU(i=}HZ=5T9GF)FI|3#|DMB9x%P@}3q zo6U^LGek@^1m0)A9^O|JD-);^So|2cm5_Hyp-yI}qE;9AS$JKfYqHj|N!%w7JnWIuvvb^9*I5ed0Qe z2SqbPI2Jy)@z5SjEp^B=zEN6*ikP01Tz9QIrx1BhyY``U?3_j-2xcQ=Vy>c!MwTZW zQ3WNOhh|c7j~At66~#U{iLN&1Uf!p6G-+=tvX@cCb-8L2`+b?wsTJ;I1c$)kbME#1$3_9M&+nI=86caIavfkaYX_K3ScZdgP^G* zKR*9lmcT@BS zO~um6#iIrRx+<@0D6{GJKV2@%X8M9yiP;*^+bd4bNE{DoQ`(A0hcK81UNSvO*7$sn zMRayOLFv?^>%;hWxWksB@!m0s&1g4O-lcXo9;i(1$4e_#jHG1K^(;CWbBKqq$7>HU z4c06aDWa`XOz&oJ?KyDKwrvDpSU+)zG{1!uJ=SLo?3u@-GbJ&&;sK93n!xI#MYxw!;#zb8g zRxBW60qLu$uTTj|DnDv-^QQiThj*x0Yrjd2T+REPf&dZ}l_XPV`U?kWTtO2M-2#@G z=`v$rx^p*ua$lZW@v0eSEBr7s^KP9s`pKV9Vre}ThRnF>Jf9qP}d zeOJlEcCY*V_S+k0hOc2WEP`Yu+3$bRFf6CRT(9{4L0Kz12)h%A-yZkq`70bb_)hV} zM*iN(&=`;Ai<`)YW#7#Jem%b!`g@gF0IxXLCzF3)cQ|zXicp z8-6#ozjt=nERi{VW8|u;q^0p~Qb%AkC!XJ(>cxt31Jhxeb4=A$4Pzbym!E-K3bRO) zAOkk2B9Zx z*)al(|&H}NB)dpr);+tt2X5GolJQ=aChSdl(@~WP9SHOrEH;$99AmIgsyA&2y|S8GILB8hUZWU=D&^9h)Sk!l zK#@?wtn>I&Wfduga;E_PgNH|Fsp6DJYEO^!Cpbnhg2>8pJQ@hENOK6LwqPWP$BW9R z+Py?8fp36=v0+)(F;&?+Ttm@0uI9Py80G1Lw@{0joI6Q=yHptKcL0OC%r762Yr zE*3L(4h{e>FDnN(4=*nVGk}wwgOiQ@@6F4?!42f$1#&?~N5~wC2_20h! zwuC9IK_F)!8=HrR2df7ctCOo08;5{^z&{+EoGgD4EN)(oAQMj(M>nc}Ge}stnYr3H zgKV4}0skqEaQ+`!N4Nh@)8B-#d73!0aj>%gGo*h56&3&gPzQ(q zLA!y}EdDp%|0l7VhL^Jio0^52le??g--)xN`p1~f#MQU92|UNTwu~ZU2#igY#d{5*DsD zUoFg~T%8;M{~9vT=0C^6@gMpA+t&O)$HMs^ZQ1??!}ia_{$CUQ@2V1D>)$jS2zx@4}P#-SKy4UNI`=-df@BaJS`TJzR1fH7Q%gg1F z7h!&YrFXBB60M?kvB1mD4$~9}RxFZf262>taG}EUw26dS8LUo1d(%j5?iB zbBBw8Iko&?{70<{WUJ>!$or5-1S9`e`F-4n4}GY@tAW1jFq*jndGa0s8|gaz?X80n9Ztr_=cuUmUZcN%8|S@AQ`Y{lFmzhIyN!v7AGPBr?QF{hAuB1P-Yzy8PMP zoRN@sy4u|7V`;g!j)Rk8l$)LXga)q7Py}=Fiz1k>M@Shj#n2#9UFNY!pFP!Yk*>Ph z+>zo(zDEs4-SdoxS;`y`dkDb>!V|iD`m;|$`3dP;Gdeo@Pj_G67j<)C^21RJF}ozu z=fKD%mwsX~$^toKLfFU2v-aIRX|83VHAa=%GWFr89*Fq8f$JSLtAgu-Y(Z(gHw`z~Pw^4r8vhgN3?aJ4QPP*{0JhPUiG`xjmy)|XT0 zPvFaM&~=e-4|FI{gDy#O#m?8`)dE6a&rVV{{r4UMF3dLradnkslGV3Dh$g4{t|goj z1V2D9b0U&!H9YuUEZ36`hXtN5CHXF$XDU9~!l(G(zriT%!v74DJ=r)kn>6tGUI-s! z*r=bp#FM-rq7zaOw1gz`+Pgk5xf-VI5`ayL#m<~zFy9ITALRD?B1u?1X17!5y?0xC z%qb$v8f=H<9Fw+E`)GRWqUPbOk8!90L!@T+MbMrrUOAn2&CC3)(M`R-!ODu=ekM$F zKO|-W#~`?%yKHQG02<-G^Om>h2DhBPw^qhP0QVy`GNxlZJ)-ll80ZOC&~;P#fUd9n zJM%rAg5Ha6F7tp4t%Dhd} z&cyn&zFVVTyi0F-9$Ke>9Wmh;?b})VAlo|E@orQH>O%~{)*QhhrTT}=+Aa9!xhxW6 z(y=+`&DUy4#?=tlM&ul!mSfctA_h-i5m|f*=x_2RJoMH@@32fs-F%V_^GXhqqK~;G zsKnu)b8V+0Jw9`w%zPLV$Jj`yEz|LRJdn(Mga%6*CXBJZzXYU%K^UKk(T0YADYoDU>AKtKu?|{;_nx%$A+-I6~dCWG&C*oF(Ed=J`0f z-F6~_8pTM~a*x@B>d-%OG{&64svDM$-BY+8LG4|hY5h!k3K*Wi!DH z1B(T*i1ZO|<42UV6(boVf9b`(01W0mWY}a5UVkCnXaz+*;!Z{Lzv<_`b(+)>@kkBOUHp#Rna7Rg$3!dx0!1hDI?Jq_N$5p1+V;)Wvb zFeCO3AF^{P)v}y^db?o-S+t%sh@QQaibt^|$qJKjcuEeGrsiUw1Fwyo<;%A5I-qya zs~iAp*2sJ%tEj^!9L{BFy5H2j;YJi~kO%a?E8H)^-w>}(+9m8vRifRnvwkXON)uBH zys_Y&co%XVvfuZ1J1mj!@DGr~00y(wc)U}fCY<#j66E(Y4d!+4EJ>QXdGUV6W9uW2 z;lbcTgTYwy6;|Mix#|JCwyAAvQ#t>(NAu3^;L@Q|**o-TN+hcT)T#Yo#VD9v=%{{LW0aY)=C@?kY=yp(66TzZG;j@A&NdbSOKgE_>_cdJx4H@cy{^ z-Yo6jG`&xdy3>~O! zj&YT+cDydD6KqaxrhLxouzM`jD7#l?vo&J)QdM#wOwNrnK!o-9g1$VqlyrnDA5YDc zcR%KpQ)nrCfz4t3;8mqh$v8rlB3rK_nVE>DkpyxvZy=ArIH97m`#{BK!dP;Qg~uLu zv8Bok(9xatbU`BgY>b93e{|sDdsj>6yw}G>{fs=fr2{k5HN3t3uyUW@YyIAQG0IJN zXXF7DQ_Pvn?Tjs(T*+8%7(_pzj=?IH%;UAQWCu#+{_)v}p;YiI+V5c;H}0n(>c>SV za=%?Jn!%5Mg0w629Hcu`7GOv^*)N~+6po5)2=fV9cl<|hWi)&YtzHG~pGf_>sIhY^ z+Su~x1utf8h~wJi5SyUHai#p^2@IrGs=7e4L2%QO``?HSo8Q@=njKX&`l&L4woz=M z{#^KmRDFX;2USQj0_=8FzLou+e1G83Z#($&JNF*2xk^4}aRDfst7&Km#o6igKgW0@ z?0miqND${+`-HC(@fk*pc_P_MO*%!g#R}M?wu#Ge|?AtqWF!V+SeDzVdd0 z$gR!G*112)FK#GXg2`@L@A4$q@{13Iq(w}hF6p8^*b-o%=FWYLi}n?XaR}oc*k`I_ zc6Mn(j9F=PNDS7Xl6AP@Wp{`2eJ|$naa!-(#^F0zyUL1(8cvk;5Hb2pHKI_U4e8Ef zqm+IbrOGWXF1YD{c<0PVx;{`Oxqix+{K3vSwTg%#5C@^T?GohSY*q`}ZqrGlR!G7l z5%k8LeBTjz`nnky)=G4fsD4k64|F*yl8d@2QY;!am5teo_c`xf?7X7!J*-vUn&#V# zkjI(T2A@NwRPVFk;8Ir!x-YKaHET(KaUyCawQ2O1~uQR6Zxy`=x*_QBg zyqcYPG>`0p;tloCh=89sr-W zHeci-z5Qzfs=hWQ<0&Gh_&Fnkb~R?PO0`*})H9{d0Cqn%epxwc+!{cJDpy&bRI!)Q z=R4C_wk+<|A?6n?&u?p}%yO*q7fkZFpJ7Y(tovr%Rw1e&7U#=9Bzb~@u#-cH4S4)t zO`sQZg<=F<1(*}LCN1kS0byU`D_d0PRX!aubm?5#s%mM!l55j?NF>8b!^D`P;C*1q zrw@+jI}kL0ajeyikX7&^<_=(LD^+IYcrX=>Gav`tzKQ(^l{1F{|eO9u_V~) z94I6Ef=$zIBP-63KMKg=X6F-3kgUrjv;C$VcoB(3DU$4)+=6?-10RG#wqYAi7;Kgp z3Mp?1t{VQ%D@dJS01QYTQ^jCwQ@Z&v%O(rvFYWn&_WD68AfS_&IdULeKP%CkJd--c z>W*9EXb=OUK`EEcP&^RQ<2n@5rdd~BWQ!9MDjBVV9_N_#a4Nm|^?qXOEvAHZy!3n# zDAC6rHvwH>X9(V^lTk>*w^fS-hL2@i?d>6@(nLes^LYvr2X&{Rv=Qb5OYo)M&<%bT zYUmmhGA|MjrNGIH27`MGp8WQJxnZEBxB3pCqbq9U6!Ns=u zCg`T78MNlPQv=gW**|dT!*hC!P#@=yxn5?AFM^<6s1y>CD=4c)O+3J&OIIBmiX7?( z(?j(MKL+pT;~mw$=p6(BeSfxWWKOJh%T5p-RS+(;GX&mRa_%SR7`2EX7c*d?meH|7Sb*Z7ykDRifI=2hj zJ1>Whjjo3v-NEC4C2HQ5I0X^ih;0L*yTZqKXpVzX!>s1~{4#I8>^AN6b4mgG?93u1 z{^yy5VLm%XnEj5uq`|_op$(IxQbWAq=e$i?gt;Pqe@Gbm_1v80i~g^$JKSMC@&Uw|<*mC+~_*P0!%Q zxrtv~-Ec`7qY0l-=K{&2rICf*!F*PF+<$b?9Rv7|8u$YB_)NAwCEyO!h zn|p(ZS?W+E*i;O?=0G zzZ9UEL%O@DqhQ*Ht=-{d)HFZHeSroK<5lfQajgGMIDGFfuN(ApYPkwN{d;ygxa%xd zHK*I}%)ODY`+TqQWOl`sX6zNS)3c9@GV*Z6AHCSokYNSu+9E*Vuf;8uu1HkN3;;@~ z&{>d38ADlB=-49csYty_&)ORE9T|V9+Tlti#gE7^(iaoNd)U>^pRHJCtr$y) z0DH}E^d6~hxDK;7w&;3X>;mHP+EfBkSZ$jo;8UxuZs1hmLtnB~lTr{QWHd*TJ6U%h zKUpoc|JyFufSk*WCQ_P9f`EYb2Ztb6SU1b6O2s@x;1hp_v0J$z@%c)6O{a|kEta!m zwc7|K`hMzYP2Z%I^i z08xfDNj?NrSvO-&sY#61h8SG&RYW3mTY@h+v)~{%gl}S`$>)7i2vAuWYSmTaPGO!Z zb%vf;!p01Gp~y>RoNwJ@FD*9M64yv2ojbU&H?}E@ZOszU4Bs{giC?FKvb}IKn`v*R zD|;2)=N$Mpopbba11O2FRKt`UAG5x8k zm6j@%D;dx-d_=N&%D=OOwRE23o;4iB;Ddz=cmr@1C+Q{tCu9S7sY z>!VEZ01V7GlOmZzHMKrU7>H()OKblez+P^wxNrb{`8aE1UlWBQ6pYO2YjpjK@5TcA z$#~*tW%ee7nYutun1*Civ-KNZxp;9?%5NHiHWM*5Ax^z-6rW^@pUEJOaF2Th-BA+~ zo4i)voeoI-beD&Uv4M1gIO__%yetyOJz^Td3mlV|8wbsgu6gCVvH&9%O~CYbE7(pj zjdLS`_E3|}OT~@Bhe&xwSFNHrvQ81c)alxKwy=hdVSF&HVUbWjjo|5(IyAsg1(ia; zR+%zsL2s|Lnvyc-NYt~-D=&tIC2r6tvs+ZZyn>MB?V%6t8K|lQMj27lN>jUD*^onV z8H&27)MqysLH0CLxB4SD6{n3xy*!Ozj_`0ihq0EBK%Vn?Jg@6Y$Geg5v|s;-LF_7R|p&-rA*GdtCmNL?NuEgMChciwnS5wv#u zY8@4*ZT9K9-!qemSevn4pw;AkIPEKyX=l_PJnZRP+h*| zoZBQh8P?rZ4ZL+cfOn19$hF4Px?aDSZ*d(izugoVo`5R`9(^x=P&~pYc)K{&9{qbV z6kFrwS`3jP$bUFmT@ci8IT+B zO%?}o1iAZiU9|g$+%-RFAl4STOGRR;?wbqE*3oER=^}e`}CR$5J z*oQ#&1o=(12tYoz)?N5_L~cg8Ue)rqiFxld%IdTMJEt}rL6m1zcP}g@06nL;&W*XW zO16OfrmFhB12nazyDoniR_g0TtW_9mFdrK`KM6+t;u15;;Xql%jwyf11{tPE(RsBQ zMK{<@kqE}EO)&yTt0d-ohD2pJ;~Sfk1eHFj6T=jMHHkelu(y3Kw4|!tBKUjoR+WHZ zso1_p4y!DUG}RMIh$hjm0ocAD`&!zch$2%e$fkIq4*!UItK70^KKW^WdQrK9A1sII zR8^Ik$gEF5jb_WPYce4-wMbRKP2<+&VYSDG=>QR*(BdsX%DXl7>K>HpwUxloU*`tJ z!g+=`p+Z^2;a7nlP6=F7=qpBzwQcgOg&(4CeB5lVp7610KNgojZP6ezu4B9X`TKo6 zYUcH^J|$+z+;->(Y4R98aRE}TVxw-@Sw@iI7Zy#2Lv<`DfawOcE)E5ekZlC9^fdPI zcwORIu;HGsQA>OYuBKkvZn%g9q^d3z14)AW*Cg^nEW3}5;s`QO424A+KDPw8C{;`{ zq`TOF3y4!uyV!{0DJm+iOmKUzqrmRzr&r^KmR2ySFPd}$D2M-mCU>DBe1iPx zrL;}xgUK}K+5EBLD7vs6(7iYic0?_A(8s(VhMFiC@X>(&@Af}H zoORuWWeNQ}Vwaa)Juq?pQ_NfrshUAcgw}(Qv1C;(H$`MFGqFYiMv(mpeFH;a!!`7= z@Z1~=8o8uSMJcmkWGe?sRN%FS^oK$n6jC2%_od_~G%3gh>3ousj1FX<8#|5!0S=c| zEYU0tz~TI{p%~jtksMoFMk4O*hhh_9H}>WP*$dGjoP5R?`A()~CW~$DbumoZhse4m z1~;qHQvM4Hm-1weup$j2H{tUKsr-6=`kihpMvmO#n$g*#HnGKBWi_telpCxD_4gqUM^Xx zQ_~{uzQz=ac6d|85U42MIOMyYewv@Ua^=o*P9p}zW3lX?EPk$skM#UdOW%aEaM7h6 z+bIvrH7y=dtM~?nOSdbpG#+Bi?@jHGC<)WTly@0oFONTvhdwJkVF^+7n8FS``asx8 zR{3X(=aAOjHB3ZZ6~)!pDqKWGQ+Ck!o-8*znWFtDBx!}TtN5Gu+?!&3BI`FG+Z>X# zsN3xo+Rqo`>N56qmc>j=2gA~8<~}W->vHq_>MDgAxoPc>WGCHtx{>0k#e7^aw%1&2 z+7Q&?vJ_eVU9LV|0;E)1s7Rv(qz&WwjO{DKgb%3jiM*M>Yl^pO?-B@gRcI_&yEeJ* zCloiIrS)MES~OQ;9IA8eZHJIWeoB*!X} z8O@rM@~N5W2D7C}5x?*i`B#%gI*Jzas7km3vj9!?^pe!13`u^;)d{h=0z?}Ag>j4F z$lw!N03*_pLaRJhemy5{e=!$)^atANgZWUbA7?x;y;_?&Q~N{UVMYn%-XTo+6mFOc z_Kg0yVh(Le?FvX`bANUV|Dn8)9#tu~_*9 zbL%ClAYI}k654D($5I;Hd>Uh~{DKzUZrZlRk`_8;6_2as$O0u(%ax@TLAN=c zF3hT8lz7_(Mcyi6Ixb-4N+{#R+9W=?U`O<5H^X?yCh~-xyFO#WE*x35)UO%zVSyfG zxThjLlhZX58}&GY&0V5!ld1ud1QQI0MujaCkD%Oaun@bZ0Yr%!TP-}`{Q%y5%BfqDki``N`x zlclFwo|4ri*LxXA8|ml}hwiDPQWh4l77^Ma*t*~x4HBXJrAotPFE-)z5!Z6`TM)Wj zyzPzIcV%f2QVmFi6zPY+=?O`HOeksQsR=R4876a7{W7Ethz9;MW@lWRtwojbCU!0D z{lGiEoE8hwgl3|$i=FMVewFo>?-Q?(p6u_rORG}oDC3b{neIipg4TY(GfDl|&lECF zoqb>Sj~-T?7^5|F3RqTP5PX_{FK(!a_W+EnBylu3wQ2|uv8snn9H47S$(K`EMc($- z2}fvDYk%d(hn0e&G(Lv*Vf&Bn$@h#sc?SXiApIOj-|9wY9>(UWWXlwGAtpFg1!l7D z8%N?o?^O_EsVh^KZ%60nh?ZbHmCG5OYAKf6b9Z8N{+#Sn`3fz`^z%M7wr=?HD|d65 zLG`P!ENNIOy1`58w>C8$R|o2lE(hUPGIgG~S|UZUu(xPmpC5yL-ETzSywNjV9RugD zNl+o|_i@jV+8%F4G~q~Qfd=Y z4KIU2<6%DlE;i;slxY1b-y0WE=jr?g)8T%I&pb>s_v;!twb6FIHQc`YZYvM_VZK>r zN1A(#Wq{T(qr?)dfiC^{ak-fqO1V<_d^QQ=kXP*<$L?S$9Cbq(^6E~nBi8cZ7zOUWqr{U>z)!@d;^}Sq5nFB>)PTs z3A3kMQe%GBFZKwBClS5t@nlj?spGTvEdt?y>wTw+C{->9H{o=Y$g67U9Bi`DVb8HN zAC4P@1?~EX5ALT;78Lp;$$h#GODvg9O2RqeQR{^GuHQ`4WIw*u6eN2R7Nuc}%Todd z_M)is+Vb%wH)P&3*FSN2h~UCJw1Kd>;Qj0ym2FhSdqMVomc zdcHC$+%=9l#Jl{~1<9pz(oIV;fK~&=!60GTG0j2MuV1%Y8Y7XXzpRXfH_O6B<5FoT z(_9E*;IaRd9~}Eepetq9o^h^sK3LhSSN&Scv13%wrJ`2`0`m6}`|C(;&9A&S>R;Ba z&@rS3NMGWm zTjm_saM8^8{7g^PgE<fV` zDg6ozx^h1_Tn<9Hwqj>*$0PS~BBMlOo{(?se5pHXv0M?hM2jaF3v$*2-`Ue&yTP3| zEU!OdmeL^U`;%#u+l{KzjjMJ-BY@G_7KpMxg7SXwsC%-kk<&7H`8drg7*Fyd>?h=Q zPmf@tB14IKS4Rmy2g=uX&%m?kQqmRjMEbjlP~&PIIilxPR}Q-bGniuKkJ!&spZ!6GjQMOw-1t+{e7u(bkR54$?CH0^_Jt33+*essQHE}I!1Q?%FBf(o=0d5*zYzmUXQ+IRsJs%bELH?#)7yl}|C~uu$a}JdF&;A4 z;QWVv?Nu26rm!}fw|p8uC}huuVLeoke5V7P)_AGeqzcdX^fR_<>9$9+9cg{=+Dz|) zPWfbCuaBbT%U*UXzidc028gR=Rq9B8KwvG$Mq#1yp74kxi7GE?x(3H|9?|y~?G@ZJ z5>Echk%{l_5S2? z1k=q~7%ge~`!03OTe7w6-qtm?V1WTN`4uF>smJL3Rrz8^K4nQbc@vYKOA|qzMjql` zBHualy=136&+2_LgQoA z#)xH~S)6C-d2E3RjCDNhZ6|L-GJ0S$8q9ycpgGxGXm?bS3f138;hf7&Tb;6%3Hlgo z)Vk^UmF~RyhQlFXlb$D%#}Mb(*OqGZdx&aD5@c_krGd$qVx>Qevgyv^g75G7hczE- zCRPO&irl$*VW5`aSm+OuXI+13Fi&gC+w^e%P=$BHC{<;8f!fz11blFnE9e8_xd@kt zo*0GQpUd|Ltu-%aCPRKfl#P@x+zavzWC}ebd>1T~eYB2*cSpV#EHDn56GxS*<(bjsiuxRMT*J|E~)QFC)X34R*>510KH&aNi%zXsH~h8e}td&suy4$q-*!KqnjXJ^nSC`-N{Ixe1!xw{VLZ zoupOP;mY-B$3{UvTctHv0T`Es47Zxq=j8u@|FXW%O(06lH)on>E@ynrXd2*+o{NxM zakll5(7nX{gLuE9b2jxQ?Wkn2=sU zN57l9WzmmgX`Al>Mt8>JK3mb8wXN+RosiMD4B{SXjoUaTj)|&9m!{jOKBdE|Gp41w zZT|8hfUYOqN5X`+bhTYkqH`nnoOHvdJVQ zJa{!7zgmIFoMnDsi&NIu>RrmZBu#JS*q_MlO$c~lw!H<0Bij(pycNq8Urioqy`tsq zyQB~Ol7f;=#Bi_Ax@k@>yLoSrxRci|e0vQ^@c(_JEu%Mhj-WAsUmx%;V!zph7Vy4) z{)ah;OGxO(t8nT%Oybu@#j|0~$?r*KO50I&mR!S1AISODxC3ZA`axb~)W}6DH~z{3 z%IvAbhyg#wXl%DGLG+^Qb)GK&h4zQlk4MP3h|96BN*yBvZ$iz++prt2D#1p_#e*o} covjNBJdY)RU>8^N&yibMNhJx0m~rs`0nmse{{R30 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/applist.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/applist.png new file mode 100644 index 0000000000000000000000000000000000000000..81aecad314289639a29ae258961b9bf2f1ee87ec GIT binary patch literal 11689 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ℜ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 UKa~O_)hH;6vT8C7Qs!a*0sJ2cUjP6A literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/appuninstall.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/appuninstall.png new file mode 100644 index 0000000000000000000000000000000000000000..711149d214f5b97ef411a097296eb38a1f7e721e GIT binary patch literal 10092 zcmV-yCzIHTP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRaN@<~KNRCwC#op+FBSAFL{=bRf}>VBQOrzdHo8A&6}2x*iv5&{FpfWaVQt=BGZ z@Y+j(U2A*2ly?nY%68eVwac!h@ER!ZfMd7#?pn5N_4@|~2JRXh>?;=v0lx2L*X2jM-6lzr->%miOiYaLoSK^c zMy)pcS!?Z+<#Gif1mIqI6mrI)5CW4#q*@P_dj>x-yyC)NAMRg9Uyq0HFaCeUVv%C8 zNVQsJ*|L$fjYi``larGlI(+!>52vQ4KO9H#maeX@^9~sAJVpY6AZax4%9Rf;yKLj% z4lP^W)fIqBq1kjuY4ALYloo3(&bhhKdEH?>Qc8x0hw1I>y>nuG;^}>R_kOO?sQ-p@ zt|bb=tALz}LkSD**+!+ZeDn*;uDtfm#gdO}L8Adu$A~mVNsZ@&?`M2H+wEYCL2HdM z25T+GWIS9-iBgKe!9jX@d){|o|A9Ae-@fCHYB7Au^9q~~7Qm7LDSA@+!d(#wQ5Hg^ zO9w*=o66?&)O57smev2*fAPi}96oUqOl)xN2ro?uaD=|VLm-4iDdrYbN{N(mj#8|( za{x&xNz;@d2w1abO;1-><;fSe@A$nV6Rm&ng34MUtesad5JCv)d1{NVWK%1N6ar)2 z8Dnxw2IOEv|4u{8Khtp&>xCf1lHM6=kz?HV3rXj_;}m{tu!g z+i!)yM=tR`&ln(^w@+NvtotkrL%enkCnQ4pFIi9uAa)8jGsP_%irnzp%Y`Pv5D`VQ zB&LK^Rjg1LV=+!(oWt5|;iSvh)R+i0?SADMb@xe)xI-j0z%5c(cx2#=)$vVOGsz@s~&_a4$!D$>Kv9>At4 zDky-Erv;1vQYT1SEpA?^xbcoF&?wq*M3lC0R^Sx`E)KD}gth`tkO5+H5X6b8q{Ffn zQj1gy<#`xmNwubxBrF?U!QH=bGk@_<-{W93K-tgUuoWllIWqOO3rG4tl%%>@DTOE{ zP*S3VK=bk{X-fuVsJHvRYEO%HvqkC+BE2$=!#imnK7vvnL7{lc`8uE(87}KixZ}nf z2xXbsu?B4$_h3 zLlCh3vdekfO$Yd^uRTGn(ofNI7~|Ns@5sP#werTEa`8(=KcEDhK?W(xo5eW~Yx_v0hi5Iuf-!SzeH4Wp4~Rf1m4gxBdmd6L zj7~|7!B>hm-F_24dU7Y~&e;+C*nq1@F)Aq*&2Dy-RXEmz(34wkLElF3?&J$v^v zRjV`8Xfa)H&W(xLCgW2xY#b@G>C$z?ZA08hNa_hHlF$Ov0uw2OOHjcKBA7)>M8w=T$kP0sd34#FM_fejQ?|CStNTL|h7_V63?i(*9)J^tH&N5wZl4{NO z9((TQt-B90+~3V3JNEp|WW6bkHO#i6+h069v45r+eXJM+1fIez0hlFINIfxBOWrq1 zFgV=zomQOUeg1DD<2#nF##DW2#1=a|hm3Wml zDma4hid4(p9Ncz*pFHp+N5&4)Xto#_9ANdTm8`$?Qhd*&Haklgh7<|~d_TYoe3Vq6 zQ$(u{^%}BKBTZtwAV8KwUU$h5UwrBy)6JBm-r%Y`RvsSc?&|vFw;%d5V=V0`Icli| zuz!4dKq~p|cAS2{r(F28g758vmnL7949I|QvADf^V~timN`S-7$qQ=?^;(0jYK5+@ z3RsO4*~!E>LK1GdYz?C;S5a@pc)m|qDB`R|>lB@)Xp>^wE~A=MkQnG5(Fifi*S_!r zo__ElQZK|Slrh#~4!l6?-bYzI)XlHH_uZ^oa{;wRi=a@%4+5mM(5xY9Q;2#E8@16| z(@s-nlawm3Zm@?-21`7$uK~Wt;mMgx|LMNRzH(@?7W7t1)Z6h1<)KYA&%Aixu4<{U zs}T4fUp-j*lSY&nJ#TNGSwNN*9f>v%@0xDbQomR&gdS4J+$QK4Ws)Ruxb`eX(<0P` z%t(tgBVNiimt6pUriun(fK(pVm>dvInkJ-4j80NaVo}ydbr<;8&;MV3^1~ghyY^;= zMpsfOgeWO#G+InePqKZ>6MXD1{uh7pNB@*0%ANU{5D0xrdsXz6U zdLDTAj05uJZFK|=hrshS(iHH50Ocv9lpSvfT5HlcLSYdu^DSweFw|G%k~OOUP@W(N z1A91}$?szEpR-m{q>|7a&`ue}unv}==e1%vp~W3o9-yFSCl zYi?lguI>EIC;x#z|LE^got>n0a34{#Nh>upjHPLyZ6J1#I@!%AL)rdm5jCCUS-5d{w)`p4MCL1qU zw)NNFc++*u`nua^g=O^?eQ*{Rc!cF5H7Tgi)`_B+Ql*6N`$(Djo=mFez_8BYtYxUT zo9?bs28Y!+XAr{Wk-1D8Q%d3^35z~ml`>B~d6e0G&~XV}Ye7j&cx=O^z|! ziW%t3tn{%XV?48a92b#297=+dih67a(mI|Wfb_swq!6@|lvbQ_^}3bM{N^v+dgDNM zxqW1&K7Ze58j#SFcmmr_oldm|1Eny)9~oqFVv6bM8pb(1&(DOs$Zjl?Ixe4R$J9=c z(&Q}5E#hP;;%pl!Jv`sT7Y^+!tg{QWJB#N@f*_!1q1|i{`aa8shY<+0(Q}*H;Sg@Y z9bQB?#hx7tkQA8_BxZ}!oPyFsXUw6wuPo+IR z+suJKOMnzSg)eCL^EmBGb2l|*%ipFd+qmVQKW3k#~2?WN{YPEniP@)iM zoYA=p-yJh-J`5MF3>fGtP$?ED1|AozT#gX|_ifol8o{R3eO$eM9ZD&BdwSTt?We36 z?&F#(F6Z#rI7VyCF>V!`3pHa5#bS}c-Y#}Yk=Yx@;H<_vgUBq@Im&fNOqvkI3C+~- zj+?K1(fSATI}n2m&RLZClgEklVgkYY{@w(^sWbF0p&Z3)Jc@ zT1iSu6KfqwJK?z(53zIS^NcL(=kVAhX__ME96EMEz{7$w1cAVaHldd=IaOnDc!0KX zY+QdafhRaTHpcSdAr4MVab&tivE0R;7k6^=Tkm43-eR)Wz!;O+E1igZ7U2Sn;uI``f>;_Uy=zf-jMRx-kYT<#B+- zaZH*d3{*>8dBsNBS^@?kKx;?66=SVM3VF2Id*T;32mQ+elyGzL@{Z8&MDpx{_=oa5 zq9{QdJ*ODV@pN(gr)1pAF}yOM82C8{UEJ;v0%9YWO&agNqLO}8TQJt;vhbz(fL|6s zioQY#+S+LBvB`2mU}bi<&+dGY6(b{5hgOor@!TSGmjv)qlkAdwu}^$f9dm8D@Uz^m z!5VYgF;72GBTbzymqHw{M}-u{*#tyT@C8zk8tt&^_}yTIBlLYHXX?z%Ota?V^~}~S zuc#wSekdy9O%nY%CoRB`GL{5?F0D<^=03jKK30PWtRWe1uJC3So$~<`soW z;v~{}13gNUAkGaSff5uvffCMXZ7`lV!RC=jAqh(rcJDvL`1m-z{ez@Y`icT1b%M52 zZ<4}%`e)67Sh}Sy1%Z-CaK>2d2}s0ZkOB(D5|jInu>asex_bL*$MGu*5EL`c4j#Z^ zu;&Jl?t({8NfIbQnrgIvBAZkYN>IutHL(BS5mv2POS9E}MFFCb7?<3%zRGaX<49`H z0U%SY1dC6c8kbqR_BcQsmQZA>rjUxsi79Hcv$R`nUP%>P20?-i_Sty3FYFQH#MuXA z^Uf&(PchSsC@PE9`uHR==McGU@%(^#ZI-da6BuLX64+h|hXvx)ux@4HwhIR;Pc#y9 z_5tw}_+I9|*4m(?I}VV{NXxP@q*5g9m?Qhg5K_LP0CB)AyncGTdUCRnR zi6SR;lO$+kL7d4Y5@!bqA;4&~PHDALLg92zQIV$d>;s|%ctRj? ziO~j`I}DF;VPcKMYJ>7atkXAnA?hNi=akePKXk@8}p6;H%>x-65e{UwjV zN(lB`03rpxlt@9-7=sq>1ho?uYdstei$M8B3ROS%p1QMx#~CFNi;zBvu|%TCQwJLu zZ;V>|XraD#!&z{@O94`Xz(rc8NTG1Y0OAl?WX`xuH&hCt)S?R}UM7Yk&MK?|-=tX2 z<5Q0uLO;0wI8O0vZ@>O5$Pg*;ltc(pV=P9B69ZzhXqiO^fmK8#hm815TFxX@0=v`9i`CXkS7Pyy*$*pbe1IrN=XE0 zt92fXIzGbZOcu9x*0R{<6FB13QLAfi9loE@@;L3(&vvWm}SubQQJ>7N1{5U!cC6){Ie^0b+P zTfjgTrWP&Mz2R6jwTla{yobXx|C@jRkzcc7(tg3pygQySW-ig4a#M&d(Szeg6XSO$rd>JXk8f~&9v=a@xK&YQ$WL__g za49NuJn+E7Jox2@Sz&tUpDA!;?-WzbNw6{46d^Q%6hY@_y5RNvIXZt6DW0^5Q1b1s ze3xzi@)ItMLfF&h*`0f6L^C)OkyQvqIBRfLoc8<|8)t`Qk)_-Su-W3v6UdOv6KriJ zM8%1PNG5n~=4!#F$iTAor_ZtL``dZbb+@r<^$6pphd7E(6cR#@um8)p*!iVLdH-A9N~I^n8?VtA8|TqhgX=b|p%hjj_fXqR{mQ)| z=QGRd==RQ`jYb=ZItCD99mblx9fn=ReU)4DF4w|j$_vl!L2qsF&Rbqju@W*fK8}!r z(PEjY0|5`UpXH`oE}^GTLF5T~&Sk90i40eFl>L||(iIDQ=WE|*`xhSOJ#Tz7z5U%x zPfZaB$+hJwleHqvnnqL`6pCK1je)QhcfPZ%g~o=>)!IdeJ)PmQ++L-5X!Dai_3$n# zl_I)P$D|21PH3i0HVlo>e<0xg`?oS1*RVPQmmo-SEj2F zc7SmyqU8ADy^rwV=bqs0H{Qn3K$WSnaa@|9qlg|MIdou(Z%#f711$;yura#Rc)*%7 zE<=_Mh{)U^PFQ#H9b$4BajKE+M3NR)Ts+Eu`pBCYD@^c{t=kEt4{?NxW6~&MHm-B+ z=qNqgB=_I{91T5-HAzMhXdpqjBvTH`@W2C4vHAZ!#V>8Tk>vwjOpT4<(v&n#=$4Yh z`zQGN#5OLtbCio#^ny*m##!v&h&ki)^zP&MaaLrAF*cvDRn{1+k%(g~S!*+PHYY*`+oZpsu2M}Ydm(^U@<7A$(F3&K@wJc7qWjQRk7@f9B1#DV3LUKo) zM>jvqO>zUhm4Ifeo`V8b3a;+$=kX_w@Tk9=O`AsO_DU$F@Vk5-ef)X8_4iNn=Fv;I zq`%1cf1Z7T8{T^{H?3bm8nuxKj1gettaikL=xABzH6YreQ;RiD zxQ^j>tV6=OY?mF=RP14%JdcU7HeYBQ;QIHi z`PxtdVNvaHPQZaV^QF<-B>nLEij zunEq^V6!^)P|b>e6|?lIdZ+4{mWJax|) zca&DKVW7ao)Ku;zwp2aE)P&*l%_Cg*zESSnI7Hl@&g;v4AVA6jh<3(qt;>b;`A#8u zNtm_PxttP?%ggGNjh%u*Iz=(gS&U1tHbJ6sLXsvazEa$@VFf>CHxJ&ojcZv$w^TG+ zO`MQe=SZ=X4z@85En~J>cp3gLVPM5DFFS|hBp zVBB#fz(=zz!O1w*+}%3Br8sM{ObVO%&7Ffdfx!2;{mN0COZdmXe1?gw%Xt0Tk*xRC zLO+(y%B+Ra#8Z|nT@6;eWjA+iDq)ilA>D${UKmHoy<*bKT4>mucJ1l)kv!)@9cvW} z45y=R&tz<1j@%t5K}2D6o49=dCoags9VW#|Hy6eQL6W3+R&wW6E8urDU-|4FM(Ta6 zFG_TpWd5gAU1da?5Kr zQh8{K+TlZJqp?Zm_p(WhOH*7er8GOjK=%+vH8Dn`JhdQs#T`c>9RY6VDyiKZNawd< zsB;-XCtiK5``ymTm{U@S%RzC1w6%xWjYF{)f^MWJ;G~Dh&--D_i(_@Re7l$B4>oaI zAETB=h+HU$EDDu*f_r`1Uw?weflHY9t$sFLJWCK|L8{~X{T}_=7%?Z?aOXWBChHxN zJI_uev==57bP^L57wT?~Qji6l)0pHim@%aE^5}~qEE--o*yj8HJV5{bb=v!%A(bG) z5Su&cyr@m;2N=)G!UR=E@!_Ac?Z6nt=uE~txKsCaa~taWpJPTUy=L@u3W zS**4=dy=UN@{A6SZ((x6(di+cFRcg=!plz?!l1>z$r@k#d=K9D41;^NkYI3L*2zKY z1Th;k-n{}VBs3dXtuYQ55L~?b5Qjci!>ywN4*l@B!$qiziIf=J);!9@3`pT77~|Wq(Y}D%A}|x5fAr= z+jt()3-^(;fbqg7?bZuVL%l1r>jc4z+`1}^A<`J&r3N_Yw*o`FT(#0 ztbg){#5N}Jg6t^_CPj?3xUa8|(LWyHUAKd3W=RgIwg?w+%|%`GtbK&t*CzD8>0Jcc zBc7VV8AF;Hbf3pX2llZ0!!Pi?pLn#38mo1tSaq~4Cr&x3R- z*!LyX29JOn)>Y}d_)+%VkTCSN_YydtXlgR+Y^N={>T%JLJ&gasezxowp%EnLBt_(j z*x(Q^hZ=Rp0m;cxoI;Sfm!u*(5GnNpY6os(@JB^@zIzXmiO_{2CI>^*T5RqbX8Ffg z@SZzCH9DT=qo1&oXoJM(`n6U1*FDPK>m!EV@c}}wM0;ii=NzfF*mB5_3Ppb0f9YX`d)6WdC^|LAUdp<+k zw4qeO8jWWSveDv!$}pq<^8()c20;*kQ}eB5=klxbm#MKR5pdnwDt&7oVgC&=%isO0 zlx2~)UeEe1I&fitc;YA2K9%Ci>#?G>fYqLS-lvo?XBCk7)aR41tkZoE?T8;&Mi~8*HN5Zj7O$E0HO*@i=CeFH86UaIoumfge6G8whrSCQ z;)QD(^ndU-sDxdltrpf8igCj3a2Y!Fr=wGaR z?ZSH%=MWGn=7tk8H>^(36E!mk?WqwFSwcaa8U$r-*#J*h9_5L~M*OF*=J3>RhX43N z-hG!v)*+DsaSRk4SNg(7XDnR1M1${Tpg8j&KU}*8|MFYWKm93<-?)GezI~Sd)Y2fp zn1rKi8BesU+}!7OzRnpSN@SzcxN~8P@S`mC)73>31fC&@Elr)$EkZ6^-ez*_VYc19 zf=kzTbMw`8?6jgS#9U0{ID>K_68Y|4cwHKr2xUR3d5adPk_1$kFjP)CIPLR|EhA7Ar`%Ff&X02jNLNA8UGyjg(s9hjT+~uugk4GLu*%~T z-&jX?QL}cqNxdnlwGC2`lb`Q|kgXM%+>Am< zq%5N~q^Uz&kirog#b-9JX8VgH$Uf5v>@TX=bQL}Nx<SjrExTWU85x8pmuq>xnDm z2}t&|NmwAeE&C1+@oS%~FgjcVlZ8-SE-kI?v|-Pbgt@>>>oDKF9#sYqQGMlTo-39Gpog1rf7L@MSF-kS{!bXzro!p)X0(#Z}qU zQhc36_BfKL% z{5}5qNBd5CYk&BAX91AZWNvqvKMX|(v55QK&If-^35r03Kxj{*W4e?1iBC#}r~due zcRNiRD$-e@{J9kB^8y`CmT~{mJUu_3eHhEtAnOyqgy}E+dFl&3JWfrP-R>PPy9KY@ z!X z`Hwd?p%|F<-Isg+Oyd3Km!EaiV?$TyIKw&0=K;$SL{WQPqdrUXT*?r$P+UuBX@@WT z55N7=V4zFZ-~IV#74=BaQ?NhhI@GCE>6cmpeMSH|Ue$FZh{Vat-EX*5Y_1mSfBV@j zFw+L9-Mj(!N>RHy(M0W#Qr11+!}HEz8qgwUIZ3LqUg_^{S{Hs}w6Fc8Pd-?``o)

>{V9l+d<6y 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_bookmark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..82f18a7750326c2c2642e518e8703685690e3fc1 GIT binary patch literal 7078 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_check_default.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_check_default.png new file mode 100644 index 0000000000000000000000000000000000000000..cf411b455252f1ccd8bb6156490c88abb4d14fcb GIT binary patch literal 8569 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_check_selected.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_check_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..88b1110261049a5768a200beb3ec64e251257e49 GIT binary patch literal 12609 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 j0q0pSZz}L3Yur={ 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 Y5751+GwB-bumAu607*qoM6N<$g2tis3IG5A literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_logo.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ca46dfb347d6965411975945e08fe2c59aeaa5fc GIT binary patch literal 6475 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 VkPva6-|ycW%JMKsiL9~z{{X^0KqUYG literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_logo_dark.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/ic_logo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ca46dfb347d6965411975945e08fe2c59aeaa5fc GIT binary patch literal 6475 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 VkPva6-|ycW%JMKsiL9~z{{X^0KqUYG literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/info.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/info.png new file mode 100644 index 0000000000000000000000000000000000000000..78b917243fe06ee4285fd23acfaa765860f0d5f6 GIT binary patch literal 12733 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 F{{vR1t=Rwo literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/location.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/location.png new file mode 100644 index 0000000000000000000000000000000000000000..3c93225bb004916c4dd0bdb60512c5a353ad9611 GIT binary patch literal 13926 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 L5mYT^9Q=O(dlrfa literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/repeat_bg.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/repeat_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..b15eedd675879df70ffd866b85cc70ff59cd3733 GIT binary patch literal 16939 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

@w9PXH786-xwV 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/wipe.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xhdpi/wipe.png new file mode 100644 index 0000000000000000000000000000000000000000..ca047ab527bbcc39c6bcb7e799738eadbf2b4890 GIT binary patch literal 14301 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 a=l=tlWajt_-Riyo0000RnD)5k1)n&3W|M}kk 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_launcher.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..2c36d39e78e4410901ba46e8461adc4bf845cc72 GIT binary patch literal 9581 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 literal 0 HcmV?d00001 diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_logo.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable-xxhdpi/ic_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..993ef9971fa6e91196686992607f0df7a1e4501f GIT binary patch literal 10459 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 + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/btn_orange.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/btn_orange.xml new file mode 100644 index 0000000000..c67fa13d1e --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/btn_orange.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/custom_checkbox.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/custom_checkbox.xml new file mode 100644 index 0000000000..a0ad1a1a42 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/custom_checkbox.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/dot.png b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/drawable/dot.png new file mode 100644 index 0000000000000000000000000000000000000000..7a3361fbec1fd1236c57bd34be595a5aaf9434eb GIT binary patch literal 85 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61|)m))t&+=8BZ6-5RU7~KmPx>KU~kIz + + + + + + + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_agent_settings.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_agent_settings.xml new file mode 100644 index 0000000000..ad864a9649 --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_agent_settings.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_alert.xml b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_alert.xml new file mode 100644 index 0000000000..50232ae14c --- /dev/null +++ b/product/modules/tools/mdm-android-agent-archetype/src/main/resources/archetype-resources/res/layout/activity_alert.xml @@ -0,0 +1,35 @@ + + + + + + +