summaryrefslogtreecommitdiffstats
path: root/mobile/android/android-components/components/ui
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/android-components/components/ui')
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/README.md19
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/build.gradle40
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/src/main/AndroidManifest.xml4
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/src/main/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditText.kt905
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/src/main/res/values/attrs.xml9
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/src/test/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditTextTest.kt585
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker2
-rw-r--r--mobile/android/android-components/components/ui/autocomplete/src/test/resources/robolectric.properties1
-rw-r--r--mobile/android/android-components/components/ui/colors/README.md19
-rw-r--r--mobile/android/android-components/components/ui/colors/build.gradle40
-rw-r--r--mobile/android/android-components/components/ui/colors/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/ui/colors/src/main/AndroidManifest.xml4
-rw-r--r--mobile/android/android-components/components/ui/colors/src/main/java/mozilla/components/ui/colors/PhotonColors.kt178
-rw-r--r--mobile/android/android-components/components/ui/colors/src/main/res/values/photon_colors.xml219
-rw-r--r--mobile/android/android-components/components/ui/fonts/README.md19
-rw-r--r--mobile/android/android-components/components/ui/fonts/build.gradle31
-rw-r--r--mobile/android/android-components/components/ui/fonts/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/ui/fonts/src/main/AndroidManifest.xml4
-rw-r--r--mobile/android/android-components/components/ui/fonts/src/main/res/values/roboto_fonts.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/README.md19
-rw-r--r--mobile/android/android-components/components/ui/icons/build.gradle31
-rw-r--r--mobile/android/android-components/components/ui/icons/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/AndroidManifest.xml4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_asleep.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_confused.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_eye_roll.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_hourglass.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_inspect.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_lock.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_no_internet.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_question_file.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_shred_file.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_surprised.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_unplugged.svg4
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_add_to_homescreen_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_space_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_down_left_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_left_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_right_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_arrow_clockwise_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_slash_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_24.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_fill_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_info_circle_fill_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_warning_circle_fill_24.xml22
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_back_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_20.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_24.xml14
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_badge_fill_20.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_20.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_slash_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_fill_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_briefcase.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_broken_lock.xml21
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_slash_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cart.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_checkmark_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_20.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_8.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_left_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_right_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_20.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chill.xml19
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_circle.xml9
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_clipboard_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_collection_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_competitiveness_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_slash_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_copy_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_credit_card_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_fill_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_20.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_20.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cryptominer_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_data_clearance_24.xml14
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_debug_drawer_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_delete_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_send_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_mobile_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dollar.xml19
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_download_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dropdown_arrow.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_edit_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_horizontal_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_vertical_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_experiments_24.xml28
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_cog_24.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_fill_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_external_link_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_slash_24.xml24
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fence.xml13
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fingerprinter_24.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_add_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_font.xml14
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_food.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_forward_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fruit.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_gift.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_globe_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid.xml13
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid_add_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_fill_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_history_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_home_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_slash_24.xml24
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_fill_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lightbulb_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_link_24.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_slash_24.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_20.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_20.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_20.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_24.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_login_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_chrome_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_firefox_24.xml14
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_safari_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_slash_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_more_grid_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_mozilla.xml7
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_night_mode_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_dot_badge_fill_20.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_slash_24.xml24
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_open_in.xml7
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_packaging_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_fill_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_passkey_24.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pause_badge_fill_16.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_permissions_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pet.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_badge_fill_16.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_fill_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_filled.xml13
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_24.xml20
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_fill_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_play_badge_fill_16.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plugin_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plus_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_preferences.xml14
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_price_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_print_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_24.xml14
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_20.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_24.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_48.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_stroke_20.xml22
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_qr_code_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_quality_24.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_fill_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_add_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reorder.xml7
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket_filled.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_file_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_search_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_select_all.xml13
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_settings_24.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_android_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_apple_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_slash_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shipping_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shopping_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_social_tracker_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sparkle_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_fill_20.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_half_fill_20.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_one_half_fill_20.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_stop.xml13
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_slash_24.xml24
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_tabs_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab.xml13
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_badge_fill_20.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_new.xml13
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_number_24.xml17
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_tray_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_themes_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tool_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_translate_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tree.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_update_circle_24.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_vacation.xml26
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_24.xml18
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_fill_24.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_web_extension_default_icon.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_whats_new_24.xml16
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/values/attrs.xml12
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/values/colors.xml15
-rw-r--r--mobile/android/android-components/components/ui/icons/src/main/res/values/mozac_ui_icons_strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/.gitignore1
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/README.md37
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/build.gradle50
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/AndroidManifest.xml8
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounter.kt348
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounterMenu.kt101
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_bar.xml11
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_box.xml15
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_round_rectangle_ripple.xml13
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/layout/mozac_ui_tabcounter_layout.xml50
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-am/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ar/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ast/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-be/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bg/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bn/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-br/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bs/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ca/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cak/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ceb/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ckb/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-co/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cs/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cy/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-da/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-de/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-dsb/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-el/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rCA/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rGB/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eo/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rAR/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rCL/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rES/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rMX/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-et/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eu/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fa/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ff/strings.xml7
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fi/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fr/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fur/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fy-rNL/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gd/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gl/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gn/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hi-rIN/strings.xml15
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hr/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hsb/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hu/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hy-rAM/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ia/strings.xml18
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-in/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-is/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-it/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-iw/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ja/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ka/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kaa/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kab/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kk/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kmr/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ko/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lo/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lt/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-my/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nb-rNO/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ne-rNP/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nl/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nn-rNO/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-oc/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-or/strings.xml11
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rIN/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rPK/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pl/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rBR/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rPT/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-rm/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml11
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ru/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sat/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sc/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-si/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sk/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-skr/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sl/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sq/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sr/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-su/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sv-rSE/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-szl/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-te/strings.xml13
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tg/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-th/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tl/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tr/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-trs/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tt/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tzm/strings.xml9
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ug/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uk/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ur/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uz/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-vi/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-yo/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rCN/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rTW/strings.xml17
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values/attrs.xml11
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values/colors.xml9
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values/dimens.xml8
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/main/res/values/strings.xml20
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterMenuTest.kt53
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterTest.kt70
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker2
-rw-r--r--mobile/android/android-components/components/ui/tabcounter/src/test/resources/robolectric.properties1
-rw-r--r--mobile/android/android-components/components/ui/widgets/README.md19
-rw-r--r--mobile/android/android-components/components/ui/widgets/build.gradle51
-rw-r--r--mobile/android/android-components/components/ui/widgets/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/AndroidManifest.xml4
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/Extentions.kt37
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/SnackbarDelegate.kt55
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayout.kt216
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/WidgetSiteItemView.kt106
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetector.kt192
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt90
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt237
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt189
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt81
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/drawable/mozac_widget_favicon_background.xml17
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/drawable/rounded_button_background.xml18
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/layout/mozac_widget_site_item.xml77
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-am/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ar/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ast/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-azb/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-be/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-bg/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-br/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-bs/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ca/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-cak/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-co/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-cs/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-cy/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-da/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-de/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-dsb/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-el/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rCA/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rGB/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-eo/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rAR/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rCL/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rES/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rMX/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-es/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-et/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-eu/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-fa/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-fi/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-fr/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-fur/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-fy-rNL/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-gd/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-gl/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-gn/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-hr/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-hsb/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-hu/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-hy-rAM/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ia/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-in/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-is/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-it/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-iw/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ja/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ka/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-kaa/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-kab/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-kk/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-kmr/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ko/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-lo/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-nb-rNO/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-nl/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-nn-rNO/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-oc/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rIN/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rPK/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-pl/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rBR/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rPT/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-rm/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ro/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ru/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-sat/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-sc/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-si/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-sk/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-skr/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-sl/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-sq/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-sr/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-su/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-sv-rSE/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-tg/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-th/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-tr/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-trs/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-tt/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-ug/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-uk/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-vi/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rCN/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rTW/strings.xml5
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values/attrs.xml19
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values/colors.xml10
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values/dimens.xml14
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values/strings.xml8
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/main/res/values/styles.xml63
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/TestUtils.kt73
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayoutTest.kt430
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/WidgetSiteItemViewTest.kt93
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetectorTest.kt231
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt221
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt575
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/TestUtils.kt62
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt712
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt113
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker2
-rw-r--r--mobile/android/android-components/components/ui/widgets/src/test/resources/robolectric.properties1
456 files changed, 11995 insertions, 0 deletions
diff --git a/mobile/android/android-components/components/ui/autocomplete/README.md b/mobile/android/android-components/components/ui/autocomplete/README.md
new file mode 100644
index 0000000000..da22f2fea5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/README.md
@@ -0,0 +1,19 @@
+# [Android Components](../../../README.md) > UI > Autocomplete
+
+A set of components to provide autocomplete functionality.
+
+## Usage
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:ui-autocomplete:{latest-version}"
+```
+
+## License
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/
diff --git a/mobile/android/android-components/components/ui/autocomplete/build.gradle b/mobile/android/android-components/components/ui/autocomplete/build.gradle
new file mode 100644
index 0000000000..16f9792a02
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/build.gradle
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ namespace 'mozilla.components.ui.autocomplete'
+}
+
+dependencies {
+ implementation ComponentsDependencies.androidx_appcompat
+
+ implementation project(":support-base")
+ implementation project(":support-utils")
+
+ testImplementation project(":support-test")
+
+ testImplementation ComponentsDependencies.androidx_test_junit
+ testImplementation ComponentsDependencies.testing_robolectric
+}
+
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description)
diff --git a/mobile/android/android-components/components/ui/autocomplete/proguard-rules.pro b/mobile/android/android-components/components/ui/autocomplete/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/ui/autocomplete/src/main/AndroidManifest.xml b/mobile/android/android-components/components/ui/autocomplete/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e16cda1d34
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<manifest />
diff --git a/mobile/android/android-components/components/ui/autocomplete/src/main/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditText.kt b/mobile/android/android-components/components/ui/autocomplete/src/main/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditText.kt
new file mode 100644
index 0000000000..c029f226eb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/src/main/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditText.kt
@@ -0,0 +1,905 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.autocomplete
+
+import android.content.ClipboardManager
+import android.content.Context
+import android.content.Context.INPUT_METHOD_SERVICE
+import android.graphics.Rect
+import android.os.Build
+import android.provider.Settings.Secure.DEFAULT_INPUT_METHOD
+import android.provider.Settings.Secure.getString
+import android.text.Editable
+import android.text.NoCopySpan
+import android.text.Selection
+import android.text.Spannable
+import android.text.Spanned
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.text.style.BackgroundColorSpan
+import android.text.style.ForegroundColorSpan
+import android.util.AttributeSet
+import android.view.KeyEvent
+import android.view.MotionEvent
+import android.view.View
+import android.view.accessibility.AccessibilityEvent
+import android.view.inputmethod.BaseInputConnection
+import android.view.inputmethod.EditorInfo
+import android.view.inputmethod.InputConnection
+import android.view.inputmethod.InputConnectionWrapper
+import android.view.inputmethod.InputMethodManager
+import androidx.annotation.VisibleForTesting
+import androidx.appcompat.widget.AppCompatEditText
+import mozilla.components.support.base.Component
+import mozilla.components.support.base.facts.Action
+import mozilla.components.support.base.facts.Fact
+import mozilla.components.support.base.facts.collect
+import mozilla.components.support.utils.SafeUrl
+import androidx.appcompat.R as appcompatR
+
+typealias OnCommitListener = () -> Unit
+typealias OnFilterListener = (String) -> Unit
+typealias OnSearchStateChangeListener = (Boolean) -> Unit
+typealias OnTextChangeListener = (String, String) -> Unit
+typealias OnDispatchKeyEventPreImeListener = (KeyEvent?) -> Boolean
+typealias OnKeyPreImeListener = (View, Int, KeyEvent) -> Boolean
+typealias OnSelectionChangedListener = (Int, Int) -> Unit
+typealias OnWindowsFocusChangeListener = (Boolean) -> Unit
+
+typealias TextFormatter = (String) -> String
+
+/**
+ * Aids in testing functionality which relies on some aspects of InlineAutocompleteEditText.
+ */
+interface AutocompleteView {
+
+ /**
+ * Current text.
+ */
+ val originalText: String
+
+ /**
+ * Apply provided [result] autocomplete result.
+ */
+ fun applyAutocompleteResult(result: InlineAutocompleteEditText.AutocompleteResult)
+
+ /**
+ * Notify that there is no autocomplete result available.
+ */
+ fun noAutocompleteResult()
+}
+
+/**
+ * A UI edit text component which supports inline autocompletion.
+ *
+ * The background color of autocomplete spans can be configured using
+ * the custom autocompleteBackgroundColor attribute e.g.
+ * app:autocompleteBackgroundColor="#ffffff".
+ *
+ * A filter listener (see [setOnFilterListener]) needs to be attached to
+ * provide autocomplete results. It will be invoked when the input
+ * text changes. The listener gets direct access to this component (via its view
+ * parameter), so it can call {@link applyAutocompleteResult} in return.
+ *
+ * A commit listener (see [setOnCommitListener]) can be attached which is
+ * invoked when the user selected the result i.e. is done editing.
+ *
+ * Various other listeners can be attached to enhance default behaviour e.g.
+ * [setOnSelectionChangedListener] and [setOnWindowsFocusChangeListener] which
+ * will be invoked in response to [onSelectionChanged] and [onWindowFocusChanged]
+ * respectively (see also [setOnTextChangeListener],
+ * [setOnSelectionChangedListener], and [setOnWindowsFocusChangeListener]).
+ */
+@Suppress("LargeClass", "TooManyFunctions")
+open class InlineAutocompleteEditText @JvmOverloads constructor(
+ ctx: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = appcompatR.attr.editTextStyle,
+) : AppCompatEditText(ctx, attrs, defStyleAttr), AutocompleteView {
+
+ data class AutocompleteResult(
+ val text: String,
+ val source: String,
+ val totalItems: Int,
+ ) {
+ fun startsWith(text: String): Boolean = this.text.startsWith(text)
+ }
+
+ private var commitListener: OnCommitListener? = null
+ fun setOnCommitListener(l: OnCommitListener) { commitListener = l }
+
+ private var filterListener: OnFilterListener? = null
+ fun setOnFilterListener(l: OnFilterListener) { filterListener = l }
+ fun refreshAutocompleteSuggestions() { filterListener?.invoke(originalText) }
+
+ private var searchStateChangeListener: OnSearchStateChangeListener? = null
+ fun setOnSearchStateChangeListener(l: OnSearchStateChangeListener) { searchStateChangeListener = l }
+
+ private var textChangeListener: OnTextChangeListener? = null
+ fun setOnTextChangeListener(l: OnTextChangeListener) { textChangeListener = l }
+
+ private var dispatchKeyEventPreImeListener: OnDispatchKeyEventPreImeListener? = null
+ fun setOnDispatchKeyEventPreImeListener(l: OnDispatchKeyEventPreImeListener?) { dispatchKeyEventPreImeListener = l }
+
+ private var keyPreImeListener: OnKeyPreImeListener? = null
+ fun setOnKeyPreImeListener(l: OnKeyPreImeListener) { keyPreImeListener = l }
+
+ private var selectionChangedListener: OnSelectionChangedListener? = null
+ fun setOnSelectionChangedListener(l: OnSelectionChangedListener) { selectionChangedListener = l }
+
+ private var windowFocusChangeListener: OnWindowsFocusChangeListener? = null
+ fun setOnWindowsFocusChangeListener(l: OnWindowsFocusChangeListener) { windowFocusChangeListener = l }
+
+ // The previous autocomplete result returned to us
+ var autocompleteResult: AutocompleteResult? = null
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ set
+
+ // Length of the user-typed portion of the result
+ private var autoCompletePrefixLength: Int = 0
+
+ // If text change is due to us setting autocomplete
+ private var settingAutoComplete: Boolean = false
+
+ // Spans used for marking the autocomplete text
+ private var autoCompleteSpans: List<Any>? = null
+
+ // Do not process autocomplete result
+ private var discardAutoCompleteResult: Boolean = false
+
+ val nonAutocompleteText: String
+ get() = getNonAutocompleteText(text)
+
+ override val originalText: String
+ get() = text.subSequence(0, autoCompletePrefixLength).toString()
+
+ /**
+ * The background color used for the autocomplete suggestion.
+ */
+ var autoCompleteBackgroundColor: Int = {
+ val a = context.obtainStyledAttributes(attrs, R.styleable.InlineAutocompleteEditText)
+ val color = a.getColor(
+ R.styleable.InlineAutocompleteEditText_autocompleteBackgroundColor,
+ DEFAULT_AUTOCOMPLETE_BACKGROUND_COLOR,
+ )
+ a.recycle()
+ color
+ }()
+
+ /**
+ * The Foreground color used for the autocomplete suggestion.
+ */
+ var autoCompleteForegroundColor: Int? = null
+
+ private val inputMethodManger get() = context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
+
+ @SuppressWarnings("ReturnCount")
+ private val onKeyPreIme = fun (_: View, keyCode: Int, event: KeyEvent): Boolean {
+ // We only want to process one event per tap
+ if (event.action != KeyEvent.ACTION_DOWN) {
+ return false
+ }
+
+ if (keyCode == KeyEvent.KEYCODE_ENTER) {
+ // If the edit text has a composition string, don't submit the text yet.
+ // ENTER is needed to commit the composition string.
+ val content = text
+ if (!hasCompositionString(content)) {
+ commitListener?.invoke()
+ return true
+ }
+ }
+
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ removeAutocomplete(text)
+ return false
+ }
+
+ return false
+ }
+
+ private val onKey = fun (_: View, keyCode: Int, event: KeyEvent): Boolean {
+ if (keyCode == KeyEvent.KEYCODE_ENTER) {
+ if (event.action != KeyEvent.ACTION_DOWN) {
+ return true
+ }
+
+ commitListener?.invoke()
+ return true
+ }
+
+ // Delete autocomplete text when backspacing or forward deleting.
+ return (
+ (
+ keyCode == KeyEvent.KEYCODE_DEL ||
+ keyCode == KeyEvent.KEYCODE_FORWARD_DEL
+ ) &&
+ removeAutocomplete(text)
+ )
+ }
+
+ private val onSelectionChanged = fun (selStart: Int, selEnd: Int) {
+ // The user has repositioned the cursor somewhere. We need to adjust
+ // the autocomplete text depending on where the new cursor is.
+ val text = text
+ val start = text.getSpanStart(AUTOCOMPLETE_SPAN)
+
+ val nothingSelected = start == selStart && start == selEnd
+ if (settingAutoComplete || nothingSelected || start < 0) {
+ // Do not commit autocomplete text if there is no autocomplete text
+ // or if selection is still at start of autocomplete text
+ return
+ }
+
+ if (selStart <= start && selEnd <= start) {
+ // The cursor is in user-typed text; remove any autocomplete text.
+ removeAutocomplete(text)
+ } else {
+ // The cursor is in the autocomplete text; commit it so it becomes regular text.
+ commitAutocomplete(text)
+ }
+ }
+
+ private val isAmazonEchoShowKeyboard: Boolean
+ get() = INPUT_METHOD_AMAZON_ECHO_SHOW == getCurrentInputMethod()
+
+ public override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+
+ if (this.keyPreImeListener == null) { this.keyPreImeListener = onKeyPreIme }
+ if (this.selectionChangedListener == null) { this.selectionChangedListener = onSelectionChanged }
+
+ setOnKeyListener(onKey)
+ addTextChangedListener(TextChangeListener())
+ }
+
+ public override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)
+
+ // Make search icon inactive when edit toolbar search term isn't a user entered
+ // search term
+ val isActive = !TextUtils.isEmpty(text)
+
+ searchStateChangeListener?.invoke(isActive)
+
+ if (gainFocus) {
+ resetAutocompleteState()
+ return
+ }
+
+ removeAutocomplete(text)
+
+ try {
+ restartInput()
+ inputMethodManger?.hideSoftInputFromWindow(windowToken, 0)
+ } catch (ignored: NullPointerException) {
+ // See bug 782096 for details
+ }
+ }
+
+ override fun setText(text: CharSequence?, type: BufferType) {
+ val textString = text?.toString() ?: ""
+ super.setText(textString, type)
+
+ // Any autocomplete text would have been overwritten, so reset our autocomplete states.
+ resetAutocompleteState()
+ }
+
+ /**
+ * Sets the text of the edit text.
+ * @param text The text to set.
+ * @param shouldAutoComplete If false, [TextChangeListener] the text watcher will be disabled for this set.
+ */
+ fun setText(text: CharSequence?, shouldAutoComplete: Boolean = true) {
+ val wasSettingAutoComplete = settingAutoComplete
+
+ // Disable listeners in order to stop auto completion
+ settingAutoComplete = !shouldAutoComplete
+ setText(text, BufferType.EDITABLE)
+ settingAutoComplete = wasSettingAutoComplete
+ }
+
+ /**
+ * Appends the given text to the end of the current text.
+ * @param text The text to append.
+ * @param shouldAutoComplete If false, [TextChangeListener] text watcher will be disabled for this append.
+ */
+ fun appendText(text: CharSequence?, shouldAutoComplete: Boolean = true) {
+ val wasSettingAutoComplete = settingAutoComplete
+
+ // Disable listeners in order to stop auto completion
+ settingAutoComplete = !shouldAutoComplete
+ append(text)
+ settingAutoComplete = wasSettingAutoComplete
+ }
+
+ override fun getText(): Editable {
+ return super.getText() as Editable
+ }
+
+ override fun sendAccessibilityEventUnchecked(event: AccessibilityEvent) {
+ // We need to bypass the isShown() check in the default implementation
+ // for TYPE_VIEW_TEXT_SELECTION_CHANGED events so that accessibility
+ // services could detect a url change.
+ if (event.eventType == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED &&
+ parent != null && !isShown
+ ) {
+ onInitializeAccessibilityEvent(event)
+ dispatchPopulateAccessibilityEvent(event)
+ parent.requestSendAccessibilityEvent(this, event)
+ } else {
+ super.sendAccessibilityEventUnchecked(event)
+ }
+ }
+
+ /**
+ * Mark the start of autocomplete changes so our text change
+ * listener does not react to changes in autocomplete text
+ */
+ private fun beginSettingAutocomplete() {
+ beginBatchEdit()
+ settingAutoComplete = true
+ }
+
+ /**
+ * Mark the end of autocomplete changes
+ */
+ private fun endSettingAutocomplete() {
+ settingAutoComplete = false
+ endBatchEdit()
+ }
+
+ /**
+ * Reset autocomplete states to their initial values
+ */
+ private fun resetAutocompleteState() {
+ autoCompleteSpans = mutableListOf(
+ AUTOCOMPLETE_SPAN,
+ BackgroundColorSpan(autoCompleteBackgroundColor),
+ ).apply {
+ autoCompleteForegroundColor?.let { add(ForegroundColorSpan(it)) }
+ }
+ autocompleteResult = null
+ // Pretend we already autocompleted the existing text,
+ // so that actions like backspacing don't trigger autocompletion.
+ autoCompletePrefixLength = text.length
+ isCursorVisible = true
+ }
+
+ /**
+ * Remove any autocomplete text
+ *
+ * @param text Current text content that may include autocomplete text
+ */
+ private fun removeAutocomplete(text: Editable): Boolean {
+ val start = text.getSpanStart(AUTOCOMPLETE_SPAN)
+ if (start < 0) {
+ // No autocomplete text
+ return false
+ }
+
+ beginSettingAutocomplete()
+
+ // When we call delete() here, the autocomplete spans we set are removed as well.
+ text.delete(start, text.length)
+
+ // Keep autoCompletePrefixLength the same because the prefix has not changed.
+ // Clear mAutoCompleteResult to make sure we get fresh autocomplete text next time.
+ autocompleteResult = null
+
+ // Reshow the cursor.
+ isCursorVisible = true
+
+ endSettingAutocomplete()
+ return true
+ }
+
+ /**
+ * Convert any autocomplete text to regular text
+ *
+ * @param text Current text content that may include autocomplete text
+ */
+ private fun commitAutocomplete(text: Editable): Boolean {
+ val start = text.getSpanStart(AUTOCOMPLETE_SPAN)
+ if (start < 0) {
+ // No autocomplete text
+ return false
+ }
+
+ beginSettingAutocomplete()
+
+ // Remove all spans here to convert from autocomplete text to regular text
+ for (span in autoCompleteSpans!!) {
+ text.removeSpan(span)
+ }
+
+ // Keep mAutoCompleteResult the same because the result has not changed.
+ // Reset autoCompletePrefixLength because the prefix now includes the autocomplete text.
+ autoCompletePrefixLength = text.length
+
+ // Reshow the cursor.
+ isCursorVisible = true
+
+ endSettingAutocomplete()
+
+ // Invoke textChangeListener manually, because previous autocomplete text is now committed
+ textChangeListener?.apply {
+ val fullText = text.toString()
+ invoke(fullText, fullText)
+ }
+
+ return true
+ }
+
+ /**
+ * Applies the provided result by updating the current autocomplete
+ * text and selection, if any.
+ *
+ * @param result the [AutocompleteResult] to apply
+ */
+ override fun applyAutocompleteResult(result: AutocompleteResult) {
+ // If discardAutoCompleteResult is true, we temporarily disabled
+ // autocomplete (due to backspacing, etc.) and we should bail early.
+ if (discardAutoCompleteResult) {
+ return
+ }
+
+ if (!isEnabled) {
+ autocompleteResult = null
+ return
+ }
+
+ val text = text
+ val autoCompleteStart = text.getSpanStart(AUTOCOMPLETE_SPAN)
+ autocompleteResult = result
+
+ if (autoCompleteStart > -1) {
+ // Autocomplete text already exists; we should replace existing autocomplete text.
+ replaceAutocompleteText(result, autoCompleteStart)
+ } else {
+ // No autocomplete text yet; we should add autocomplete text
+ addAutocompleteText(result)
+ }
+
+ announceForAccessibility(text.toString())
+ }
+
+ private fun replaceAutocompleteText(result: AutocompleteResult, autoCompleteStart: Int) {
+ // Autocomplete text already exists; we should replace existing autocomplete text.
+ val text = text
+ val resultLength = result.text.length
+
+ // If the result and the current text don't have the same prefixes,
+ // the result is stale and we should wait for the another result to come in.
+ if (!TextUtils.regionMatches(result.text, 0, text, 0, autoCompleteStart)) {
+ return
+ }
+
+ beginSettingAutocomplete()
+
+ // Replace the existing autocomplete text with new one.
+ // replace() preserves the autocomplete spans that we set before.
+ text.replace(autoCompleteStart, text.length, result.text, autoCompleteStart, resultLength)
+
+ // Reshow the cursor if there is no longer any autocomplete text.
+ if (autoCompleteStart == resultLength) {
+ isCursorVisible = true
+ }
+
+ endSettingAutocomplete()
+ }
+
+ private fun addAutocompleteText(result: AutocompleteResult) {
+ // No autocomplete text yet; we should add autocomplete text
+ val text = text
+ val textLength = text.length
+ val resultLength = result.text.length
+
+ // If the result prefix doesn't match the current text,
+ // the result is stale and we should wait for the another result to come in.
+ if (resultLength <= textLength || !TextUtils.regionMatches(result.text, 0, text, 0, textLength)) {
+ return
+ }
+
+ val spans = text.getSpans(textLength, textLength, Any::class.java)
+ val spanStarts = IntArray(spans.size)
+ val spanEnds = IntArray(spans.size)
+ val spanFlags = IntArray(spans.size)
+
+ // Save selection/composing span bounds so we can restore them later.
+ for (i in spans.indices) {
+ val span = spans[i]
+ val spanFlag = text.getSpanFlags(span)
+
+ // We don't care about spans that are not selection or composing spans.
+ // For those spans, spanFlag[i] will be 0 and we don't restore them.
+ if (spanFlag and Spanned.SPAN_COMPOSING == 0 &&
+ span !== Selection.SELECTION_START &&
+ span !== Selection.SELECTION_END
+ ) {
+ continue
+ }
+
+ spanStarts[i] = text.getSpanStart(span)
+ spanEnds[i] = text.getSpanEnd(span)
+ spanFlags[i] = spanFlag
+ }
+
+ beginSettingAutocomplete()
+
+ // First add trailing text.
+ text.append(result.text, textLength, resultLength)
+
+ // Restore selection/composing spans.
+ for (i in spans.indices) {
+ val spanFlag = spanFlags[i]
+ if (spanFlag == 0) {
+ // Skip if the span was ignored before.
+ continue
+ }
+ text.setSpan(spans[i], spanStarts[i], spanEnds[i], spanFlag)
+ }
+
+ // Mark added text as autocomplete text.
+ for (span in autoCompleteSpans!!) {
+ text.setSpan(span, textLength, resultLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ }
+
+ // Hide the cursor.
+ isCursorVisible = false
+
+ // Make sure the autocomplete text is visible. If the autocomplete text is too
+ // long, it would appear the cursor will be scrolled out of view. However, this
+ // is not the case in practice, because EditText still makes sure the cursor is
+ // still in view.
+ bringPointIntoView(resultLength)
+
+ endSettingAutocomplete()
+ }
+
+ override fun noAutocompleteResult() {
+ removeAutocomplete(text)
+ }
+
+ /**
+ * Code to handle deleting autocomplete first when backspacing.
+ * If there is no autocomplete text, both removeAutocomplete() and commitAutocomplete()
+ * are no-ops and return false. Therefore we can use them here without checking explicitly
+ * if we have autocomplete text or not.
+ *
+ * Also turns off text prediction for private mode tabs.
+ */
+ @SuppressWarnings("ComplexMethod")
+ override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
+ val ic = super.onCreateInputConnection(outAttrs) ?: return null
+
+ return object : InputConnectionWrapper(ic, false) {
+ override fun deleteSurroundingText(beforeLength: Int, afterLength: Int): Boolean {
+ if (removeAutocomplete(text)) {
+ // If we have autocomplete text, the cursor is at the boundary between
+ // regular and autocomplete text. So regardless of which direction we
+ // are deleting, we should delete the autocomplete text first.
+ //
+ // On Amazon Echo Show devices, restarting input prevents us from backspacing
+ // the last few characters of autocomplete: #911. However, on non-Echo devices,
+ // not restarting input will cause the keyboard to desync when backspacing: #1489.
+ if (!isAmazonEchoShowKeyboard) {
+ restartInput()
+ }
+ return false
+ }
+ return super.deleteSurroundingText(beforeLength, afterLength)
+ }
+
+ // available on API level 24+
+ override fun deleteSurroundingTextInCodePoints(beforeLength: Int, afterLength: Int): Boolean {
+ if (removeAutocomplete(text)) {
+ restartInput()
+ return false
+ }
+ return super.deleteSurroundingTextInCodePoints(beforeLength, afterLength)
+ }
+
+ /**
+ * Optionally remove the current autocompletion depending on the new [text].
+ *
+ * Cases in which the autocompletion will be removed:
+ * - if the user pressed the backspace to remove the autocompletion or
+ * - if the user modified their input such that the autocompletion does not apply anymore.
+ *
+ * @return `true` if this method consumed the user input, `false` otherwise.
+ */
+ @Suppress("ComplexCondition")
+ private fun removeAutocompleteOnComposing(text: CharSequence): Boolean {
+ val editable = getText()
+
+ // Remove the autocomplete text as soon as possible if not applicable anymore.
+ if (!editableText.startsWith(text) && removeAutocomplete(editable)) {
+ return false // If the user modified their input then allow the new text to be set.
+ }
+
+ val composingStart = BaseInputConnection.getComposingSpanStart(editable)
+ val composingEnd = BaseInputConnection.getComposingSpanEnd(editable)
+ // We only delete the autocomplete text when the user is backspacing,
+ // i.e. when the composing text is getting shorter.
+ if (composingStart >= 0 &&
+ composingEnd >= 0 &&
+ composingEnd - composingStart > text.length &&
+ removeAutocomplete(editable)
+ ) {
+ finishComposingText()
+ // Make the IME aware that we interrupted the setComposingText call,
+ // by calling restartInput()
+ restartInput()
+ return true
+ }
+ return false
+ }
+
+ override fun commitText(text: CharSequence, newCursorPosition: Int): Boolean {
+ return if (removeAutocompleteOnComposing(text)) {
+ false
+ } else {
+ super.commitText(text, newCursorPosition)
+ }
+ }
+
+ override fun setComposingText(text: CharSequence, newCursorPosition: Int): Boolean {
+ return if (removeAutocompleteOnComposing(text)) {
+ false
+ } else {
+ super.setComposingText(text, newCursorPosition)
+ }
+ }
+ }
+ }
+
+ private fun restartInput() {
+ inputMethodManger?.restartInput(this)
+ }
+
+ private fun getCurrentInputMethod(): String {
+ val inputMethod = getString(context.contentResolver, DEFAULT_INPUT_METHOD)
+ return inputMethod ?: ""
+ }
+
+ /**
+ * This class watches for text changes and adds or removes autocomplete text accordingly.
+ * Using this class is preferred when making text changes as it will not interfere
+ * with any composing text at the same time as custom keyboards.
+ *
+ * Known issue: autocomplete will not be added when replacing the current text with one
+ * that has a text length equal to the one being replaced minus 1.
+ * */
+ private inner class TextChangeListener : TextWatcher {
+
+ /**
+ * Holds the value of the non-autocomplete text before any changes have been made.
+ * */
+ private var beforeChangedTextNonAutocomplete: String = ""
+
+ /**
+ * The number of characters that have been changed in [onTextChanged].
+ * When using keyboards that do not have their own text correction enabled
+ * and the user is pressing backspace this value will be 0.
+ * */
+ private var textChangedCount: Int = 0
+
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+ if (!isEnabled || settingAutoComplete) return
+ beforeChangedTextNonAutocomplete = getNonAutocompleteText(text)
+ }
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+ if (settingAutoComplete) return
+
+ // In this initial implementation, we do not include the changed text to minimize PII.
+ Fact(Component.UI_AUTOCOMPLETE, Action.IMPLEMENTATION_DETAIL, "onTextChanged", "InlineAutocompleteEditText")
+ .collect()
+
+ if (!isEnabled) return
+
+ textChangedCount = count
+ }
+
+ override fun afterTextChanged(editable: Editable) {
+ if (!isEnabled || settingAutoComplete) return
+
+ val afterNonAutocompleteText = getNonAutocompleteText(editable)
+
+ val hasTextShortenedByOne: Boolean =
+ beforeChangedTextNonAutocomplete.length == afterNonAutocompleteText.length + 1
+
+ // Covers both keyboards with text correction activated and those without.
+ val hasBackspaceBeenPressed =
+ textChangedCount == 0 || hasTextShortenedByOne
+
+ // No autocompleting when typing a search query
+ val afterTextIsSearch = afterNonAutocompleteText.contains(" ")
+
+ val hasTextBeenAdded: Boolean =
+ (
+ afterNonAutocompleteText.contains(beforeChangedTextNonAutocomplete) ||
+ beforeChangedTextNonAutocomplete.isEmpty()
+ ) &&
+ afterNonAutocompleteText.length > beforeChangedTextNonAutocomplete.length
+
+ var shouldAddAutocomplete: Boolean = hasTextBeenAdded || (!afterTextIsSearch && !hasBackspaceBeenPressed)
+
+ autoCompletePrefixLength = afterNonAutocompleteText.length
+
+ // If we are not autocompleting, we set discardAutoCompleteResult to true
+ // to discard any autocomplete results that are in-flight, and vice versa.
+ discardAutoCompleteResult = !shouldAddAutocomplete
+
+ if (!shouldAddAutocomplete) {
+ // Remove the old autocomplete text until any new autocomplete text gets added.
+ removeAutocomplete(editable)
+ } else {
+ // If this text already matches our autocomplete text, autocomplete likely
+ // won't change. Just reuse the old autocomplete value.
+ autocompleteResult?.takeIf { it.startsWith(afterNonAutocompleteText) }?.let {
+ applyAutocompleteResult(it)
+ shouldAddAutocomplete = false
+ }
+ }
+
+ // Update search icon with an active state since user is typing
+ searchStateChangeListener?.invoke(afterNonAutocompleteText.isNotEmpty())
+
+ if (shouldAddAutocomplete) {
+ filterListener?.invoke(afterNonAutocompleteText)
+ }
+
+ textChangeListener?.invoke(afterNonAutocompleteText, text.toString())
+ }
+ }
+
+ override fun dispatchKeyEventPreIme(event: KeyEvent?): Boolean {
+ return event?.let {
+ dispatchKeyEventPreImeListener?.invoke(it) ?: onKeyPreIme(it.keyCode, it)
+ } ?: super.dispatchKeyEventPreIme(event)
+ }
+
+ override fun onKeyPreIme(keyCode: Int, event: KeyEvent): Boolean {
+ return keyPreImeListener?.invoke(this, keyCode, event) ?: false
+ }
+
+ public override fun onSelectionChanged(selStart: Int, selEnd: Int) {
+ selectionChangedListener?.invoke(selStart, selEnd)
+ super.onSelectionChanged(selStart, selEnd)
+ }
+
+ override fun onWindowFocusChanged(hasFocus: Boolean) {
+ super.onWindowFocusChanged(hasFocus)
+ windowFocusChangeListener?.invoke(hasFocus)
+ }
+
+ override fun onTextContextMenuItem(id: Int): Boolean {
+ // Ensure more control over what gets pasted from the framework floating menu.
+ // Behavior closely following the default implementation from TextView#onTextContextMenuItem().
+ if (id == android.R.id.paste || id == android.R.id.pasteAsPlainText) {
+ val selectionStart = selectionStart
+ val selectionEnd = selectionEnd
+
+ val min = 0.coerceAtLeast(selectionStart.coerceAtMost(selectionEnd))
+ val max = 0.coerceAtLeast(selectionStart.coerceAtLeast(selectionEnd))
+
+ if (id == android.R.id.pasteAsPlainText ||
+ (id == android.R.id.paste && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+ ) {
+ paste(min, max, false)
+ } else {
+ paste(min, max, true)
+ }
+
+ return true // action was performed
+ }
+
+ return callOnTextContextMenuItemSuper(id)
+ }
+
+ @Suppress("ClickableViewAccessibility")
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ return if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M &&
+ event.actionMasked == MotionEvent.ACTION_UP
+ ) {
+ // Android 6 occasionally throws a NullPointerException inside Editor.onTouchEvent()
+ // for ACTION_UP when attempting to display (uninitialised) text handles. The Editor
+ // and TextView IME interactions are quite complex, so I don't know how to properly
+ // work around this issue, but we can at least catch the NPE to prevent crashing
+ // the whole app.
+ // (Editor tries to make both selection handles visible, but in certain cases they haven't
+ // been initialised yet, causing the NPE. It doesn't bother to check the selection handle
+ // state, and making some other calls to ensure the handles exist doesn't seem like a
+ // clean solution either since I don't understand most of the selection logic. This implementation
+ // only seems to exist in Android 6, both Android 5 and 7 have different implementations.)
+ try {
+ super.onTouchEvent(event)
+ } catch (ignored: NullPointerException) {
+ // Ignore this (see above) - since we're now in an unknown state let's clear all selection
+ // (which is still better than an arbitrary crash that we can't control):
+ clearFocus()
+ true
+ }
+ } else {
+ super.onTouchEvent(event)
+ }
+ }
+
+ @VisibleForTesting
+ internal fun callOnTextContextMenuItemSuper(id: Int) = super.onTextContextMenuItem(id)
+
+ /**
+ * Paste clipboard content between min and max positions.
+ *
+ * Method matching TextView#paste() but which also strips unwanted schemes before actually pasting.
+ */
+ @Suppress("NestedBlockDepth")
+ @VisibleForTesting
+ internal fun paste(min: Int, max: Int, withFormatting: Boolean) {
+ val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+ val clip = clipboard.primaryClip
+
+ if (clip != null) {
+ var didFirst = false
+ for (i in 0 until clip.itemCount) {
+ val textToBePasted: CharSequence?
+ textToBePasted = if (withFormatting) {
+ clip.getItemAt(i).coerceToStyledText(context)
+ } else {
+ // Get an item as text and remove all spans by toString().
+ val text = clip.getItemAt(i).coerceToText(context)
+ (text as? Spanned)?.toString() ?: text
+ }
+
+ // Actually stripping unwanted schemes
+ val safeTextToBePasted = SafeUrl.stripUnsafeUrlSchemes(context, textToBePasted)
+
+ if (safeTextToBePasted != null) {
+ if (!didFirst) {
+ Selection.setSelection(editableText as Spannable?, max)
+ editableText.replace(min, max, safeTextToBePasted)
+ didFirst = true
+ } else {
+ editableText.insert(selectionEnd, "\n")
+ editableText.insert(selectionEnd, safeTextToBePasted)
+ }
+ }
+ }
+ }
+ }
+
+ companion object {
+ internal val AUTOCOMPLETE_SPAN = NoCopySpan.Concrete()
+ internal const val DEFAULT_AUTOCOMPLETE_BACKGROUND_COLOR = 0xffb5007f.toInt()
+
+ // The Echo Show IME does not conflict with Fire TV: com.amazon.tv.ime/.FireTVIME
+ // However, it may be used by other Amazon keyboards. In theory, if they have the same IME
+ // ID, they should have similar behavior.
+ const val INPUT_METHOD_AMAZON_ECHO_SHOW = "com.amazon.bluestone.keyboard/.DictationIME"
+
+ /**
+ * Get the portion of text that is not marked as autocomplete text.
+ *
+ * @param text Current text content that may include autocomplete text
+ */
+ private fun getNonAutocompleteText(text: Editable): String {
+ val start = text.getSpanStart(AUTOCOMPLETE_SPAN)
+ return if (start < 0) {
+ // No autocomplete text; return the whole string.
+ text.toString()
+ } else {
+ // Only return the portion that's not autocomplete text
+ TextUtils.substring(text, 0, start)
+ }
+ }
+
+ private fun hasCompositionString(content: Editable): Boolean {
+ val spans = content.getSpans(0, content.length, Any::class.java)
+ return spans.any { span -> content.getSpanFlags(span) and Spanned.SPAN_COMPOSING != 0 }
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/ui/autocomplete/src/main/res/values/attrs.xml b/mobile/android/android-components/components/ui/autocomplete/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..2b23026264
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/src/main/res/values/attrs.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <declare-styleable name="InlineAutocompleteEditText">
+ <attr name="autocompleteBackgroundColor" format="color" />
+ </declare-styleable>
+</resources> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/autocomplete/src/test/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditTextTest.kt b/mobile/android/android-components/components/ui/autocomplete/src/test/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditTextTest.kt
new file mode 100644
index 0000000000..d455b0a28e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/src/test/java/mozilla/components/ui/autocomplete/InlineAutocompleteEditTextTest.kt
@@ -0,0 +1,585 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.autocomplete
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.os.Build
+import android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+import android.view.KeyEvent
+import android.view.ViewParent
+import android.view.accessibility.AccessibilityEvent
+import android.view.inputmethod.BaseInputConnection
+import android.view.inputmethod.EditorInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.support.test.robolectric.testContext
+import mozilla.components.ui.autocomplete.InlineAutocompleteEditText.AutocompleteResult
+import mozilla.components.ui.autocomplete.InlineAutocompleteEditText.Companion.AUTOCOMPLETE_SPAN
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.robolectric.Robolectric.buildAttributeSet
+import org.robolectric.annotation.Config
+
+@RunWith(AndroidJUnit4::class)
+class InlineAutocompleteEditTextTest {
+
+ private val attributes = buildAttributeSet().build()
+
+ @Test
+ fun autoCompleteResult() {
+ val result = AutocompleteResult("testText", "testSource", 1)
+ assertEquals("testText", result.text)
+ assertEquals("testSource", result.source)
+ assertEquals(1, result.totalItems)
+ }
+
+ @Test
+ fun getNonAutocompleteText() {
+ val et = InlineAutocompleteEditText(testContext)
+ et.setText("Test")
+ assertEquals("Test", et.nonAutocompleteText)
+
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 2, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ assertEquals("Te", et.nonAutocompleteText)
+
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 0, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ assertEquals("", et.nonAutocompleteText)
+ }
+
+ @Test
+ fun getOriginalText() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.setText("Test")
+ assertEquals("Test", et.originalText)
+
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 2, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ assertEquals("Test", et.originalText)
+
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 0, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ assertEquals("Test", et.originalText)
+ }
+
+ @Test
+ fun onFocusChange() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ val searchStates = mutableListOf<Boolean>()
+
+ et.setOnSearchStateChangeListener { b: Boolean -> searchStates.add(searchStates.size, b) }
+ et.onFocusChanged(false, 0, null)
+
+ et.setText("text")
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 0, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ et.onFocusChanged(false, 0, null)
+ assertTrue(et.text.isEmpty())
+
+ et.setText("text")
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 0, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ et.onFocusChanged(true, 0, null)
+ assertFalse(et.text.isEmpty())
+ assertEquals(listOf(false, true, true), searchStates)
+ }
+
+ @Test
+ fun sendAccessibilityEventUnchecked() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+ doReturn(false).`when`(et).isShown
+ doReturn(mock(ViewParent::class.java)).`when`(et).parent
+
+ val event = AccessibilityEvent()
+ event.eventType = AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
+ et.sendAccessibilityEventUnchecked(event)
+
+ verify(et).onInitializeAccessibilityEvent(event)
+ verify(et).dispatchPopulateAccessibilityEvent(event)
+ verify(et.parent).requestSendAccessibilityEvent(et, event)
+ }
+
+ @Test
+ fun onAutocompleteSetsEmptyResult() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+
+ doReturn(false).`when`(et).isEnabled
+ et.applyAutocompleteResult(AutocompleteResult("text", "source", 1))
+ assertNull(et.autocompleteResult)
+ }
+
+ @Test
+ fun onAutocompleteDiscardsStaleResult() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+ doReturn(true).`when`(et).isEnabled
+ et.setText("text")
+
+ et.applyAutocompleteResult(AutocompleteResult("stale result", "source", 1))
+ assertEquals("text", et.text.toString())
+
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 1, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ et.applyAutocompleteResult(AutocompleteResult("stale result", "source", 1))
+ assertEquals("text", et.text.toString())
+ }
+
+ @Test
+ fun onAutocompleteReplacesExistingAutocompleteText() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+ doReturn(true).`when`(et).isEnabled
+
+ et.setText("text")
+ et.text.setSpan(AUTOCOMPLETE_SPAN, 1, 3, SPAN_EXCLUSIVE_EXCLUSIVE)
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+ assertEquals("text completed", et.text.toString())
+ }
+
+ @Test
+ fun onAutocompleteAppendsExistingText() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+ doReturn(true).`when`(et).isEnabled
+
+ et.setText("text")
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+ assertEquals("text completed", et.text.toString())
+ }
+
+ @Test
+ fun onAutocompleteSetsSpan() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+ doReturn(true).`when`(et).isEnabled
+
+ et.setText("text")
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+
+ assertEquals(4, et.text.getSpanStart(AUTOCOMPLETE_SPAN))
+ assertEquals(14, et.text.getSpanEnd(AUTOCOMPLETE_SPAN))
+ assertEquals(SPAN_EXCLUSIVE_EXCLUSIVE, et.text.getSpanFlags(AUTOCOMPLETE_SPAN))
+ }
+
+ @Test
+ fun onKeyPreImeListenerInvocation() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ var invokedWithParams: List<Any>? = null
+ et.setOnKeyPreImeListener { p1, p2, p3 ->
+ invokedWithParams = listOf(p1, p2, p3)
+ true
+ }
+ val event = mock(KeyEvent::class.java)
+ et.onKeyPreIme(1, event)
+ assertEquals(listOf(et, 1, event), invokedWithParams)
+ }
+
+ @Test
+ fun onSelectionChangedListenerInvocation() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ var invokedWithParams: List<Any>? = null
+ et.setOnSelectionChangedListener { p1, p2 ->
+ invokedWithParams = listOf(p1, p2)
+ }
+ et.onSelectionChanged(0, 1)
+ assertEquals(listOf(0, 1), invokedWithParams)
+ }
+
+ @Test
+ fun onSelectionChangedCommitsResult() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.onAttachedToWindow()
+
+ et.setText("text")
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+ assertEquals(4, et.text.getSpanStart(AUTOCOMPLETE_SPAN))
+
+ et.onSelectionChanged(4, 14)
+ assertEquals(-1, et.text.getSpanStart(AUTOCOMPLETE_SPAN))
+ }
+
+ @Test
+ fun onWindowFocusChangedListenerInvocation() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ var invokedWithParams: List<Any>? = null
+ et.setOnWindowsFocusChangeListener { p1 ->
+ invokedWithParams = listOf(p1)
+ }
+ et.onWindowFocusChanged(true)
+ assertEquals(listOf(true), invokedWithParams)
+ }
+
+ @Test
+ fun onCommitListenerInvocation() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ var invoked = false
+ et.setOnCommitListener { invoked = true }
+ et.onAttachedToWindow()
+
+ et.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER))
+ assertTrue(invoked)
+ }
+
+ @Test
+ fun onTextChangeListenerInvocation() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ var invokedWithParams: List<Any>? = null
+ et.setOnTextChangeListener { p1, p2 ->
+ invokedWithParams = listOf(p1, p2)
+ }
+ et.onAttachedToWindow()
+
+ et.setText("text")
+ assertEquals(listOf("text", "text"), invokedWithParams)
+ }
+
+ @Test
+ fun onSearchStateChangeListenerInvocation() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.onAttachedToWindow()
+
+ var invokedWithParams: List<Any>? = null
+ et.setOnSearchStateChangeListener { p1 ->
+ invokedWithParams = listOf(p1)
+ }
+
+ et.setText("")
+ assertEquals(listOf(false), invokedWithParams)
+
+ et.setText("text")
+ assertEquals(listOf(true), invokedWithParams)
+ }
+
+ @Test
+ fun onFilterListenerInvocation() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.onAttachedToWindow()
+
+ var lastInvokedWithText: String? = null
+ var invokedCounter = 0
+ et.setOnFilterListener { p1 ->
+ lastInvokedWithText = p1
+ invokedCounter++
+ }
+
+ // Already have an autocomplete result, and setting a text to the same value as the result.
+ et.applyAutocompleteResult(AutocompleteResult("text", "source", 1))
+ et.setText("text")
+ // Autocomplete filter shouldn't have been called, because we already have a matching result.
+ assertEquals(0, invokedCounter)
+
+ et.setText("text")
+ assertEquals(1, invokedCounter)
+ assertEquals("text", lastInvokedWithText)
+
+ // Test backspace. We don't expect autocomplete to have been called.
+ et.setText("tex")
+ assertEquals(1, invokedCounter)
+
+ // Presence of a space is counted as a 'search query', we don't autocomplete those.
+ et.setText("search term")
+ assertEquals(1, invokedCounter)
+
+ // Empty text isn't autocompleted either.
+ et.setText("")
+ assertEquals(1, invokedCounter)
+
+ // Autocomplete for the first letter
+ et.setText("t")
+ assertEquals(2, invokedCounter)
+ et.applyAutocompleteResult(AutocompleteResult("text", "source", 1))
+
+ // Autocomplete should be called for the next letter that doesn't match the result
+ et.setText("ta")
+ assertEquals(3, invokedCounter)
+ }
+
+ @Test
+ fun `GIVEN an autocomplete listener WHEN asked to refresh autocomplete suggestions THEN restart the autocomplete functionality with the curret text`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.onAttachedToWindow()
+ et.setText("Test")
+ var lastInvokedWithText: String? = null
+ var invokedCounter = 0
+ et.setOnFilterListener { p1 ->
+ lastInvokedWithText = p1
+ invokedCounter++
+ }
+
+ et.refreshAutocompleteSuggestions()
+
+ assertEquals("Test", lastInvokedWithText)
+ assertEquals(1, invokedCounter)
+ }
+
+ @Test
+ fun onCreateInputConnection() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+ val icw = et.onCreateInputConnection(mock(EditorInfo::class.java))
+ doReturn(true).`when`(et).isEnabled
+
+ et.setText("text")
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+ assertEquals("text completed", et.text.toString())
+
+ icw?.deleteSurroundingText(0, 1)
+ assertNull(et.autocompleteResult)
+ assertEquals("text", et.text.toString())
+
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+ assertEquals("text completed", et.text.toString())
+
+ BaseInputConnection.setComposingSpans(et.text)
+ icw?.commitText("text", 4)
+ assertNull(et.autocompleteResult)
+ assertEquals("text", et.text.toString())
+
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+ assertEquals("text completed", et.text.toString())
+
+ BaseInputConnection.setComposingSpans(et.text)
+ icw?.setComposingText("text", 4)
+ assertNull(et.autocompleteResult)
+ assertEquals("text", et.text.toString())
+ }
+
+ @Test
+ fun removeAutocompleteOnComposing() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ val ic = et.onCreateInputConnection(mock(EditorInfo::class.java))
+
+ ic?.setComposingText("text", 1)
+ assertEquals("text", et.text.toString())
+
+ et.applyAutocompleteResult(AutocompleteResult("text completed", "source", 1))
+ assertEquals("text completed", et.text.toString())
+
+ // Simulating a backspace which should remove the autocomplete and leave original text
+ ic?.setComposingText("tex", 1)
+ assertEquals("text", et.text.toString())
+
+ // Verify that we finished composing
+ assertEquals(-1, BaseInputConnection.getComposingSpanStart(et.text))
+ assertEquals(-1, BaseInputConnection.getComposingSpanEnd(et.text))
+ }
+
+ @Test
+ fun `GIVEN the current text contains an autocompletion WHEN a new character does not match the autocompletion THEN remove the autocompletion`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ val ic = et.onCreateInputConnection(mock(EditorInfo::class.java))
+
+ ic?.setComposingText("mo", 1)
+ assertEquals("mo", et.text.toString())
+
+ et.applyAutocompleteResult(AutocompleteResult("mozilla", "source", 1))
+ assertEquals("mozilla", et.text.toString())
+
+ // Simulating the user entering a new character which makes the current autocomplete invalid
+ ic?.setComposingText("mod", 1)
+ assertEquals("mod", et.text.toString())
+
+ // Verify that autocompletion works for the new text
+ et.applyAutocompleteResult(AutocompleteResult("moderator", "source", 1))
+ assertEquals("moderator", et.text.toString())
+ }
+
+ @Test
+ fun `GIVEN empty edit field WHEN text 'g' added THEN autocomplete to google`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.setText("")
+ et.onAttachedToWindow()
+
+ et.autocompleteResult = AutocompleteResult(
+ text = "google.com",
+ source = "test-source",
+ totalItems = 100,
+ )
+
+ et.setText("g")
+ assertEquals("google.com", "${et.text}")
+ }
+
+ @Test
+ fun `GIVEN empty edit field WHEN text 'g ' added THEN don't autocomplete to google`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.setText("")
+ et.onAttachedToWindow()
+
+ et.autocompleteResult = AutocompleteResult(
+ text = "google.com",
+ source = "test-source",
+ totalItems = 100,
+ )
+
+ et.setText("g ")
+ assertEquals("g ", "${et.text}")
+ }
+
+ @Test
+ fun `GIVEN field with 'google' WHEN backspacing THEN doesn't autocomplete`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.setText("google")
+ et.onAttachedToWindow()
+
+ et.autocompleteResult = AutocompleteResult(
+ text = "google.com",
+ source = "test-source",
+ totalItems = 100,
+ )
+
+ et.setText("googl")
+ assertEquals("googl", "${et.text}")
+ }
+
+ @Test
+ fun `GIVEN field with selected text WHEN text 'g' added THEN autocomplete to google`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.setText("testestest")
+ et.selectAll()
+ et.onAttachedToWindow()
+ et.autocompleteResult = AutocompleteResult(
+ text = "google.com",
+ source = "test-source",
+ totalItems = 100,
+ )
+
+ et.setText("g")
+ assertEquals("google.com", "${et.text}")
+ }
+
+ @Test
+ fun `GIVEN field with selected text 'google ' WHEN text 'g' added THEN autocomplete to google`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.setText("https://www.google.com/")
+ et.selectAll()
+ et.onAttachedToWindow()
+ et.autocompleteResult = AutocompleteResult(
+ text = "google.com",
+ source = "test-source",
+ totalItems = 100,
+ )
+
+ et.setText("g")
+ assertEquals("google.com", "${et.text}")
+ }
+
+ @Test
+ fun `WHEN setting text THEN isEnabled is never modified`() {
+ val et = spy(InlineAutocompleteEditText(testContext, attributes))
+ et.setText("", shouldAutoComplete = false)
+ // assigning here so it verifies the setter, not the getter
+ verify(et, never()).isEnabled = true
+ }
+
+ @Test
+ fun `WHEN onTextContextMenuItem is called for options other than paste THEN we should not paste() and just call super`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+
+ editText.onTextContextMenuItem(android.R.id.copy)
+ editText.onTextContextMenuItem(android.R.id.shareText)
+ editText.onTextContextMenuItem(android.R.id.cut)
+ editText.onTextContextMenuItem(android.R.id.selectAll)
+
+ verify(editText, never()).paste(anyInt(), anyInt(), anyBoolean())
+ verify(editText, times(4)).callOnTextContextMenuItemSuper(anyInt())
+ }
+
+ @Test
+ fun `WHEN onTextContextMenuItem is called for paste THEN we should paste() and not call super`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+
+ editText.onTextContextMenuItem(android.R.id.paste)
+
+ verify(editText).paste(anyInt(), anyInt(), anyBoolean())
+ verify(editText, never()).callOnTextContextMenuItemSuper(anyInt())
+ }
+
+ @Test
+ fun `WHEN onTextContextMenuItem is called for pasteAsPlainText THEN we should paste() and not call super`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+
+ editText.onTextContextMenuItem(android.R.id.pasteAsPlainText)
+
+ verify(editText).paste(anyInt(), anyInt(), anyBoolean())
+ verify(editText, never()).callOnTextContextMenuItemSuper(anyInt())
+ }
+
+ @Test
+ @Config(sdk = [Build.VERSION_CODES.LOLLIPOP, Build.VERSION_CODES.LOLLIPOP_MR1])
+ fun `GIVEN an Android L device, WHEN onTextContextMenuItem is called for paste THEN we should paste() with formatting`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+
+ editText.onTextContextMenuItem(android.R.id.paste)
+
+ verify(editText).paste(anyInt(), anyInt(), eq(true))
+ }
+
+ @Test
+ @Config(sdk = [Build.VERSION_CODES.M, Build.VERSION_CODES.N, Build.VERSION_CODES.O, Build.VERSION_CODES.P])
+ fun `GIVEN an Android M device, WHEN onTextContextMenuItem is called for paste THEN we should paste() without formatting`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+
+ editText.onTextContextMenuItem(android.R.id.paste)
+
+ verify(editText).paste(anyInt(), anyInt(), eq(false))
+ }
+
+ @Test
+ fun `GIVEN no previous text WHEN paste is selected THEN paste() should be called with 0,0`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+
+ editText.onTextContextMenuItem(android.R.id.paste)
+
+ verify(editText).paste(eq(0), eq(0), eq(false))
+ }
+
+ @Test
+ fun `GIVEN 5 chars previous text WHEN paste is selected THEN paste() should be called with 0,5`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+ editText.setText("chars")
+ editText.selectAll()
+
+ editText.onTextContextMenuItem(android.R.id.paste)
+
+ verify(editText).paste(eq(0), eq(5), eq(false))
+ }
+
+ @Test
+ fun `WHEN paste() is called with new text THEN we will display the new text`() {
+ val editText = spy(InlineAutocompleteEditText(testContext, attributes))
+ (testContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).apply {
+ setPrimaryClip(ClipData.newPlainText("Test", "test"))
+ }
+
+ assertEquals("", editText.text.toString())
+
+ editText.paste(0, 0, false)
+
+ assertEquals("test", editText.text.toString())
+ }
+
+ fun `WHEN committing autocomplete THEN textChangedListener is invoked`() {
+ val et = InlineAutocompleteEditText(testContext, attributes)
+ et.setText("")
+
+ et.onAttachedToWindow()
+ et.autocompleteResult = AutocompleteResult(
+ text = "google.com",
+ source = "test-source",
+ totalItems = 100,
+ )
+ et.setText("g")
+ var callbackInvoked = false
+ et.setOnTextChangeListener { _, _ ->
+ callbackInvoked = true
+ }
+ et.setSelection(3)
+ assertTrue(callbackInvoked)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/autocomplete/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/mobile/android/android-components/components/ui/autocomplete/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000..cf1c399ea8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1,2 @@
+mock-maker-inline
+// This allows mocking final classes (classes are final by default in Kotlin)
diff --git a/mobile/android/android-components/components/ui/autocomplete/src/test/resources/robolectric.properties b/mobile/android/android-components/components/ui/autocomplete/src/test/resources/robolectric.properties
new file mode 100644
index 0000000000..932b01b9eb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/autocomplete/src/test/resources/robolectric.properties
@@ -0,0 +1 @@
+sdk=28
diff --git a/mobile/android/android-components/components/ui/colors/README.md b/mobile/android/android-components/components/ui/colors/README.md
new file mode 100644
index 0000000000..2b7855fee9
--- /dev/null
+++ b/mobile/android/android-components/components/ui/colors/README.md
@@ -0,0 +1,19 @@
+# [Android Components](../../../README.md) > UI > Colors
+
+The standard set of [Photon](https://design.firefox.com/photon/) colors.
+
+## Usage
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:ui-colors:{latest-version}"
+```
+
+## License
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/
diff --git a/mobile/android/android-components/components/ui/colors/build.gradle b/mobile/android/android-components/components/ui/colors/build.gradle
new file mode 100644
index 0000000000..865b113e50
--- /dev/null
+++ b/mobile/android/android-components/components/ui/colors/build.gradle
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ buildFeatures {
+ compose true
+ }
+
+ composeOptions {
+ kotlinCompilerExtensionVersion = Versions.compose_compiler
+ }
+
+ namespace 'mozilla.components.ui.colors'
+}
+
+dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
+ implementation ComponentsDependencies.androidx_compose_ui
+}
+
+apply from: '../../../android-lint.gradle'
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description) \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/colors/proguard-rules.pro b/mobile/android/android-components/components/ui/colors/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/colors/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/ui/colors/src/main/AndroidManifest.xml b/mobile/android/android-components/components/ui/colors/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e16cda1d34
--- /dev/null
+++ b/mobile/android/android-components/components/ui/colors/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<manifest />
diff --git a/mobile/android/android-components/components/ui/colors/src/main/java/mozilla/components/ui/colors/PhotonColors.kt b/mobile/android/android-components/components/ui/colors/src/main/java/mozilla/components/ui/colors/PhotonColors.kt
new file mode 100644
index 0000000000..214070deed
--- /dev/null
+++ b/mobile/android/android-components/components/ui/colors/src/main/java/mozilla/components/ui/colors/PhotonColors.kt
@@ -0,0 +1,178 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.colors
+
+import androidx.compose.ui.graphics.Color
+
+/**
+ * Colors from the [Photon Design System](https://design.firefox.com/photon/visuals/color.html).
+ *
+ * _"Firefox colors are bold, vibrant and attractive. They enhance the experience by providing visual
+ * clues and by bringing attention to primary actions."_
+ */
+object PhotonColors {
+ // Firefox Blue is one of our primary colors. We use blue as accent color for highlighting buttons,
+ // links and active states like the current tab in Firefox for desktop.
+ val Blue05 = Color(0xFFAAF2FF)
+ val Blue10 = Color(0xFF80EBFF)
+ val Blue20 = Color(0xFF00DDFF)
+ val Blue30 = Color(0xFF00B3F4)
+ val Blue40 = Color(0xFF0090ED)
+ val Blue50 = Color(0xFF0060DF)
+ val Blue50A44 = Blue50.copy(alpha = 0.44f)
+ val Blue50A80 = Blue50.copy(alpha = 0.8f)
+ val Blue60 = Color(0xFF0250BB)
+ val Blue70 = Color(0xFF054096)
+ val Blue80 = Color(0xFF073072)
+ val Blue90 = Color(0xFF09204D)
+
+ // Green is primarily used for positive / success / update status in user interface.
+ val Green05 = Color(0xFFE3FFF3)
+ val Green10 = Color(0xFFD1FFEE)
+ val Green20 = Color(0xFFB3FFE3)
+ val Green30 = Color(0xFF87FFD1)
+ val Green40 = Color(0xFF54FFBD)
+ val Green50 = Color(0xFF3FE1B0)
+ val Green60 = Color(0xFF2AC3A2)
+ val Green70 = Color(0xFF008787)
+ val Green80 = Color(0xFF005E5E)
+ val Green90 = Color(0xFF08403F)
+
+ // Red is primarily used for attention / error status or a destructive action in user interface.
+ val Red05 = Color(0xFFFFDFE7)
+ val Red10 = Color(0xFFFFBDC5)
+ val Red20 = Color(0xFFFF9AA2)
+ val Red30 = Color(0xFFFF848B)
+ val Red40 = Color(0xFFFF6A75)
+ val Red50 = Color(0xFFFF4F5E)
+ val Red60 = Color(0xFFE22850)
+ val Red70 = Color(0xFFC50042)
+ val Red80 = Color(0xFF810220)
+ val Red90 = Color(0xFF440306)
+
+ // Yellow is primarily used for attention / caution / warning status in user interface.
+ val Yellow05 = Color(0xFFFFFFCC)
+ val Yellow10 = Color(0xFFFFFF98)
+ val Yellow20 = Color(0xFFFFEA80)
+ val Yellow30 = Color(0xFFFFD567)
+ val Yellow40 = Color(0xFFFFBD4F)
+ val Yellow40A41 = Yellow40.copy(alpha = .41f)
+ val Yellow50 = Color(0xFFFFA436)
+ val Yellow60 = Color(0xFFE27F2E)
+ val Yellow60A40 = Yellow60.copy(alpha = 0.4f)
+ val Yellow70 = Color(0xFFC45A27)
+ val Yellow70A77 = Yellow70.copy(alpha = 0.77f)
+ val Yellow80 = Color(0xFFA7341F)
+ val Yellow90 = Color(0xFF960E18)
+
+ // Purple is commonly used to indicate privacy.
+ val Purple05 = Color(0xFFF7E2FF)
+ val Purple10 = Color(0xFFF6B8FF)
+ val Purple20 = Color(0xFFF68FFF)
+ val Purple30 = Color(0xFFF770FF)
+ val Purple40 = Color(0xFFD74CF0)
+ val Purple50 = Color(0xFFB833E1)
+ val Purple60 = Color(0xFF952BB9)
+ val Purple70 = Color(0xFF722291)
+ val Purple80 = Color(0xFF4E1A69)
+ val Purple90 = Color(0xFF2B1141)
+
+ // Firefox Orange is only used for branding. Do not use it otherwise!
+ val Orange05 = Color(0xFFFFF4DE)
+ val Orange10 = Color(0xFFFFD5B2)
+ val Orange20 = Color(0xFFFFB587)
+ val Orange30 = Color(0xFFFFA266)
+ val Orange40 = Color(0xFFFF8A50)
+ val Orange50 = Color(0xFFFF7139)
+ val Orange60 = Color(0xFFE25920)
+ val Orange70 = Color(0xFFCC3D00)
+ val Orange80 = Color(0xFF9E280B)
+ val Orange90 = Color(0xFF7C1504)
+
+ // Pink is only used for Firefox Focus. Do not use it otherwise!
+ val Pink05 = Color(0xFFFFDEF0)
+ val Pink10 = Color(0xFFFFB4DB)
+ val Pink20 = Color(0xFFFF8AC5)
+ val Pink30 = Color(0xFFFF6BBA)
+ val Pink40 = Color(0xFFFF4AA2)
+ val Pink50 = Color(0xFFFF298A)
+ val Pink60 = Color(0xFFE21587)
+ val Pink70 = Color(0xFFC60084)
+ val Pink70A69 = Pink70.copy(alpha = 0.69f)
+ val Pink80 = Color(0xFF7F145B)
+ val Pink90 = Color(0xff50134b)
+
+ // Firefox Ink is commonly used for Firefox branding and new product websites.
+ val Ink05 = Color(0xFF393473)
+ val Ink10 = Color(0xFF342F6D)
+ val Ink20 = Color(0xFF312A64)
+ val Ink20A48 = Color(0x7A312A64)
+ val Ink20A50 = Color(0x80312A64)
+ val Ink30 = Color(0xFF2E255D)
+ val Ink40 = Color(0xFF2B2156)
+ val Ink50 = Color(0xFF291D4F)
+ val Ink60 = Color(0xFF271948)
+ val Ink70 = Color(0xFF241541)
+ val Ink80 = Color(0xFF20123A)
+ val Ink80A96 = Color(0xF520123A)
+ val Ink90 = Color(0xFF1D1133)
+
+ // Light grey should primarily be used for the Light Theme and secondary buttons.
+ val LightGrey05 = Color(0xFFFBFBFE)
+ val LightGrey05A40 = Color(0x66FBFBFE)
+ val LightGrey05A60 = Color(0x99FBFBFE)
+ val LightGrey10 = Color(0xFFF9F9FB)
+ val LightGrey20 = Color(0xFFF0F0F4)
+ val LightGrey30 = Color(0xFFE0E0E6)
+ val LightGrey40 = Color(0xFFCFCFD8)
+ val LightGrey50 = Color(0xFFBFBFC9)
+ val LightGrey60 = Color(0xFFAFAFBA)
+ val LightGrey70 = Color(0xFF9F9FAD)
+ val LightGrey80 = Color(0xFF8F8F9D)
+ val LightGrey90 = Color(0xFF80808E)
+
+ // Dark grey should primarily be used for the Dark theme and secondary buttons.
+ val DarkGrey05 = Color(0xFF5B5B66)
+ val DarkGrey05A45 = Color(0x735B5B66)
+ val DarkGrey10 = Color(0xFF52525E)
+ val DarkGrey20 = Color(0xFF4A4A55)
+ val DarkGrey30 = Color(0xFF42414D)
+ val DarkGrey30A95 = Color(0xF242414D)
+ val DarkGrey30A96 = Color(0xF542414D)
+ val DarkGrey40 = Color(0xFF3A3944)
+ val DarkGrey50 = Color(0xFF32313C)
+ val DarkGrey60 = Color(0xFF2B2A33)
+ val DarkGrey70 = Color(0xFF23222B)
+ val DarkGrey80 = Color(0xFF1C1B22)
+ val DarkGrey90 = Color(0xFF15141A)
+ val DarkGrey90A40 = Color(0x6615141A)
+ val DarkGrey90A60 = Color(0x9915141A)
+ val DarkGrey90A95 = Color(0xF215141A)
+ val DarkGrey90A96 = Color(0xF515141A)
+
+ // Violet
+ val Violet05 = Color(0xFFE7DFFF)
+ val Violet10 = Color(0xFFD9BFFF)
+ val Violet20 = Color(0xFFCB9EFF)
+ val Violet20A60 = Color(0x99CB9EFF)
+ val Violet30 = Color(0xFFC689FF)
+ val Violet40 = Color(0xFFAB71FF)
+ val Violet40A12 = Color(0x1FAB71FF)
+ val Violet40A30 = Color(0x4DAB71FF)
+ val Violet50 = Color(0xFF9059FF)
+ val Violet50A32 = Color(0x529059FF)
+ val Violet50A48 = Color(0x7A9059FF)
+ val Violet60 = Color(0xFF7542E5)
+ val Violet60A50 = Color(0x807542E5)
+ val Violet70 = Color(0xFF592ACB)
+ val Violet70A12 = Color(0x1F592ACB)
+ val Violet70A80 = Color(0xCC592ACB)
+ val Violet80 = Color(0xFF45278D)
+ val Violet90 = Color(0xFF321C64)
+ val Violet90A20 = Color(0x33321C64)
+
+ val White = Color(0xFFFFFFFF)
+ val Black = Color(0xFF000000)
+}
diff --git a/mobile/android/android-components/components/ui/colors/src/main/res/values/photon_colors.xml b/mobile/android/android-components/components/ui/colors/src/main/res/values/photon_colors.xml
new file mode 100644
index 0000000000..c873639d17
--- /dev/null
+++ b/mobile/android/android-components/components/ui/colors/src/main/res/values/photon_colors.xml
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
+ <!--
+ Firefox colors are bold, vibrant and attractive. They enhance the experience by providing
+ visual clues and by bringing attention to primary actions.
+
+ The color palette includes primary and secondary colors that can be used for interfaces and illustrations.
+
+ https://design.firefox.com/photon/visuals/color.html
+ -->
+
+ <!--
+ Blue
+ Firefox Blue is one of our primary colors. We use blue as accent color for highlighting buttons, links and active states like the current tab in Firefox for desktop.
+ -->
+ <color name="photonBlue05">#ffaaf2ff</color>
+ <color name="photonBlue10">#ff80ebff</color>
+ <color name="photonBlue20">#ff00ddff</color>
+ <color name="photonBlue30">#ff00b3f4</color>
+ <color name="photonBlue40">#ff0090ed</color>
+ <color name="photonBlue50">#ff0060df</color>
+ <color name="photonBlue50A44">#700060df</color>
+ <color name="photonBlue50A80">#cc0060df</color>
+ <color name="photonBlue60">#ff0250bb</color>
+ <color name="photonBlue70">#ff054096</color>
+ <color name="photonBlue80">#ff073072</color>
+ <color name="photonBlue90">#ff09204d</color>
+
+ <!--
+ Magenta
+ Firefox Magenta is one of our primary colors. We currently have no common usage for it.
+
+ In the future, Magenta should be redefined into Pink wherever possible.
+ -->
+ <color name="photonMagenta50">#ffff1ad9</color>
+ <color name="photonMagenta60">#ffed00b5</color>
+ <color name="photonMagenta70">#ffb5007f</color>
+ <color name="photonMagenta80">#ff7d004f</color>
+ <color name="photonMagenta90">#ff440027</color>
+
+ <!-- Pink -->
+ <color name="photonPink05">#ffffdef0</color>
+ <color name="photonPink10">#ffffb4db</color>
+ <color name="photonPink20">#ffff8ac5</color>
+ <color name="photonPink30">#ffff6bba</color>
+ <color name="photonPink40">#ffff4aa2</color>
+ <color name="photonPink50">#ffff298a</color>
+ <color name="photonPink60">#ffe21587</color>
+ <color name="photonPink70">#ffc60084</color>
+ <color name="photonPink70A69">#b0c60084</color>
+ <color name="photonPink80">#ff7f145b</color>
+ <color name="photonPink90">#ff50134b</color>
+
+ <!-- Green -->
+ <color name="photonGreen05">#ffe3fff3</color>
+ <color name="photonGreen10">#ffd1ffee</color>
+ <color name="photonGreen20">#ffb3ffe3</color>
+ <color name="photonGreen30">#ff87ffd1</color>
+ <color name="photonGreen40">#ff54ffbd</color>
+ <color name="photonGreen50">#ff3fe1b0</color>
+ <color name="photonGreen60">#ff2ac3a2</color>
+ <color name="photonGreen70">#ff008787</color>
+ <color name="photonGreen80">#ff005e5e</color>
+ <color name="photonGreen90">#ff08403f</color>
+
+ <!-- Red -->
+ <color name="photonRed05">#ffffdfe7</color>
+ <color name="photonRed10">#ffffbdc5</color>
+ <color name="photonRed20">#ffff9aa2</color>
+ <color name="photonRed30">#ffff848b</color>
+ <color name="photonRed40">#ffff6a75</color>
+ <color name="photonRed50">#ffff4f5e</color>
+ <color name="photonRed60">#ffe22850</color>
+ <color name="photonRed70">#ffc50042</color>
+ <color name="photonRed80">#ff810220</color>
+ <color name="photonRed90">#ff440306</color>
+
+ <!-- Yellow -->
+ <color name="photonYellow05">#ffffffcc</color>
+ <color name="photonYellow10">#ffffff98</color>
+ <color name="photonYellow20">#ffffea80</color>
+ <color name="photonYellow30">#ffffd567</color>
+ <color name="photonYellow40">#ffffbd4f</color>
+ <color name="photonYellow40A41">#69ffbd4f</color>
+ <color name="photonYellow50">#ffffa436</color>
+ <color name="photonYellow60">#ffe27f2e</color>
+ <color name="photonYellow60A40">#66e27f2e</color>
+ <color name="photonYellow70">#ffc45a27</color>
+ <color name="photonYellow70A77">#c4c45a27</color>
+ <color name="photonYellow80">#ffa7341f</color>
+ <color name="photonYellow90">#ff960e18</color>
+
+ <!--
+ Teal
+ Teal is a colour palette that we no longer use.
+ -->
+ <color name="photonTeal50">#00feff</color>
+ <color name="photonTeal60">#00c8d7</color>
+ <color name="photonTeal70">#008ea4</color>
+ <color name="photonTeal80">#005a71</color>
+ <color name="photonTeal90">#002d3e</color>
+
+ <!-- Purple -->
+ <color name="photonPurple05">#fff7e2ff</color>
+ <color name="photonPurple10">#fff6b8ff</color>
+ <color name="photonPurple20">#fff68fff</color>
+ <color name="photonPurple30">#fff770ff</color>
+ <color name="photonPurple40">#ffd74cf0</color>
+ <color name="photonPurple50">#ffb833e1</color>
+ <color name="photonPurple60">#ff952bb9</color>
+ <color name="photonPurple70">#ff722291</color>
+ <color name="photonPurple80">#ff4e1a69</color>
+ <color name="photonPurple90">#ff2b1141</color>
+
+ <!-- Orange -->
+ <color name="photonOrange05">#fffff4de</color>
+ <color name="photonOrange10">#ffffd5b2</color>
+ <color name="photonOrange20">#ffffb587</color>
+ <color name="photonOrange30">#ffffa266</color>
+ <color name="photonOrange40">#ffff8a50</color>
+ <color name="photonOrange50">#ffff7139</color>
+ <color name="photonOrange60">#ffe25920</color>
+ <color name="photonOrange70">#ffcc3d00</color>
+ <color name="photonOrange80">#ff9e280b</color>
+ <color name="photonOrange90">#ff7c1504</color>
+
+ <!-- Ink -->
+ <color name="photonInk05">#ff393473</color>
+ <color name="photonInk10">#ff342f6d</color>
+ <color name="photonInk20">#ff312a64</color>
+ <color name="photonInk20A48">#7A312a64</color>
+ <color name="photonInk20A50">#80312A64</color>
+ <color name="photonInk30">#ff2e255d</color>
+ <color name="photonInk40">#ff2b2156</color>
+ <color name="photonInk50">#ff291d4f</color>
+ <color name="photonInk60">#ff271948</color>
+ <color name="photonInk70">#ff241541</color>
+ <color name="photonInk80">#ff20123a</color>
+ <color name="photonInk80A96">#f520123a</color>
+ <color name="photonInk90">#ff1d1133</color>
+
+ <!--
+ Grey
+ Grey is a colour palette that we no longer use.
+ In the future, Grey should be redefined into LightGrey and DarkGrey wherever possible.
+ -->
+ <color name="photonGrey10">#f9f9fa</color>
+ <color name="photonGrey20">#ededf0</color>
+ <color name="photonGrey30">#d7d7db</color>
+ <color name="photonGrey40">#b1b1b3</color>
+ <color name="photonGrey50">#737373</color>
+ <color name="photonGrey60">#4a4a4f</color>
+ <color name="photonGrey70">#38383d</color>
+ <color name="photonGrey80">#2a2a2e</color>
+ <color name="photonGrey90">#0c0c0d</color>
+
+ <!-- Light Grey -->
+ <color name="photonLightGrey05">#fffbfbfe</color>
+ <color name="photonLightGrey05A40">#66fbfbfe</color>
+ <color name="photonLightGrey05A60">#99fbfbfe</color>
+ <color name="photonLightGrey10">#fff9f9fb</color>
+ <color name="photonLightGrey20">#fff0f0f4</color>
+ <color name="photonLightGrey30">#ffe0e0e6</color>
+ <color name="photonLightGrey40">#ffcfcfd8</color>
+ <color name="photonLightGrey50">#ffbfbfc9</color>
+ <color name="photonLightGrey60">#ffafafba</color>
+ <color name="photonLightGrey70">#ff9f9fad</color>
+ <color name="photonLightGrey80">#ff8f8f9d</color>
+ <color name="photonLightGrey90">#ff80808e</color>
+
+ <!-- Dark Grey -->
+ <color name="photonDarkGrey05">#ff5b5b66</color>
+ <color name="photonDarkGrey05A45">#735b5b66</color>
+ <color name="photonDarkGrey10">#ff52525e</color>
+ <color name="photonDarkGrey20">#ff4a4a55</color>
+ <color name="photonDarkGrey30">#ff42414d</color>
+ <color name="photonDarkGrey30A95">#f242414d</color>
+ <color name="photonDarkGrey30A96">#f542414d</color>
+ <color name="photonDarkGrey40">#ff3a3944</color>
+ <color name="photonDarkGrey50">#ff32313c</color>
+ <color name="photonDarkGrey60">#ff2b2a33</color>
+ <color name="photonDarkGrey70">#ff23222b</color>
+ <color name="photonDarkGrey80">#ff1c1b22</color>
+ <color name="photonDarkGrey90">#ff15141a</color>
+ <color name="photonDarkGrey90A40">#6615141a</color>
+ <color name="photonDarkGrey90A60">#9915141a</color>
+ <color name="photonDarkGrey90A95">#f215141a</color>
+ <color name="photonDarkGrey90A96">#f515141a</color>
+
+ <!-- Violet -->
+ <color name="photonViolet05">#ffE7DFFF</color>
+ <color name="photonViolet10">#ffd9bfff</color>
+ <color name="photonViolet20">#ffcb9eFF</color>
+ <color name="photonViolet20A60">#99cb9eFF</color>
+ <color name="photonViolet30">#ffc689FF</color>
+ <color name="photonViolet40">#ffab71ff</color>
+ <color name="photonViolet40A12">#1fab71ff</color>
+ <color name="photonViolet40A30">#4dab71ff</color>
+ <color name="photonViolet50">#ff9059FF</color>
+ <color name="photonViolet50A32">#529059FF</color>
+ <color name="photonViolet50A48">#7A9059FF</color>
+ <color name="photonViolet60">#ff7542e5</color>
+ <color name="photonViolet60A50">#807542E5</color>
+ <color name="photonViolet70">#ff592ACB</color>
+ <color name="photonViolet70A12">#1F592ACB</color>
+ <color name="photonViolet70A80">#CC592ACB</color>
+ <color name="photonViolet80">#ff45278d</color>
+ <color name="photonViolet90">#ff321c64</color>
+ <color name="photonViolet90A20">#33321c64</color>
+
+ <!-- White -->
+ <color name="photonWhite">#ffffff</color>
+
+ <!-- Black -->
+ <color name="photonBlack">#000000</color>
+</resources>
diff --git a/mobile/android/android-components/components/ui/fonts/README.md b/mobile/android/android-components/components/ui/fonts/README.md
new file mode 100644
index 0000000000..33b94590e0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/fonts/README.md
@@ -0,0 +1,19 @@
+# [Android Components](../../../README.md) > UI > Fonts
+
+The standard set of fonts used by Mozilla Android products.
+
+## Usage
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:ui-fonts:{latest-version}"
+```
+
+## License
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/
diff --git a/mobile/android/android-components/components/ui/fonts/build.gradle b/mobile/android/android-components/components/ui/fonts/build.gradle
new file mode 100644
index 0000000000..f3eb06ce5e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/fonts/build.gradle
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ namespace 'mozilla.components.ui.fonts'
+}
+
+dependencies {
+ // None
+}
+
+apply from: '../../../android-lint.gradle'
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description) \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/fonts/proguard-rules.pro b/mobile/android/android-components/components/ui/fonts/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/fonts/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/ui/fonts/src/main/AndroidManifest.xml b/mobile/android/android-components/components/ui/fonts/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e16cda1d34
--- /dev/null
+++ b/mobile/android/android-components/components/ui/fonts/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<manifest />
diff --git a/mobile/android/android-components/components/ui/fonts/src/main/res/values/roboto_fonts.xml b/mobile/android/android-components/components/ui/fonts/src/main/res/values/roboto_fonts.xml
new file mode 100644
index 0000000000..eeb5222aab
--- /dev/null
+++ b/mobile/android/android-components/components/ui/fonts/src/main/res/values/roboto_fonts.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
+
+ <!-- Designers specify the Roboto fontFamily as "Roboto Medium" but they appear in Android as
+ "sans-serif-medium": this file aliases the Android definitions to those used by the designers.
+
+ This solution is adapted from SO: https://stackoverflow.com/a/26545517 and https://stackoverflow.com/a/42927799 -->
+ <string name="font_roboto_regular">sans-serif</string>
+ <string name="font_roboto_light">sans-serif-light</string>
+ <string name="font_roboto_condensed">sans-serif-condensed</string>
+ <string name="font_roboto_black">sans-serif-black</string>
+ <string name="font_roboto_thin">sans-serif-thin</string> <!-- API 17+ -->
+ <string name="font_roboto_medium">sans-serif-medium</string> <!-- API 21+ -->
+
+</resources>
diff --git a/mobile/android/android-components/components/ui/icons/README.md b/mobile/android/android-components/components/ui/icons/README.md
new file mode 100644
index 0000000000..47c4e989c0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/README.md
@@ -0,0 +1,19 @@
+# [Android Components](../../../README.md) > UI > Icons
+
+A collection of often used browser icons.
+
+## Usage
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:ui-icons:{latest-version}"
+```
+
+## License
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/
diff --git a/mobile/android/android-components/components/ui/icons/build.gradle b/mobile/android/android-components/components/ui/icons/build.gradle
new file mode 100644
index 0000000000..d49b47c2f8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/build.gradle
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ namespace 'mozilla.components.ui.icons'
+}
+
+dependencies {
+ // None
+}
+
+apply from: '../../../android-lint.gradle'
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description) \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/proguard-rules.pro b/mobile/android/android-components/components/ui/icons/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/ui/icons/src/main/AndroidManifest.xml b/mobile/android/android-components/components/ui/icons/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e16cda1d34
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<manifest />
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_asleep.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_asleep.svg
new file mode 100644
index 0000000000..8829f8a102
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_asleep.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:url(#linear-gradient-3);}.cls-6{fill:url(#linear-gradient-4);}.cls-7{fill:#cc3d00;}.cls-8{fill:#e31587;}.cls-9{fill:#ff4f5e;}.cls-10{fill:#c60084;}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="-496.29" y1="61.33" x2="-547.1" y2="10.52" gradientTransform="matrix(-1, 0, 0, 1, -471.81, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-2" x1="-572.12" y1="-14.51" x2="-454.86" y2="102.75" gradientTransform="matrix(-1, 0, 0, 1, -471.81, 0)" gradientUnits="userSpaceOnUse"><stop offset="0.4" stop-color="#ffd567"/><stop offset="0.86" stop-color="#ffc456"/><stop offset="1" stop-color="#ffbd4f"/></linearGradient><linearGradient id="linear-gradient-3" x1="14.23" y1="9.62" x2="63.25" y2="58.64" gradientUnits="userSpaceOnUse"><stop offset="0.25" stop-color="#ffd567"/><stop offset="1" stop-color="#ffa436"/></linearGradient><linearGradient id="linear-gradient-4" x1="29.38" y1="-5.52" x2="78.4" y2="43.5" xlink:href="#linear-gradient-3"/></defs><title>fx-fenix_error_2</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M49.79,56.33a8,8,0,0,1-7.92,8H10.05a6.08,6.08,0,0,1,0-12.15,6.26,6.26,0,0,1,1.45.18,6.48,6.48,0,0,1-.16-1.41,6.26,6.26,0,0,1,9.81-5.16,10.53,10.53,0,0,1,20.72,2.64A8,8,0,0,1,49.79,56.33Z"/><path class="cls-2" d="M188.39,27.89a8.76,8.76,0,0,0-2.19.27,9.25,9.25,0,0,0,.24-2.12,9.45,9.45,0,0,0-14.78-7.78,15.88,15.88,0,0,0-31.24,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,1,0,0-18.21Z"/><path class="cls-3" d="M50.35,4.45a31,31,0,0,1,31,31c0,.42,0,.84,0,1.27A3.67,3.67,0,0,1,80.82,44h-.66A31,31,0,1,1,50.35,4.45Z"/><path class="cls-4" d="M19.34,36.73c0-.43,0-.85,0-1.27a30.86,30.86,0,0,1,8.55-21.37A31.87,31.87,0,0,0,71.71,57.94,31,31,0,0,1,20.53,44.05h-.7a3.68,3.68,0,0,1-.49-7.32Z"/><path class="cls-5" d="M31.48,31.9a1,1,0,0,1-.69-.26,1.06,1.06,0,0,1-.08-1.49A6.36,6.36,0,0,1,35.46,28h0a6.38,6.38,0,0,1,4.75,2.13,1.05,1.05,0,1,1-1.58,1.39,4.25,4.25,0,0,0-3.17-1.43h0a4.21,4.21,0,0,0-3.17,1.43A1.12,1.12,0,0,1,31.48,31.9Z"/><path class="cls-6" d="M69.68,31.9a1,1,0,0,1-.79-.36,4.25,4.25,0,0,0-3.17-1.43h0a4.21,4.21,0,0,0-3.17,1.43A1.05,1.05,0,0,1,61,30.14,6.36,6.36,0,0,1,65.74,28h0a6.36,6.36,0,0,1,4.75,2.13,1,1,0,0,1-.1,1.48A1,1,0,0,1,69.68,31.9Z"/><path class="cls-7" d="M70,37.1a1.41,1.41,0,0,0-2,.12,3,3,0,0,1-2.25,1,3,3,0,0,1-2.24-1,1.42,1.42,0,0,0-2-.12,1.39,1.39,0,0,0-.34,1.62,1.46,1.46,0,0,0,.09.39,4.8,4.8,0,0,0,9,0,1.07,1.07,0,0,0,.1-.39A1.36,1.36,0,0,0,70,37.1Z"/><path class="cls-7" d="M39.69,37.1a1.41,1.41,0,0,0-2,.12,3,3,0,0,1-2.24,1h0a3,3,0,0,1-2.25-1,1.41,1.41,0,0,0-2-.12,1.38,1.38,0,0,0-.35,1.62,1.18,1.18,0,0,0,.1.39,4.91,4.91,0,0,0,4.47,3.06h0a4.92,4.92,0,0,0,4.48-3.06,1.3,1.3,0,0,0,.09-.39A1.34,1.34,0,0,0,39.69,37.1Z"/><path class="cls-7" d="M55,52a4.34,4.34,0,1,1-8.67,0c0-2.4,1.94-3.4,4.34-3.4S55,49.58,55,52Z"/><path class="cls-8" d="M66.68,16.08H60.39a1.15,1.15,0,0,1-.82-2L64,9.68H60.6a1.15,1.15,0,1,1,0-2.3h6.2a1.15,1.15,0,0,1,.82,2l-4.43,4.43h3.5a1.15,1.15,0,1,1,0,2.3Z"/><path class="cls-9" d="M75.48,6.52H71.39A.87.87,0,0,1,70.78,5l2.69-2.69H71.53a.87.87,0,1,1,0-1.74h4a.84.84,0,0,1,.8.54.85.85,0,0,1-.19.94L73.48,4.78h2a.87.87,0,1,1,0,1.74Z"/><path class="cls-10" d="M80,24.27H71.5a1.72,1.72,0,0,1-1.23-2.95L76,15.61H71.76a1.73,1.73,0,0,1,0-3.46h8.4a1.73,1.73,0,0,1,1.23,2.95l-5.71,5.71H80a1.73,1.73,0,0,1,0,3.46Z"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_confused.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_confused.svg
new file mode 100644
index 0000000000..0bed690133
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_confused.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:url(#linear-gradient-3);}.cls-6{fill:url(#linear-gradient-4);}.cls-7{fill:url(#linear-gradient-5);}.cls-8{fill:url(#linear-gradient-6);}.cls-9{fill:#cc3d00;}.cls-10{fill:url(#linear-gradient-7);}.cls-11{fill:url(#linear-gradient-8);}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="75.94" y1="61.05" x2="25.13" y2="10.24" gradientTransform="matrix(-1, 0, 0, 1, 100.19, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-2" x1="0.1" y1="-14.79" x2="117.37" y2="102.48" gradientTransform="matrix(-1, 0, 0, 1, 100.19, 0)" gradientUnits="userSpaceOnUse"><stop offset="0.4" stop-color="#ffd567"/><stop offset="0.86" stop-color="#ffc456"/><stop offset="1" stop-color="#ffbd4f"/></linearGradient><linearGradient id="linear-gradient-3" x1="26.98" y1="-14.71" x2="82.12" y2="43.5" gradientUnits="userSpaceOnUse"><stop offset="0.25" stop-color="#ffd567"/><stop offset="1" stop-color="#ffa436"/></linearGradient><linearGradient id="linear-gradient-4" x1="13.11" y1="-1.58" x2="68.26" y2="56.63" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-5" x1="20.19" y1="-8.28" x2="75.33" y2="49.93" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-6" x1="4.78" y1="6.32" x2="59.92" y2="64.53" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-7" x1="4.86" y1="6.24" x2="60.01" y2="64.45" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-8" x1="58.01" y1="29.76" x2="89.14" y2="-1.37" gradientUnits="userSpaceOnUse"><stop offset="0.26" stop-color="#e31587"/><stop offset="0.63" stop-color="#ff298a"/><stop offset="1" stop-color="#ff8a50"/></linearGradient></defs><title>fx-fenix_error_4</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M105,57A8,8,0,0,1,97,65H65.22a6.08,6.08,0,0,1,0-12.15,6.26,6.26,0,0,1,1.45.18,6.48,6.48,0,0,1-.16-1.41,6.26,6.26,0,0,1,9.81-5.16A10.53,10.53,0,0,1,97,49.09,8,8,0,0,1,105,57Z"/><path class="cls-2" d="M203.71,26.36a8.76,8.76,0,0,0-2.19.27,9.31,9.31,0,0,0,.24-2.12A9.45,9.45,0,0,0,187,16.72a15.88,15.88,0,0,0-31.24,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,0,0,0-18.21Z"/><path class="cls-3" d="M50.12,4.18a31,31,0,0,1,31,31c0,.42,0,.84,0,1.26a3.68,3.68,0,0,1-.52,7.32h-.66A31,31,0,1,1,50.12,4.18Z"/><path class="cls-4" d="M19.11,36.45q0-.63,0-1.26a30.86,30.86,0,0,1,8.55-21.37A31.88,31.88,0,0,0,71.48,57.67,31,31,0,0,1,20.3,43.78h-.7a3.68,3.68,0,0,1-.49-7.33Z"/><path class="cls-5" d="M65.62,28.93h0a6.44,6.44,0,0,1-4.83-2.16,1.07,1.07,0,0,1,1.61-1.41,4.28,4.28,0,0,0,3.22,1.45h0a4.28,4.28,0,0,0,3.22-1.45,1.06,1.06,0,0,1,1.58,1.42A6.4,6.4,0,0,1,65.62,28.93Z"/><path class="cls-6" d="M30.65,22.26A1,1,0,0,1,30,22a1.07,1.07,0,0,1-.09-1.51,6.49,6.49,0,0,1,4.83-2.16h0a6.47,6.47,0,0,1,4.82,2.16,1.06,1.06,0,0,1-.1,1.51,1.05,1.05,0,0,1-1.5-.1,4.35,4.35,0,0,0-3.22-1.45h0a4.25,4.25,0,0,0-3.22,1.45A1.14,1.14,0,0,1,30.65,22.26Z"/><path class="cls-7" d="M65.52,41.54A8.19,8.19,0,0,1,62,40.76a1.16,1.16,0,0,1-.55-1.54A1.15,1.15,0,0,1,63,38.68a6,6,0,0,0,5.19-.07,1.15,1.15,0,0,1,1.55.52,1.16,1.16,0,0,1-.52,1.54A8.44,8.44,0,0,1,65.52,41.54Z"/><path class="cls-8" d="M50,56a8.2,8.2,0,0,1-3.49-.79,1.15,1.15,0,1,1,1-2.08,6,6,0,0,0,5.18-.07,1.16,1.16,0,1,1,1,2.07A8.55,8.55,0,0,1,50,56Z"/><path class="cls-9" d="M59.5,47.07a1.29,1.29,0,0,0-1.81.25,4.07,4.07,0,0,1-6.56,0,6.66,6.66,0,0,0-10.68,0,1.3,1.3,0,1,0,2.07,1.56,4.06,4.06,0,0,1,6.55,0h0a6.65,6.65,0,0,0,5.34,2.69h0a6.67,6.67,0,0,0,5.34-2.69A1.31,1.31,0,0,0,59.5,47.07Z"/><path class="cls-9" d="M34.67,25.17a3.38,3.38,0,0,1,3.4,3.4V36.2c0,1.89-1.51,1.17-3.4,1.17h0c-1.88,0-3.4.72-3.4-1.17V28.57a3.4,3.4,0,0,1,3.4-3.4Z"/><path class="cls-9" d="M70.27,34.5a1.07,1.07,0,0,0-.1-.39,4.87,4.87,0,0,0-9.08,0,1,1,0,0,0-.1.39A1.43,1.43,0,0,0,63.37,36a3,3,0,0,1,2.27-1h0a3,3,0,0,1,2.28,1,1.44,1.44,0,0,0,2,.11A1.46,1.46,0,0,0,70.27,34.5Z"/><path class="cls-10" d="M31.58,38.92a1.15,1.15,0,0,1-.51-2.18,8.2,8.2,0,0,1,7.2-.1,1.15,1.15,0,1,1-1,2.08,6,6,0,0,0-5.19.07A1.25,1.25,0,0,1,31.58,38.92Z"/><path class="cls-11" d="M83.74,7c0,5.59-6.21,5.21-6.21,9.08v0a.81.81,0,0,1-.81.81H73.33a.81.81,0,0,1-.81-.81v-.23c0-6,5.46-5.59,5.46-8.39,0-1.21-.9-1.93-2.39-1.93A5.14,5.14,0,0,0,72,7.1a.79.79,0,0,1-1,.05L68.75,5.41a.81.81,0,0,1-.09-1.2,10,10,0,0,1,7.49-3.07C81.22,1.14,83.74,3.87,83.74,7Zm-5.52,16.2A3.15,3.15,0,1,1,75.07,20,3.13,3.13,0,0,1,78.22,23.15Z"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_eye_roll.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_eye_roll.svg
new file mode 100644
index 0000000000..3f8a939693
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_eye_roll.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:#ffbd4f;}.cls-6{fill:#cc3d00;}.cls-7{fill:url(#linear-gradient-3);}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="matrix(1, 0.01, 0, 0.7, 0.04, 23.76)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="75.92" y1="60.35" x2="25.11" y2="9.54" gradientTransform="matrix(-1, 0, 0, 1, 100.19, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-2" x1="0.08" y1="-15.49" x2="117.35" y2="101.78" gradientTransform="matrix(-1, 0, 0, 1, 100.19, 0)" gradientUnits="userSpaceOnUse"><stop offset="0.4" stop-color="#ffd567"/><stop offset="0.86" stop-color="#ffc456"/><stop offset="1" stop-color="#ffbd4f"/></linearGradient><linearGradient id="linear-gradient-3" x1="3.98" y1="6.32" x2="59.13" y2="64.53" gradientUnits="userSpaceOnUse"><stop offset="0.25" stop-color="#ffd567"/><stop offset="1" stop-color="#ffa436"/></linearGradient></defs><title>fx-fenix_error_7</title><path class="cls-1" d="M4.43,34.39A23.25,23.25,0,0,1,27.72,11.18l174.59.49a23.25,23.25,0,1,1-.07,46.49l-174.6-.48A23.25,23.25,0,0,1,4.43,34.39Z"/><path class="cls-2" d="M142.55,24a8,8,0,0,1-8,7.9l-31.83-.18a6.08,6.08,0,0,1,.07-12.15,5.9,5.9,0,0,1,1.46.19,5.5,5.5,0,0,1-.16-1.41A6.27,6.27,0,0,1,114,13.27,10.53,10.53,0,0,1,134.68,16,8,8,0,0,1,142.55,24Z"/><path class="cls-2" d="M206.71,48.43a8.81,8.81,0,0,0-2.19.25,9.84,9.84,0,0,0,.26-2.12A9.46,9.46,0,0,0,190,38.7a15.87,15.87,0,0,0-31.25,3.81,11.93,11.93,0,1,0-.14,23.86l48,.27a9.11,9.11,0,1,0,.1-18.21Z"/><path class="cls-3" d="M50.14,3.47a31,31,0,0,1,31,31c0,.42,0,.84,0,1.26a3.67,3.67,0,0,1-.52,7.31H80A31,31,0,1,1,50.14,3.47Z"/><path class="cls-4" d="M19.13,35.75c0-.42,0-.84,0-1.26a30.86,30.86,0,0,1,8.55-21.37A31.88,31.88,0,0,0,71.5,57,31,31,0,0,1,20.33,43.08h-.71a3.68,3.68,0,0,1-.49-7.33Z"/><path class="cls-5" d="M61.31,26.81a1.06,1.06,0,0,0,.8-.37A4.36,4.36,0,0,1,65.34,25h0a4.27,4.27,0,0,1,3.22,1.45A1.07,1.07,0,1,0,70.15,25a6.45,6.45,0,0,0-4.83-2.17h0A6.48,6.48,0,0,0,60.49,25a1.06,1.06,0,0,0,.1,1.51A1,1,0,0,0,61.31,26.81Z"/><path class="cls-5" d="M31,19.81a1.08,1.08,0,0,0,.8-.37A4.34,4.34,0,0,1,35,18h0a4.29,4.29,0,0,1,3.23,1.45,1.06,1.06,0,0,0,1.5.09A1.07,1.07,0,0,0,39.8,18,6.48,6.48,0,0,0,35,15.85h0A6.45,6.45,0,0,0,30.14,18,1.08,1.08,0,0,0,31,19.81Z"/><path class="cls-6" d="M43.85,51.9a1.65,1.65,0,0,0,1.27.71c.08,0,1.9.08,4.91.08s4.83-.08,4.9-.08a1.65,1.65,0,0,0,1.27-.71,1.62,1.62,0,0,0,.22-1.43c-.42-1.39-2.33-2-6.38-2s-5.95.59-6.39,2A1.75,1.75,0,0,0,43.85,51.9Z"/><path class="cls-6" d="M59.43,31.39v1.78a1.29,1.29,0,0,0,0,.35,3.51,3.51,0,0,0,7-.35v0h2.3a1.75,1.75,0,1,0,0-3.49h-7.6A1.76,1.76,0,0,0,59.43,31.39Z"/><path class="cls-6" d="M29.55,31.39v1.78a1.29,1.29,0,0,0,0,.35,3.52,3.52,0,0,0,7-.35v0h2.31a1.75,1.75,0,0,0,0-3.49H31.31a1.75,1.75,0,0,0-1.75,1.75Z"/><path class="cls-7" d="M30.7,39a1.17,1.17,0,0,1-1-.63,1.15,1.15,0,0,1,.52-1.55,8.2,8.2,0,0,1,7.2-.1,1.15,1.15,0,1,1-1,2.08,6,6,0,0,0-5.18.07A1.11,1.11,0,0,1,30.7,39Z"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_hourglass.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_hourglass.svg
new file mode 100644
index 0000000000..62d88c9e19
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_hourglass.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#radial-gradient-2);}.cls-4{fill:url(#linear-gradient);}.cls-5{fill:url(#linear-gradient-2);}.cls-6{fill:#ffb587;}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><radialGradient id="radial-gradient-2" cx="25.52" cy="-3.12" r="113.73" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff4de"/><stop offset="0.15" stop-color="#fff1d9"/><stop offset="0.32" stop-color="#ffe7cc"/><stop offset="0.5" stop-color="#ffd6b5"/><stop offset="0.69" stop-color="#ffbf95"/><stop offset="0.76" stop-color="#ffb587"/></radialGradient><linearGradient id="linear-gradient" x1="17.06" y1="12.67" x2="58.93" y2="45.61" gradientUnits="userSpaceOnUse"><stop offset="0.44" stop-color="#ff8a50"/><stop offset="0.91" stop-color="#ff298a"/></linearGradient><linearGradient id="linear-gradient-2" x1="21.99" y1="63.28" x2="81.31" y2="3.96" gradientUnits="userSpaceOnUse"><stop offset="0.24" stop-color="#e31587"/><stop offset="0.63" stop-color="#ff298a"/><stop offset="1" stop-color="#ff8a50"/></linearGradient></defs><title>fx-fenix_error_8</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M238.23,29.47a8,8,0,0,1-7.91,8H198.49a6.08,6.08,0,0,1,0-12.16,5.84,5.84,0,0,1,1.46.19,6,6,0,0,1-.17-1.41,6.28,6.28,0,0,1,9.81-5.17,10.54,10.54,0,0,1,20.73,2.65A7.94,7.94,0,0,1,238.23,29.47Z"/><path class="cls-2" d="M98,37.08a9.25,9.25,0,0,0-2.19.27,9.84,9.84,0,0,0,.24-2.12,9.45,9.45,0,0,0-14.79-7.78,15.87,15.87,0,0,0-31.23,4,11.93,11.93,0,1,0,0,23.85H98a9.11,9.11,0,0,0,0-18.21Z"/><path class="cls-3" d="M60.21,25.49c-2.44,2.44-5.34,5.6-5.7,9.72.36,4.12,3.26,7.29,5.7,9.72A15.48,15.48,0,0,1,65.6,56.68v0h0v6.62h-31V56.7h0v0A15.48,15.48,0,0,1,40,44.93c2.44-2.43,5.34-5.6,5.7-9.72-.36-4.12-3.26-7.28-5.7-9.72a15.46,15.46,0,0,1-5.39-11.75V7h31v6.71A15.46,15.46,0,0,1,60.21,25.49Z"/><path class="cls-4" d="M50.09,55.48c1.16,0,7,6.39,7,6.39h-14S48.94,55.48,50.09,55.48ZM49.48,47a.7.7,0,1,0,.69.69A.69.69,0,0,0,49.48,47Zm.69,2.48a.7.7,0,1,0,.7.69A.69.69,0,0,0,50.17,49.49Zm-1.69,4.16a.7.7,0,1,0,.7.69A.69.69,0,0,0,48.48,53.65Zm2.08-9.82a.7.7,0,1,0,.69.7A.7.7,0,0,0,50.56,43.83Zm-12-24.76c0,2.89,3.27,5.48,5.3,7.23,1.5,1.51,4.07,4.34,4.07,7.91,0,.12,0,.23,0,.34.07,2.92.44,6.16,1.37,7.32a.7.7,0,1,0,1.24.44.69.69,0,0,0,0-.13c1.24-.76,1.68-4.73,1.72-8.23.21-3,2.63-6.21,4.07-7.65,2-1.75,5.3-4.34,5.3-7.23C61.63,17.66,38.56,17.66,38.56,19.07ZM50.9,52.32a.7.7,0,1,0,.69.7A.7.7,0,0,0,50.9,52.32Z"/><g id="Layer_4" data-name="Layer 4"><path class="cls-5" d="M65.6,8.76h-31a1.73,1.73,0,0,1,0-3.46h31a1.73,1.73,0,1,1,0,3.46Zm1.73,54.56a1.73,1.73,0,0,0-1.73-1.73h-31a1.73,1.73,0,0,0,0,3.46h31A1.74,1.74,0,0,0,67.33,63.32Z"/></g><g id="Layer_5" data-name="Layer 5"><path class="cls-6" d="M61.63,18.65c0,1.08-5.16,1.94-11.54,1.94s-11.53-.86-11.53-1.94,5.16-1.93,11.53-1.93S61.63,17.58,61.63,18.65Z"/></g></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_inspect.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_inspect.svg
new file mode 100644
index 0000000000..b64c203ae7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_inspect.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:#cc3d00;}.cls-6{fill:url(#linear-gradient-3);}.cls-7{fill:url(#linear-gradient-4);}.cls-8{fill:url(#linear-gradient-5);}.cls-9{fill:url(#linear-gradient-6);}.cls-10{fill:#ffbd4f;}.cls-11{fill:url(#linear-gradient-7);}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="76.3" y1="61.03" x2="25.49" y2="10.22" gradientTransform="matrix(-1, 0, 0, 1, 100.19, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-2" x1="0.47" y1="-14.81" x2="117.73" y2="102.46" gradientTransform="matrix(-1, 0, 0, 1, 100.19, 0)" gradientUnits="userSpaceOnUse"><stop offset="0.4" stop-color="#ffd567"/><stop offset="0.86" stop-color="#ffc456"/><stop offset="1" stop-color="#ffbd4f"/></linearGradient><linearGradient id="linear-gradient-3" x1="32.96" y1="-14.67" x2="79.83" y2="42.94" gradientUnits="userSpaceOnUse"><stop offset="0.25" stop-color="#ffd567"/><stop offset="1" stop-color="#ffa436"/></linearGradient><linearGradient id="linear-gradient-4" x1="12.99" y1="1.58" x2="59.86" y2="59.19" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-5" x1="6.75" y1="6.72" x2="53.62" y2="64.33" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-6" x1="28.56" y1="-11.09" x2="75.43" y2="46.52" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-7" x1="47.79" y1="16.87" x2="1.03" y2="63.63" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff7139"/><stop offset="0.22" stop-color="#ff624a"/><stop offset="0.66" stop-color="#ff3c75"/><stop offset="0.86" stop-color="#ff298a"/></linearGradient></defs><title>fx-fenix_error_1</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M109.55,21.81a8,8,0,0,1-7.91,8H69.81a6.08,6.08,0,0,1,0-12.16,5.84,5.84,0,0,1,1.46.19,6,6,0,0,1-.17-1.41,6.28,6.28,0,0,1,9.81-5.17,10.54,10.54,0,0,1,20.73,2.65A7.94,7.94,0,0,1,109.55,21.81Z"/><path class="cls-2" d="M234.35,42.44a9.25,9.25,0,0,0-2.19.27,9.84,9.84,0,0,0,.24-2.12,9.45,9.45,0,0,0-14.79-7.78,15.87,15.87,0,0,0-31.23,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,0,0,0-18.21Z"/><path class="cls-3" d="M49.76,4.15a31,31,0,0,1,31,31c0,.42,0,.84,0,1.26a3.67,3.67,0,0,1-.52,7.31h-.66A31,31,0,1,1,49.76,4.15Z"/><path class="cls-4" d="M18.75,36.43q0-.63,0-1.26A30.86,30.86,0,0,1,27.27,13.8,31.88,31.88,0,0,0,71.12,57.65,31,31,0,0,1,19.94,43.76h-.7a3.68,3.68,0,0,1-3.68-3.69A3.64,3.64,0,0,1,18.75,36.43Z"/><circle class="cls-5" cx="55.16" cy="46.74" r="4.02"/><path class="cls-5" d="M33.61,20.86a5.19,5.19,0,0,1,5.2,5.2V37.74c0,2.88-2.32,3.22-5.2,3.22h0c-2.88,0-5.2-.34-5.2-3.22V26.06a5.19,5.19,0,0,1,5.2-5.2Z"/><path class="cls-5" d="M68.61,34.77v-3a3.4,3.4,0,0,0-6.79,0v3Z"/><path class="cls-6" d="M69.23,26.05h-8a1.07,1.07,0,1,1,0-2.13h8a1.07,1.07,0,0,1,0,2.13Z"/><path class="cls-7" d="M55.11,54.88a5.34,5.34,0,0,1-2.21-.49,1.06,1.06,0,0,1,.92-1.92,3,3,0,0,0,2.66,0,1.07,1.07,0,0,1,1,1.91A5.2,5.2,0,0,1,55.11,54.88Z"/><path class="cls-8" d="M38.79,41.44H28.54a1.64,1.64,0,1,1,0-3.27H38.79a1.64,1.64,0,1,1,0,3.27Z"/><path class="cls-9" d="M68.55,35H61.87a1.07,1.07,0,0,1,0-2.14h6.68a1.07,1.07,0,1,1,0,2.14Z"/><path class="cls-5" d="M45.84,19a17.33,17.33,0,0,0-26.09,22.7l-2.67,2.67,3.39,3.39,2.67-2.67A17.33,17.33,0,0,0,45.84,19ZM33.58,45.43a14.15,14.15,0,0,1-13.42-9.69l.06.27a14.14,14.14,0,0,1,23.3-14.77l0,0a14.14,14.14,0,0,1-10,24.17Z"/><path class="cls-10" d="M24,23A14.14,14.14,0,0,1,47.33,28.2a14.11,14.11,0,1,0-27.17,7.54A14.13,14.13,0,0,1,24,23Z"/><g id="Layer_5" data-name="Layer 5"><path class="cls-11" d="M2.62,62h0C1,60.34.44,58.29,1.31,57.44L16.62,43.82c.88-.85,2.3-.82,3.89.83h0c1.6,1.64,1.58,3.06.7,3.91L7.13,63.44C6.25,64.29,4.22,63.63,2.62,62Z"/></g><polygon class="cls-5" points="4.41 54.82 10.06 60.47 16.88 53.04 11.84 47.99 4.41 54.82"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_lock.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_lock.svg
new file mode 100644
index 0000000000..fc72ea7b8e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_lock.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:#ffa266;opacity:0.8;}.cls-6{fill:#b1b1bc;}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="47.51" y1="28.54" x2="84.23" y2="-8.18" gradientUnits="userSpaceOnUse"><stop offset="0.07" stop-color="#e31587"/><stop offset="0.29" stop-color="#ff298a"/><stop offset="0.7" stop-color="#ff8a50"/></linearGradient><linearGradient id="linear-gradient-2" x1="80.65" y1="22.6" x2="33.16" y2="67.53" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff7139"/><stop offset="0.22" stop-color="#ff624a"/><stop offset="0.66" stop-color="#ff3c75"/><stop offset="0.86" stop-color="#ff298a"/></linearGradient></defs><title>fx-fenix_error_5</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M239,55.51a7.94,7.94,0,0,1-7.92,8H199.26a6.08,6.08,0,0,1,0-12.15,5.9,5.9,0,0,1,1.46.18,6,6,0,0,1-.17-1.41,6.28,6.28,0,0,1,9.81-5.17,10.53,10.53,0,0,1,20.72,2.65A7.94,7.94,0,0,1,239,55.51Z"/><path class="cls-2" d="M104.13,27.89a8.74,8.74,0,0,0-2.18.27,9.84,9.84,0,0,0,.24-2.12A9.45,9.45,0,0,0,87.4,18.26a15.87,15.87,0,0,0-31.23,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,1,0,0-18.21Z"/><path class="cls-3" d="M66.28,34.75A2.59,2.59,0,0,1,63,33L58.61,18.57A9.24,9.24,0,0,0,40.94,24a2.6,2.6,0,0,1-5,1.52,14.43,14.43,0,0,1,27.6-8.46L68,31.51A2.6,2.6,0,0,1,66.28,34.75Z"/><g id="Layer_3" data-name="Layer 3"><path class="cls-4" d="M76.37,54.16,46.16,63.42a5.33,5.33,0,0,1-6.67-3.54L34.14,42.41a5.33,5.33,0,0,1,3.54-6.67l30.21-9.26A5.34,5.34,0,0,1,74.56,30l5.36,17.47A5.35,5.35,0,0,1,76.37,54.16Z"/></g><g id="Layer_4" data-name="Layer 4"><path class="cls-5" d="M44.23,59.51l-.26.08a1.53,1.53,0,0,1-1.91-1L37,42.05a1.52,1.52,0,0,1,1-1.91l.25-.08a1.54,1.54,0,0,1,1.91,1l5.07,16.53A1.53,1.53,0,0,1,44.23,59.51Z"/></g><path class="cls-6" d="M19.47,32.68l13-2.16a.17.17,0,0,0,0-.34L19.47,28a.17.17,0,0,0-.2.17v4.33A.17.17,0,0,0,19.47,32.68Z"/><g id="Layer_3-2" data-name="Layer 3"><path class="cls-6" d="M23.61,41.74l8.88-6.9a.17.17,0,0,0-.15-.3l-10.83,3a.17.17,0,0,0-.11.24l2,3.86A.17.17,0,0,0,23.61,41.74Z"/></g><g id="Layer_4-2" data-name="Layer 4"><path class="cls-6" d="M21.51,23.11l10.83,3a.17.17,0,0,0,.15-.3L23.61,19a.17.17,0,0,0-.26.06l-2,3.86A.17.17,0,0,0,21.51,23.11Z"/></g></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_no_internet.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_no_internet.svg
new file mode 100644
index 0000000000..cdb183fb97
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_no_internet.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:url(#linear-gradient-3);}.cls-6{fill:url(#linear-gradient-4);}.cls-7{fill:url(#linear-gradient-5);}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="29.85" y1="50.09" x2="66.88" y2="13.07" gradientUnits="userSpaceOnUse"><stop offset="0.23" stop-color="#e31587"/><stop offset="1" stop-color="#ff298a"/></linearGradient><linearGradient id="linear-gradient-2" x1="38.42" y1="58.65" x2="75.44" y2="21.63" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-3" x1="35.56" y1="55.8" x2="72.58" y2="18.77" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-4" x1="32.71" y1="52.94" x2="69.73" y2="15.92" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-5" x1="24.89" y1="60.37" x2="73.67" y2="11.59" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff298a"/><stop offset="1" stop-color="#ff7139"/></linearGradient></defs><title>fx-fenix_error_3</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M242.83,38.66a8,8,0,0,1-7.92,8H203.09a6.08,6.08,0,0,1,0-12.15,5.9,5.9,0,0,1,1.46.18,6,6,0,0,1-.17-1.41,6.28,6.28,0,0,1,9.81-5.17,10.53,10.53,0,0,1,20.72,2.65A7.94,7.94,0,0,1,242.83,38.66Z"/><path class="cls-2" d="M113.32,46.27a9.23,9.23,0,0,0-2.18.27,9.84,9.84,0,0,0,.24-2.12,9.45,9.45,0,0,0-14.79-7.78,15.87,15.87,0,0,0-31.23,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,1,0,0-18.21Z"/><path class="cls-3" d="M66.55,32a2.3,2.3,0,0,1-1.36-.44,25.62,25.62,0,0,0-29.89,0,2.34,2.34,0,1,1-2.73-3.8,30.28,30.28,0,0,1,35.34,0A2.34,2.34,0,0,1,66.55,32Z"/><path class="cls-4" d="M54.31,49.17A2.3,2.3,0,0,1,53,48.73a4.69,4.69,0,0,0-5.42,0,2.34,2.34,0,1,1-2.72-3.8,9.42,9.42,0,0,1,10.87,0,2.34,2.34,0,0,1-1.37,4.24Z"/><path class="cls-5" d="M58.39,43.46A2.3,2.3,0,0,1,57,43a11.82,11.82,0,0,0-13.58,0,2.34,2.34,0,0,1-2.73-3.8,16.57,16.57,0,0,1,19,0,2.34,2.34,0,0,1-1.37,4.24Z"/><path class="cls-6" d="M62.47,37.75a2.3,2.3,0,0,1-1.36-.44,18.92,18.92,0,0,0-21.74,0,2.34,2.34,0,1,1-2.72-3.8,23.27,23.27,0,0,1,27.18,0,2.34,2.34,0,0,1-1.36,4.24Z"/><g id="Layer_5" data-name="Layer 5"><path class="cls-7" d="M50.29,4a31,31,0,1,0,31,31A31,31,0,0,0,50.29,4ZM32.08,53.17a25.73,25.73,0,0,1-1.65-34.58L66.67,54.83a25.76,25.76,0,0,1-34.59-1.66ZM70.35,51.1,34.16,14.9A25.74,25.74,0,0,1,70.35,51.1Z"/></g></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_question_file.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_question_file.svg
new file mode 100644
index 0000000000..9bc4e60044
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_question_file.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:url(#linear-gradient-3);}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="25.2" y1="59.03" x2="68.31" y2="15.92" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-2" x1="-5.38" y1="-38.79" x2="59.3" y2="55.74" gradientUnits="userSpaceOnUse"><stop offset="0.35" stop-color="#ffd567"/><stop offset="0.9" stop-color="#ffa436"/></linearGradient><linearGradient id="linear-gradient-3" x1="28.71" y1="53.17" x2="63.08" y2="18.8" gradientUnits="userSpaceOnUse"><stop offset="0.26" stop-color="#e31587"/><stop offset="0.63" stop-color="#ff298a"/><stop offset="1" stop-color="#ff8a50"/></linearGradient></defs><title>fx-fenix_error_12</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M109.55,21.81a8,8,0,0,1-7.91,8H69.81a6.08,6.08,0,0,1,0-12.16,5.84,5.84,0,0,1,1.46.19,6,6,0,0,1-.17-1.41,6.28,6.28,0,0,1,9.81-5.17,10.54,10.54,0,0,1,20.73,2.65A7.94,7.94,0,0,1,109.55,21.81Z"/><path class="cls-2" d="M189.11,48.67a9.31,9.31,0,0,0-2.19.26,9.22,9.22,0,0,0,.24-2.11A9.45,9.45,0,0,0,172.38,39a15.88,15.88,0,0,0-31.24,4,11.93,11.93,0,1,0,0,23.86h48a9.11,9.11,0,1,0,0-18.21Z"/><path class="cls-3" d="M68,63.86,32.38,64a5.28,5.28,0,0,1-5.31-5.26l-.2-49a5.29,5.29,0,0,1,5.27-5.32l22.21-.09A5.26,5.26,0,0,1,58.1,5.86L71.6,19.21A5.28,5.28,0,0,1,73.17,23l.15,35.59A5.31,5.31,0,0,1,68,63.86Z"/><g id="Layer_4" data-name="Layer 4"><path class="cls-4" d="M48.71,12.73H35.54a1.35,1.35,0,0,1,0-2.7H48.71a1.35,1.35,0,1,1,0,2.7Zm1.35,7.48a1.35,1.35,0,0,0-1.35-1.34H35.54a1.35,1.35,0,1,0,0,2.69H48.71A1.35,1.35,0,0,0,50.06,20.21Zm0,8.84a1.35,1.35,0,0,0-1.35-1.35H35.54a1.35,1.35,0,0,0,0,2.7H48.71A1.36,1.36,0,0,0,50.06,29.05Zm11.4,8.83a1.35,1.35,0,0,0-1.35-1.35H35.54a1.35,1.35,0,0,0,0,2.7H60.11A1.36,1.36,0,0,0,61.46,37.88ZM66,29.05a1.34,1.34,0,0,0-1.35-1.35H55.56a1.35,1.35,0,0,0,0,2.7h9.09A1.35,1.35,0,0,0,66,29.05ZM56.57,46.71a1.35,1.35,0,0,0-1.35-1.35H35.54a1.35,1.35,0,0,0,0,2.7H55.22A1.35,1.35,0,0,0,56.57,46.71Zm8,8.83a1.35,1.35,0,0,0-1.35-1.35H35.54a1.35,1.35,0,0,0,0,2.7h27.7A1.34,1.34,0,0,0,64.59,55.54Z"/></g><path class="cls-5" d="M59.71,25.83c0,7-7.81,6.56-7.81,11.41v0a1,1,0,0,1-1,1H46.63a1,1,0,0,1-1-1V37c0-7.5,6.86-7,6.86-10.54,0-1.52-1.13-2.43-3-2.43A6.52,6.52,0,0,0,45,26a1,1,0,0,1-1.32.06l-2.8-2.19a1,1,0,0,1-.11-1.5,12.52,12.52,0,0,1,9.41-3.85C56.54,18.55,59.71,22,59.71,25.83ZM52.77,46.18a4,4,0,1,1-4-4A3.94,3.94,0,0,1,52.77,46.18Z"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_shred_file.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_shred_file.svg
new file mode 100644
index 0000000000..a7df64add3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_shred_file.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:url(#linear-gradient-3);}.cls-6{fill:url(#linear-gradient-4);}.cls-7{fill:url(#linear-gradient-5);}.cls-8{fill:url(#linear-gradient-6);}.cls-9{fill:url(#radial-gradient-2);}.cls-10{fill:url(#linear-gradient-7);}.cls-11{fill:url(#linear-gradient-8);}.cls-12{fill:url(#linear-gradient-9);}.cls-13{fill:url(#linear-gradient-10);}.cls-14{fill:url(#linear-gradient-11);}.cls-15{fill:url(#linear-gradient-12);}.cls-16{fill:url(#linear-gradient-13);}.cls-17{fill:url(#linear-gradient-14);}.cls-18{fill:url(#linear-gradient-15);}.cls-19{fill:url(#linear-gradient-16);}.cls-20{fill:url(#linear-gradient-17);}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="15.02" y1="84.89" x2="70.79" y2="29.12" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-2" x1="18.75" y1="73.73" x2="74.52" y2="17.96" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-3" x1="0.09" y1="96.83" x2="55.86" y2="41.06" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-4" x1="6.43" y1="77.84" x2="62.2" y2="22.07" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-5" x1="20.2" y1="58.66" x2="75.97" y2="2.89" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-6" x1="21.49" y1="98.33" x2="77.26" y2="42.56" xlink:href="#linear-gradient"/><radialGradient id="radial-gradient-2" cx="15.16" cy="-31.08" r="110.94" gradientUnits="userSpaceOnUse"><stop offset="0.35" stop-color="#ffea80"/><stop offset="1" stop-color="#ffbd4f"/></radialGradient><linearGradient id="linear-gradient-7" x1="6.05" y1="-29.94" x2="57.88" y2="45.81" gradientUnits="userSpaceOnUse"><stop offset="0.35" stop-color="#ffd567"/><stop offset="0.9" stop-color="#ffa436"/></linearGradient><linearGradient id="linear-gradient-8" x1="12.83" y1="-34.59" x2="64.66" y2="41.16" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-9" x1="-4.9" y1="-22.45" x2="46.93" y2="53.3" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-10" x1="0.69" y1="-26.28" x2="52.52" y2="49.47" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-11" x1="6.28" y1="-30.11" x2="58.11" y2="45.64" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-12" x1="16.05" y1="-36.79" x2="67.88" y2="38.96" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-13" x1="-1.6" y1="-24.71" x2="50.23" y2="51.04" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-14" x1="3.99" y1="-28.54" x2="55.82" y2="47.21" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-15" x1="6.24" y1="-30.07" x2="58.07" y2="45.68" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-16" x1="9.53" y1="-32.33" x2="61.36" y2="43.42" xlink:href="#linear-gradient-7"/><linearGradient id="linear-gradient-17" x1="10.99" y1="1.15" x2="76.77" y2="54.97" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff298a"/><stop offset="1" stop-color="#ff7139"/></linearGradient></defs><title>fx-fenix_error_13</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M241.3,32.53a8,8,0,0,1-7.92,7.95H201.56a6.08,6.08,0,0,1,0-12.15,6.26,6.26,0,0,1,1.45.18,6.48,6.48,0,0,1-.16-1.41,6.26,6.26,0,0,1,9.81-5.16,10.53,10.53,0,0,1,20.72,2.64A8,8,0,0,1,241.3,32.53Z"/><path class="cls-2" d="M140.9,48.57a9.25,9.25,0,0,0-2.19.27,9.25,9.25,0,0,0,.24-2.12,9.45,9.45,0,0,0-14.78-7.78,15.88,15.88,0,0,0-31.24,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,1,0,0-18.21Z"/><polygon class="cls-3" points="47.88 47 47.88 52.66 52.31 52.64 52.31 47 47.88 47"/><rect class="cls-4" x="47.88" y="39.93" width="4.43" height="4.91"/><polygon class="cls-5" points="39.67 52.21 39.67 57.89 44.1 57.88 44.1 52.21 39.67 52.21"/><rect class="cls-6" x="39.67" y="39.93" width="4.43" height="4.91"/><path class="cls-7" d="M68.59,19.81a4.26,4.26,0,0,0-1.26-3L56.51,6.11a4.27,4.27,0,0,0-3-1.23L35.71,5a4.25,4.25,0,0,0-4.23,4.26l.17,39.27a4.23,4.23,0,0,0,4.24,4.21v-18h3.78v3H44.1v-3h3.78v3h4.43v-3h3.78v10.1h4.43V34.74H64.3V52.59h.18a4.24,4.24,0,0,0,4.22-4.27ZM38.43,9.46H49a1.08,1.08,0,0,1,0,2.16H38.43a1.08,1.08,0,1,1,0-2.16Zm0,7.07H49a1.09,1.09,0,0,1,0,2.17H38.43a1.09,1.09,0,0,1,0-2.17Zm0,7.08H49a1.08,1.08,0,1,1,0,2.16H38.43a1.08,1.08,0,0,1,0-2.16Zm19.69,9.24H38.43a1.08,1.08,0,1,1,0-2.16H58.12a1.08,1.08,0,1,1,0,2.16Zm3.64-7.08H54.48a1.08,1.08,0,1,1,0-2.16h7.28a1.08,1.08,0,1,1,0,2.16Z"/><polygon class="cls-8" points="56.09 58.72 56.09 64.33 60.52 64.31 60.52 58.72 56.09 58.72"/><path class="cls-9" d="M58.12,30.69H38.43a1.08,1.08,0,1,0,0,2.16H58.12a1.08,1.08,0,1,0,0-2.16Z"/><path class="cls-10" d="M58.12,30.69H38.43a1.08,1.08,0,1,0,0,2.16H58.12a1.08,1.08,0,1,0,0-2.16Z"/><path class="cls-9" d="M38.43,11.62H49a1.08,1.08,0,0,0,0-2.16H38.43a1.08,1.08,0,1,0,0,2.16Z"/><path class="cls-11" d="M38.43,11.62H49a1.08,1.08,0,0,0,0-2.16H38.43a1.08,1.08,0,1,0,0,2.16Z"/><rect class="cls-9" x="39.67" y="44.84" width="4.43" height="2.16"/><rect class="cls-12" x="39.67" y="44.84" width="4.43" height="2.16"/><rect class="cls-9" x="47.88" y="44.84" width="4.43" height="2.16"/><rect class="cls-13" x="47.88" y="44.84" width="4.43" height="2.16"/><rect class="cls-9" x="56.09" y="44.84" width="4.43" height="2.16"/><rect class="cls-14" x="56.09" y="44.84" width="4.43" height="2.16"/><path class="cls-9" d="M61.76,23.61H54.48a1.08,1.08,0,1,0,0,2.16h7.28a1.08,1.08,0,1,0,0-2.16Z"/><path class="cls-15" d="M61.76,23.61H54.48a1.08,1.08,0,1,0,0,2.16h7.28a1.08,1.08,0,1,0,0-2.16Z"/><rect class="cls-9" x="39.67" y="37.76" width="4.43" height="2.16"/><rect class="cls-16" x="39.67" y="37.76" width="4.43" height="2.16"/><rect class="cls-9" x="47.88" y="37.76" width="4.43" height="2.16"/><rect class="cls-17" x="47.88" y="37.76" width="4.43" height="2.16"/><path class="cls-9" d="M38.43,25.77H49a1.08,1.08,0,1,0,0-2.16H38.43a1.08,1.08,0,0,0,0,2.16Z"/><path class="cls-18" d="M38.43,25.77H49a1.08,1.08,0,1,0,0-2.16H38.43a1.08,1.08,0,0,0,0,2.16Z"/><path class="cls-9" d="M38.43,18.7H49a1.09,1.09,0,0,0,0-2.17H38.43a1.09,1.09,0,0,0,0,2.17Z"/><path class="cls-19" d="M38.43,18.7H49a1.09,1.09,0,0,0,0-2.17H38.43a1.09,1.09,0,0,0,0,2.17Z"/><path class="cls-20" d="M76.12,35.39H24.19a2.33,2.33,0,0,1-2.34-1.87,2.25,2.25,0,0,1,2.22-2.63H76a2.37,2.37,0,0,1,2.4,1.92A2.25,2.25,0,0,1,76.12,35.39Z"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_surprised.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_surprised.svg
new file mode 100644
index 0000000000..94889f53d0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_surprised.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#radial-gradient);}.cls-2{fill:#cdcdd4;opacity:0.15;}.cls-3{fill:url(#linear-gradient);}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:#cc3d00;}.cls-6{fill:url(#linear-gradient-3);}.cls-7{fill:url(#linear-gradient-4);}.cls-8{fill:url(#linear-gradient-5);}.cls-9{fill:url(#linear-gradient-6);}.cls-10{fill:url(#linear-gradient-7);}</style><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient" x1="-1068.38" y1="60.76" x2="-1119.19" y2="9.95" gradientTransform="matrix(-1, 0, 0, 1, -1043.81, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-2" x1="-1144.21" y1="-15.08" x2="-1026.95" y2="102.18" gradientTransform="matrix(-1, 0, 0, 1, -1043.81, 0)" gradientUnits="userSpaceOnUse"><stop offset="0.4" stop-color="#ffd567"/><stop offset="0.86" stop-color="#ffc456"/><stop offset="1" stop-color="#ffbd4f"/></linearGradient><linearGradient id="linear-gradient-3" x1="21.26" y1="-19.95" x2="85.41" y2="44.2" gradientUnits="userSpaceOnUse"><stop offset="0.25" stop-color="#ffd567"/><stop offset="1" stop-color="#ffa436"/></linearGradient><linearGradient id="linear-gradient-4" x1="2.02" y1="-0.71" x2="66.17" y2="63.44" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-5" x1="16.77" y1="-15.46" x2="80.92" y2="48.69" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-6" x1="9.32" y1="-8.02" x2="73.47" y2="56.13" xlink:href="#linear-gradient-3"/><linearGradient id="linear-gradient-7" x1="-0.86" y1="2.17" x2="63.29" y2="66.32" xlink:href="#linear-gradient-3"/></defs><title>fx-fenix_error_9</title><path class="cls-1" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-2" d="M216.79,21.81a8,8,0,0,1-7.92,8H177.05a6.08,6.08,0,0,1,0-12.16,5.76,5.76,0,0,1,1.45.19,6.62,6.62,0,0,1-.16-1.41,6.28,6.28,0,0,1,9.81-5.17,10.53,10.53,0,0,1,20.72,2.65A8,8,0,0,1,216.79,21.81Z"/><path class="cls-2" d="M152.39,26.36a8.76,8.76,0,0,0-2.19.27,9.31,9.31,0,0,0,.24-2.12,9.45,9.45,0,0,0-14.78-7.79,15.88,15.88,0,0,0-31.24,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,1,0,0-18.21Z"/><path class="cls-3" d="M50.44,3.88a31,31,0,0,1,31,31c0,.42,0,.85,0,1.27a3.67,3.67,0,0,1-.52,7.31h-.66A31,31,0,1,1,50.44,3.88Z"/><path class="cls-4" d="M19.43,36.16c0-.42,0-.85,0-1.27A30.88,30.88,0,0,1,28,13.52,31.87,31.87,0,0,0,71.8,57.37,31,31,0,0,1,20.62,43.48h-.7a3.68,3.68,0,0,1-.49-7.32Z"/><circle class="cls-5" cx="55.56" cy="46.16" r="4.02"/><path class="cls-5" d="M69,34.2v-3a3.39,3.39,0,1,0-6.78,0v3Z"/><path class="cls-6" d="M69.63,25.48h-8a1.07,1.07,0,0,1,0-2.14h8a1.07,1.07,0,1,1,0,2.14Z"/><path class="cls-7" d="M55.51,54.31a5.27,5.27,0,0,1-2.2-.49,1.06,1.06,0,1,1,.91-1.92,3,3,0,0,0,2.66,0,1.07,1.07,0,0,1,1,1.91A5.28,5.28,0,0,1,55.51,54.31Z"/><path class="cls-8" d="M69,34.45H62.27a1.07,1.07,0,1,1,0-2.13H69a1.07,1.07,0,0,1,0,2.13Z"/><path class="cls-9" d="M38.8,16.35a1,1,0,0,1,.7.27,1.06,1.06,0,0,1,.08,1.5,6.44,6.44,0,0,1-4.82,2.17h0a6.44,6.44,0,0,1-4.82-2.17,1.06,1.06,0,1,1,1.6-1.4,4.34,4.34,0,0,0,3.22,1.45h0A4.27,4.27,0,0,0,38,16.72,1,1,0,0,1,38.8,16.35Z"/><path class="cls-5" d="M34.77,25.45a3.4,3.4,0,0,1,3.41,3.4v7.64c0,1.88-1.52,2.1-3.41,2.1h0c-1.88,0-3.4-.22-3.4-2.1V28.85a3.4,3.4,0,0,1,3.4-3.4Z"/><path class="cls-10" d="M38.16,38.9h-6.7a1.07,1.07,0,1,1,0-2.13h6.7a1.07,1.07,0,1,1,0,2.13Z"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_unplugged.svg b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_unplugged.svg
new file mode 100644
index 0000000000..719986efbf
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/assets/mozac_error_unplugged.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 70"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#radial-gradient);}.cls-3{fill:#cdcdd4;opacity:0.15;}.cls-4{fill:url(#linear-gradient-2);}.cls-5{fill:#ededf0;}.cls-6{fill:url(#linear-gradient-3);}.cls-7{fill:url(#linear-gradient-4);}.cls-8{clip-path:url(#clip-path);}.cls-9{fill:url(#linear-gradient-6);}.cls-10{fill:url(#linear-gradient-7);}.cls-11{fill:url(#linear-gradient-8);}.cls-12{fill:url(#linear-gradient-9);}.cls-13{fill:url(#linear-gradient-10);}.cls-14{fill:url(#linear-gradient-11);}.cls-15{fill:url(#linear-gradient-12);}.cls-16{fill:url(#linear-gradient-13);}.cls-17{fill:url(#linear-gradient-14);}.cls-18{fill:url(#linear-gradient-15);}.cls-19{fill:url(#linear-gradient-16);}.cls-20{fill:url(#linear-gradient-17);}.cls-21{fill:url(#linear-gradient-18);}.cls-22{fill:url(#linear-gradient-19);}.cls-23{fill:url(#linear-gradient-20);}.cls-24{fill:url(#linear-gradient-21);}.cls-25{fill:url(#linear-gradient-22);}.cls-26{fill:url(#linear-gradient-23);}.cls-27{fill:url(#linear-gradient-24);}.cls-28{fill:url(#linear-gradient-25);}.cls-29{fill:url(#linear-gradient-26);}.cls-30{fill:url(#linear-gradient-27);}.cls-31{fill:url(#linear-gradient-28);}.cls-32{fill:url(#linear-gradient-29);}.cls-33{fill:url(#linear-gradient-30);}.cls-34{fill:url(#linear-gradient-31);}.cls-35{fill:url(#linear-gradient-32);}.cls-36{fill:url(#linear-gradient-33);}.cls-37{fill:url(#linear-gradient-34);}.cls-38{fill:url(#linear-gradient-35);}.cls-39{fill:url(#linear-gradient-36);}.cls-40{fill:url(#linear-gradient-37);}.cls-41{fill:url(#linear-gradient-38);}.cls-42{fill:url(#linear-gradient-39);}.cls-43{fill:url(#linear-gradient-40);}.cls-44{fill:url(#linear-gradient-41);}.cls-45{fill:url(#linear-gradient-42);}.cls-46{fill:url(#linear-gradient-43);}.cls-47{fill:url(#linear-gradient-44);}.cls-48{fill:url(#linear-gradient-45);}.cls-49{fill:url(#linear-gradient-46);}.cls-50{fill:url(#linear-gradient-47);}.cls-51{fill:url(#linear-gradient-48);}.cls-52{fill:url(#linear-gradient-49);}.cls-53{fill:url(#linear-gradient-50);}.cls-54{fill:url(#linear-gradient-51);}.cls-55{fill:url(#linear-gradient-52);}.cls-56{fill:url(#linear-gradient-53);}.cls-57{fill:url(#linear-gradient-54);}.cls-58{fill:url(#linear-gradient-55);}.cls-59{fill:url(#linear-gradient-56);}.cls-60{fill:url(#linear-gradient-57);}.cls-61{fill:url(#linear-gradient-58);}.cls-62{fill:url(#linear-gradient-59);}.cls-63{fill:url(#linear-gradient-60);}.cls-64{fill:url(#linear-gradient-61);}.cls-65{fill:url(#linear-gradient-62);}.cls-66{fill:url(#linear-gradient-63);}.cls-67{fill:url(#linear-gradient-64);}.cls-68{fill:url(#linear-gradient-65);}.cls-69{fill:url(#linear-gradient-66);}.cls-70{fill:url(#linear-gradient-67);}.cls-71{fill:url(#linear-gradient-68);}.cls-72{fill:#ffbd4f;}.cls-73{fill:#cc3d00;}</style><linearGradient id="linear-gradient" x1="70.63" y1="-19.77" x2="143.74" y2="53.34" gradientUnits="userSpaceOnUse"><stop offset="0.44" stop-color="#ff8a50"/><stop offset="0.91" stop-color="#ff298a"/></linearGradient><radialGradient id="radial-gradient" cx="143.54" cy="81.07" r="146.71" gradientTransform="translate(0 24.46) scale(1 0.7)" gradientUnits="userSpaceOnUse"><stop offset="0.08" stop-color="#cdcdd4" stop-opacity="0"/><stop offset="0.36" stop-color="#cdcdd4" stop-opacity="0.02"/><stop offset="0.65" stop-color="#cdcdd4" stop-opacity="0.08"/><stop offset="0.94" stop-color="#cdcdd4" stop-opacity="0.18"/><stop offset="1" stop-color="#cdcdd4" stop-opacity="0.2"/></radialGradient><linearGradient id="linear-gradient-2" x1="89.14" y1="29.87" x2="133.56" y2="-24.13" gradientUnits="userSpaceOnUse"><stop offset="0.07" stop-color="#e31587"/><stop offset="0.29" stop-color="#ff298a"/><stop offset="0.7" stop-color="#ff8a50"/></linearGradient><linearGradient id="linear-gradient-3" x1="44.2" y1="6.66" x2="117.31" y2="79.77" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-4" x1="62.2" y1="-11.34" x2="135.31" y2="61.77" xlink:href="#linear-gradient"/><clipPath id="clip-path"><path class="cls-1" d="M98.33,21.53l13.6-13.6a1.66,1.66,0,0,1,2.35,0h0a1.66,1.66,0,0,1,0,2.35l-.45.45a2.88,2.88,0,0,1,.34.27l6,6.06a3.65,3.65,0,0,1,.49,4.56,1,1,0,0,0,.14,1.24,4.67,4.67,0,0,1,1,5.09l4.31,5.79a2.12,2.12,0,0,1-.43,3,2.08,2.08,0,0,1-1.27.42,2.13,2.13,0,0,1-1.71-.85L119,31.16a4.66,4.66,0,0,1-5.69-.7,1,1,0,0,0-1.25-.14,3.66,3.66,0,0,1-4.56-.49l-6.06-6.06a2.24,2.24,0,0,1-.27-.34l-.45.45a1.66,1.66,0,0,1-2.35,0h0A1.68,1.68,0,0,1,98.33,21.53Z"/></clipPath><linearGradient id="linear-gradient-6" x1="85.1" y1="-34.24" x2="158.21" y2="38.87" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-7" x1="84.82" y1="-33.96" x2="157.93" y2="39.15" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-8" x1="84.53" y1="-33.67" x2="157.64" y2="39.44" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-9" x1="84.24" y1="-33.38" x2="157.35" y2="39.73" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-10" x1="83.94" y1="-33.08" x2="157.05" y2="40.02" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-11" x1="83.65" y1="-32.79" x2="156.76" y2="40.32" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-12" x1="83.36" y1="-32.5" x2="156.47" y2="40.61" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-13" x1="83.07" y1="-32.21" x2="156.18" y2="40.9" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-14" x1="82.77" y1="-31.91" x2="155.88" y2="41.19" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-15" x1="82.48" y1="-31.62" x2="155.59" y2="41.49" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-16" x1="82.19" y1="-31.33" x2="155.3" y2="41.78" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-17" x1="81.9" y1="-31.04" x2="155.01" y2="42.07" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-18" x1="81.6" y1="-30.74" x2="154.71" y2="42.36" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-19" x1="81.31" y1="-30.45" x2="154.42" y2="42.66" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-20" x1="81.02" y1="-30.16" x2="154.13" y2="42.95" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-21" x1="80.73" y1="-29.87" x2="153.84" y2="43.24" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-22" x1="80.43" y1="-29.57" x2="153.54" y2="43.53" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-23" x1="80.14" y1="-29.28" x2="153.25" y2="43.83" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-24" x1="79.85" y1="-28.99" x2="152.96" y2="44.12" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-25" x1="79.56" y1="-28.7" x2="152.67" y2="44.41" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-26" x1="79.26" y1="-28.4" x2="152.37" y2="44.7" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-27" x1="78.97" y1="-28.11" x2="152.08" y2="45" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-28" x1="78.68" y1="-27.82" x2="151.79" y2="45.29" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-29" x1="78.39" y1="-27.53" x2="151.5" y2="45.58" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-30" x1="78.09" y1="-27.23" x2="151.2" y2="45.87" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-31" x1="77.8" y1="-26.94" x2="150.91" y2="46.17" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-32" x1="77.51" y1="-26.65" x2="150.62" y2="46.46" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-33" x1="77.21" y1="-26.35" x2="150.32" y2="46.76" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-34" x1="76.92" y1="-26.06" x2="150.02" y2="47.05" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-35" x1="76.62" y1="-25.76" x2="149.73" y2="47.35" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-36" x1="76.32" y1="-25.46" x2="149.43" y2="47.65" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-37" x1="76.02" y1="-25.16" x2="149.13" y2="47.95" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-38" x1="75.73" y1="-24.87" x2="148.84" y2="48.24" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-39" x1="75.43" y1="-24.57" x2="148.54" y2="48.54" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-40" x1="75.13" y1="-24.27" x2="148.24" y2="48.84" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-41" x1="74.84" y1="-23.97" x2="147.94" y2="49.13" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-42" x1="74.54" y1="-23.68" x2="147.65" y2="49.43" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-43" x1="74.24" y1="-23.38" x2="147.35" y2="49.73" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-44" x1="73.94" y1="-23.08" x2="147.05" y2="50.03" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-45" x1="73.65" y1="-22.79" x2="146.76" y2="50.32" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-46" x1="73.35" y1="-22.49" x2="146.46" y2="50.62" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-47" x1="73.05" y1="-22.19" x2="146.16" y2="50.92" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-48" x1="72.76" y1="-21.89" x2="145.86" y2="51.21" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-49" x1="72.46" y1="-21.6" x2="145.57" y2="51.51" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-50" x1="72.16" y1="-21.3" x2="145.27" y2="51.81" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-51" x1="71.86" y1="-21" x2="144.97" y2="52.11" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-52" x1="71.57" y1="-20.71" x2="144.68" y2="52.4" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-53" x1="71.27" y1="-20.41" x2="144.38" y2="52.7" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-54" x1="70.98" y1="-20.12" x2="144.09" y2="52.99" gradientTransform="translate(48.26 -72.48) rotate(43.03)" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-55" x1="70.69" y1="-19.83" x2="143.8" y2="53.28" gradientTransform="matrix(0.73, 0.68, -0.68, 0.73, 48.37, -72.2)" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-56" x1="70.4" y1="-19.53" x2="143.5" y2="53.57" gradientTransform="translate(48.48 -71.92) rotate(43.03)" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-57" x1="70.11" y1="-19.25" x2="143.21" y2="53.86" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-58" x1="69.82" y1="-18.96" x2="142.93" y2="54.15" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-59" x1="69.53" y1="-18.67" x2="142.64" y2="54.44" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-60" x1="69.25" y1="-18.38" x2="142.35" y2="54.72" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-61" x1="68.96" y1="-18.1" x2="142.07" y2="55.01" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-62" x1="68.67" y1="-17.81" x2="141.78" y2="55.3" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-63" x1="68.38" y1="-17.52" x2="141.49" y2="55.59" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-64" x1="68.1" y1="-17.24" x2="141.21" y2="55.87" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-65" x1="67.81" y1="-16.95" x2="140.92" y2="56.16" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-66" x1="61.85" y1="-10.99" x2="134.96" y2="62.12" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-67" x1="-1068.45" y1="61" x2="-1119.26" y2="10.19" gradientTransform="matrix(-1, 0, 0, 1, -1043.81, 0)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffd567"/><stop offset="1" stop-color="#fff361"/></linearGradient><linearGradient id="linear-gradient-68" x1="-1144.28" y1="-14.84" x2="-1027.02" y2="102.42" gradientTransform="matrix(-1, 0, 0, 1, -1043.81, 0)" gradientUnits="userSpaceOnUse"><stop offset="0.4" stop-color="#ffd567"/><stop offset="0.86" stop-color="#ffc456"/><stop offset="1" stop-color="#ffbd4f"/></linearGradient></defs><title>fx-fenix_error_6</title><path class="cls-2" d="M4.45,35.06A23.24,23.24,0,0,1,27.6,11.73l174.6-.5a23.25,23.25,0,1,1,.18,46.49l-174.59.5A23.25,23.25,0,0,1,4.45,35.06Z"/><path class="cls-3" d="M109.55,21.81a8,8,0,0,1-7.91,8H69.81a6.08,6.08,0,0,1,0-12.16,5.84,5.84,0,0,1,1.46.19,6,6,0,0,1-.17-1.41,6.28,6.28,0,0,1,9.81-5.17,10.54,10.54,0,0,1,20.73,2.65A7.94,7.94,0,0,1,109.55,21.81Z"/><path class="cls-3" d="M237.41,25.59a9.31,9.31,0,0,0-2.19.27,9.25,9.25,0,0,0,.24-2.12A9.45,9.45,0,0,0,220.68,16a15.88,15.88,0,0,0-31.24,4,11.93,11.93,0,1,0,0,23.85h48a9.11,9.11,0,1,0,0-18.21Z"/><path class="cls-4" d="M101.94,3.8a1.2,1.2,0,0,1,1.7,0l8.41,8.84a1.21,1.21,0,0,1-1.75,1.66L101.9,5.5a1.23,1.23,0,0,1-.34-.86A1.21,1.21,0,0,1,101.94,3.8Zm-7.16,7.3a1.2,1.2,0,0,0,.33.86l8.41,8.84a1.2,1.2,0,1,0,1.74-1.66L96.85,10.3a1.2,1.2,0,0,0-1.7-.05A1.18,1.18,0,0,0,94.78,11.1Z"/><path class="cls-5" d="M62.21,54.14a.52.52,0,0,1,.52-.54h.86a.54.54,0,0,1,.53.51.54.54,0,0,1-.52.55l-.86,0h0A.53.53,0,0,1,62.21,54.14Zm4-.2a.53.53,0,0,1,.46-.59c1.34-.17,2.73-.41,4.13-.73a.53.53,0,1,1,.24,1,42.53,42.53,0,0,1-4.24.75h-.06A.53.53,0,0,1,66.23,53.94Zm-8.65.3a27.41,27.41,0,0,1-4.19-1.08.52.52,0,0,1-.33-.67.53.53,0,0,1,.68-.33,25.22,25.22,0,0,0,4,1,.53.53,0,0,1,.43.62.53.53,0,0,1-.52.44Zm-7.19-2.31-.77-.38a.53.53,0,1,1,.48-.95l.75.37a.54.54,0,0,1,.25.71.53.53,0,0,1-.48.3A.46.46,0,0,1,50.39,51.93Zm-49-3.06a.53.53,0,0,1,0-.75s.23-.24.64-.62a.53.53,0,0,1,.75,0,.53.53,0,0,1,0,.75c-.39.35-.59.56-.59.56h0a.56.56,0,0,1-.39.17A.51.51,0,0,1,1.37,48.87Zm43.82,0c-1.07-.73-2.07-1.47-3-2.18l-.41-.31a.53.53,0,1,1,.63-.85l.41.3c1,.71,2,1.44,3,2.16a.53.53,0,0,1-.3,1A.58.58,0,0,1,45.19,48.89Zm-40.8-2.7a.54.54,0,0,1,.11-.74A36.16,36.16,0,0,1,8.12,43.1a.53.53,0,0,1,.72.2.52.52,0,0,1-.2.72A37,37,0,0,0,5.13,46.3a.51.51,0,0,1-.31.11A.53.53,0,0,1,4.39,46.19Zm34.76-1.61-.7-.46a.52.52,0,0,1-.17-.73.53.53,0,0,1,.73-.17l.73.47a.53.53,0,0,1-.3,1A.51.51,0,0,1,39.15,44.58ZM34,42a30.3,30.3,0,0,0-4-1.23.53.53,0,0,1,.24-1A33.68,33.68,0,0,1,34.34,41a.53.53,0,0,1-.19,1A.63.63,0,0,1,34,42Zm-21.47-.37a.55.55,0,0,1,.31-.69l.81-.29a.53.53,0,1,1,.35,1l-.78.29a.63.63,0,0,1-.19,0A.54.54,0,0,1,12.49,41.58Zm3.84-1.25a.53.53,0,0,1,.39-.64A28.55,28.55,0,0,1,21,39a.53.53,0,0,1,.57.48.54.54,0,0,1-.48.58,27.68,27.68,0,0,0-4.11.66l-.13,0A.52.52,0,0,1,16.33,40.33Zm10.57-.17-.83-.09a.52.52,0,0,1-.48-.57.53.53,0,0,1,.58-.48l.86.09A.53.53,0,0,1,27,40.17Z"/><path class="cls-6" d="M114.3,64.51a16.79,16.79,0,0,0,5.49-.93,1.11,1.11,0,0,0,.7-1.41,1.13,1.13,0,0,0-1.42-.7c-6.65,2.27-12.27-.62-18.77-4C92.56,53.51,83.78,49,71,52a1.11,1.11,0,0,0-.83,1.34,1.13,1.13,0,0,0,1.35.83A31.19,31.19,0,0,1,87,54.3a60.54,60.54,0,0,1,12.25,5.18C104.27,62.05,109,64.51,114.3,64.51Z"/><path class="cls-7" d="M118,63.12a1.43,1.43,0,0,1,.89-1.82c.25-.08.5-.17.74-.27a1.44,1.44,0,0,1,1.86.82,1.43,1.43,0,0,1-.82,1.85l-.85.32a1.53,1.53,0,0,1-.47.07A1.42,1.42,0,0,1,118,63.12Zm4.72-1.92a1.43,1.43,0,0,1,.32-2,12.62,12.62,0,0,0,2.7-2.66,1.43,1.43,0,0,1,2.31,1.7,15.47,15.47,0,0,1-3.33,3.28,1.45,1.45,0,0,1-.84.27A1.42,1.42,0,0,1,122.74,61.2Zm6-7a1.44,1.44,0,0,1-1-1.75c.06-.25.12-.5.17-.75a1.43,1.43,0,1,1,2.81.56c-.06.3-.13.61-.21.91a1.44,1.44,0,0,1-1.39,1.07A1.53,1.53,0,0,1,128.72,54.21Zm-.63-6.35a19,19,0,0,0-.71-3.87,1.42,1.42,0,0,1,1-1.77,1.44,1.44,0,0,1,1.78,1,22.57,22.57,0,0,1,.81,4.46,1.43,1.43,0,0,1-1.33,1.53h-.11A1.43,1.43,0,0,1,128.09,47.86Zm-2.5-8.33c-.12-.24-.25-.48-.38-.72a1.43,1.43,0,0,1,2.51-1.38c.15.26.29.53.42.79a1.44,1.44,0,0,1-.62,1.93,1.39,1.39,0,0,1-.65.16A1.44,1.44,0,0,1,125.59,39.53ZM123,35.38a39,39,0,0,0-2.56-3.2,1.43,1.43,0,0,1,2.14-1.9c1,1.12,1.92,2.27,2.75,3.42a1.44,1.44,0,0,1-.33,2,1.42,1.42,0,0,1-.83.27A1.45,1.45,0,0,1,123,35.38Zm-6-6.72-.61-.56a1.43,1.43,0,1,1,1.9-2.14l.65.59A1.43,1.43,0,0,1,117,28.66Zm-3.8-3.2c-.69-.53-1.41-1.06-2.13-1.57a1.43,1.43,0,0,1,1.66-2.34c.75.54,1.5,1.09,2.22,1.64a1.43,1.43,0,0,1-.88,2.57A1.41,1.41,0,0,1,113.19,25.46Z"/><path class="cls-1" d="M98.33,21.53l13.6-13.6a1.66,1.66,0,0,1,2.35,0h0a1.66,1.66,0,0,1,0,2.35l-.45.45a2.88,2.88,0,0,1,.34.27l6,6.06a3.65,3.65,0,0,1,.49,4.56,1,1,0,0,0,.14,1.24,4.67,4.67,0,0,1,1,5.09l4.31,5.79a2.12,2.12,0,0,1-.43,3,2.08,2.08,0,0,1-1.27.42,2.13,2.13,0,0,1-1.71-.85L119,31.16a4.66,4.66,0,0,1-5.69-.7,1,1,0,0,0-1.25-.14,3.66,3.66,0,0,1-4.56-.49l-6.06-6.06a2.24,2.24,0,0,1-.27-.34l-.45.45a1.66,1.66,0,0,1-2.35,0h0A1.68,1.68,0,0,1,98.33,21.53Z"/><g class="cls-8"><polygon class="cls-9" points="126.39 7.28 126.88 7.82 126.88 7.28 126.39 7.28"/><polygon class="cls-10" points="125.82 7.28 126.88 8.42 126.88 7.82 126.39 7.28 125.82 7.28"/><polygon class="cls-11" points="125.26 7.28 126.88 9.03 126.88 8.42 125.82 7.28 125.26 7.28"/><polygon class="cls-12" points="124.69 7.28 126.88 9.63 126.88 9.03 125.26 7.28 124.69 7.28"/><polygon class="cls-13" points="124.13 7.28 126.88 10.23 126.88 9.63 124.69 7.28 124.13 7.28"/><polygon class="cls-14" points="123.56 7.28 126.88 10.84 126.88 10.23 124.13 7.28 123.56 7.28"/><polygon class="cls-15" points="123 7.28 126.88 11.45 126.88 10.84 123.56 7.28 123 7.28"/><polygon class="cls-16" points="122.43 7.28 126.88 12.05 126.88 11.45 123 7.28 122.43 7.28"/><polygon class="cls-17" points="121.87 7.28 126.88 12.66 126.88 12.05 122.43 7.28 121.87 7.28"/><polygon class="cls-18" points="121.3 7.28 126.88 13.26 126.88 12.66 121.87 7.28 121.3 7.28"/><polygon class="cls-19" points="120.74 7.28 126.88 13.87 126.88 13.26 121.3 7.28 120.74 7.28"/><polygon class="cls-20" points="120.17 7.28 126.88 14.47 126.88 13.87 120.74 7.28 120.17 7.28"/><polygon class="cls-21" points="119.61 7.28 126.88 15.08 126.88 14.47 120.17 7.28 119.61 7.28"/><polygon class="cls-22" points="119.04 7.28 126.88 15.68 126.88 15.08 119.61 7.28 119.04 7.28"/><polygon class="cls-23" points="118.48 7.28 126.88 16.29 126.88 15.68 119.04 7.28 118.48 7.28"/><polygon class="cls-24" points="117.91 7.28 126.88 16.89 126.88 16.29 118.48 7.28 117.91 7.28"/><polygon class="cls-25" points="117.35 7.28 126.88 17.5 126.88 16.89 117.91 7.28 117.35 7.28"/><polygon class="cls-26" points="116.78 7.28 126.88 18.1 126.88 17.5 117.35 7.28 116.78 7.28"/><polygon class="cls-27" points="116.22 7.28 126.88 18.71 126.88 18.1 116.78 7.28 116.22 7.28"/><polygon class="cls-28" points="115.66 7.28 126.88 19.31 126.88 18.71 116.22 7.28 115.66 7.28"/><polygon class="cls-29" points="115.09 7.28 126.88 19.92 126.88 19.31 115.66 7.28 115.09 7.28"/><polygon class="cls-30" points="114.53 7.28 126.88 20.52 126.88 19.92 115.09 7.28 114.53 7.28"/><polygon class="cls-31" points="113.96 7.28 126.88 21.13 126.88 20.52 114.53 7.28 113.96 7.28"/><polygon class="cls-32" points="113.4 7.28 126.88 21.73 126.88 21.13 113.96 7.28 113.4 7.28"/><polygon class="cls-33" points="112.83 7.28 126.88 22.34 126.88 21.73 113.4 7.28 112.83 7.28"/><polygon class="cls-34" points="112.27 7.28 112.27 7.28 126.88 22.94 126.88 22.34 112.83 7.28 112.27 7.28"/><polygon class="cls-35" points="112.27 7.28 111.97 7.57 126.88 23.55 126.88 22.94 112.27 7.28"/><polygon class="cls-36" points="111.97 7.57 111.66 7.85 126.88 24.15 126.88 23.55 111.97 7.57"/><polygon class="cls-37" points="111.66 7.85 111.36 8.13 126.88 24.76 126.88 24.15 111.66 7.85"/><polygon class="cls-38" points="111.36 8.13 111.06 8.41 126.88 25.36 126.88 24.76 111.36 8.13"/><polygon class="cls-39" points="111.06 8.41 110.76 8.69 126.88 25.97 126.88 25.36 111.06 8.41"/><polygon class="cls-40" points="110.76 8.69 110.46 8.97 126.88 26.57 126.88 25.97 110.76 8.69"/><polygon class="cls-41" points="110.46 8.97 110.15 9.26 126.88 27.18 126.88 26.57 110.46 8.97"/><polygon class="cls-42" points="110.15 9.26 109.85 9.54 126.88 27.78 126.88 27.18 110.15 9.26"/><polygon class="cls-43" points="109.85 9.54 109.55 9.82 126.88 28.39 126.88 27.78 109.85 9.54"/><polygon class="cls-44" points="109.55 9.82 109.25 10.1 126.88 28.99 126.88 28.39 109.55 9.82"/><polygon class="cls-45" points="109.25 10.1 108.95 10.38 126.88 29.6 126.88 28.99 109.25 10.1"/><polygon class="cls-46" points="108.95 10.38 108.64 10.66 126.88 30.2 126.88 29.6 108.95 10.38"/><polygon class="cls-47" points="108.64 10.66 108.34 10.95 126.88 30.81 126.88 30.2 108.64 10.66"/><polygon class="cls-48" points="108.34 10.95 108.04 11.23 126.88 31.41 126.88 30.81 108.34 10.95"/><polygon class="cls-49" points="108.04 11.23 107.74 11.51 126.88 32.02 126.88 31.41 108.04 11.23"/><polygon class="cls-50" points="107.74 11.51 107.44 11.79 126.88 32.63 126.88 32.02 107.74 11.51"/><polygon class="cls-51" points="107.44 11.79 107.14 12.07 126.88 33.23 126.88 32.63 107.44 11.79"/><polygon class="cls-52" points="107.14 12.07 106.83 12.35 126.88 33.84 126.88 33.23 107.14 12.07"/><polygon class="cls-53" points="106.83 12.35 106.53 12.64 126.88 34.44 126.88 33.84 106.83 12.35"/><polygon class="cls-54" points="106.53 12.64 106.23 12.92 126.88 35.05 126.88 34.44 106.53 12.64"/><polygon class="cls-55" points="106.23 12.92 105.93 13.2 126.88 35.65 126.88 35.05 106.23 12.92"/><polygon class="cls-56" points="105.93 13.2 105.63 13.48 126.82 36.19 126.88 36.13 126.88 35.65 105.93 13.2"/><rect class="cls-57" x="115.87" y="9.44" width="0.41" height="31.06" transform="translate(14.18 85.92) rotate(-43.03)"/><rect class="cls-58" x="115.57" y="9.73" width="0.41" height="31.06" transform="translate(13.9 85.79) rotate(-43.03)"/><rect class="cls-59" x="115.26" y="10.01" width="0.41" height="31.06" transform="translate(13.63 85.66) rotate(-43.03)"/><polygon class="cls-60" points="104.72 14.33 104.42 14.61 125.45 37.14 125.8 37.14 125.92 37.03 104.72 14.33"/><polygon class="cls-61" points="104.42 14.61 104.12 14.89 124.89 37.14 125.45 37.14 104.42 14.61"/><polygon class="cls-62" points="104.12 14.89 103.82 15.17 124.32 37.14 124.89 37.14 104.12 14.89"/><polygon class="cls-63" points="103.82 15.17 103.51 15.45 123.76 37.14 124.32 37.14 103.82 15.17"/><polygon class="cls-64" points="103.51 15.45 103.21 15.73 123.19 37.14 123.76 37.14 103.51 15.45"/><polygon class="cls-65" points="103.21 15.73 102.91 16.02 122.63 37.14 123.19 37.14 103.21 15.73"/><polygon class="cls-66" points="102.91 16.02 102.61 16.3 122.06 37.14 122.63 37.14 102.91 16.02"/><polygon class="cls-67" points="102.61 16.3 102.31 16.58 121.5 37.14 122.06 37.14 102.61 16.3"/><polygon class="cls-68" points="102.31 16.58 102 16.86 120.94 37.14 121.5 37.14 102.31 16.58"/><polygon class="cls-69" points="102 16.86 97.69 20.89 97.69 37.14 120.94 37.14 102 16.86"/></g><path class="cls-70" d="M50.51,4.12a31,31,0,0,1,31,31c0,.42,0,.85,0,1.27A3.67,3.67,0,0,1,81,43.71h-.66A31,31,0,1,1,50.51,4.12Z"/><path class="cls-71" d="M19.5,36.4c0-.42,0-.85,0-1.27A30.88,30.88,0,0,1,28,13.76,31.87,31.87,0,0,0,71.87,57.61,31,31,0,0,1,20.69,43.72H20a3.68,3.68,0,0,1-.49-7.32Z"/><path class="cls-72" d="M39,20.18a1.05,1.05,0,0,1-.8-.36A4.32,4.32,0,0,0,35,18.37h0a4.29,4.29,0,0,0-3.23,1.45,1.07,1.07,0,0,1-1.59-1.42A6.45,6.45,0,0,1,35,16.23h0a6.44,6.44,0,0,1,4.83,2.17,1.05,1.05,0,0,1-.1,1.5A1,1,0,0,1,39,20.18Z"/><path class="cls-72" d="M70.37,20.18a1.07,1.07,0,0,1-.8-.36,4.3,4.3,0,0,0-3.22-1.45h0a4.29,4.29,0,0,0-3.23,1.45,1.07,1.07,0,0,1-1.59-1.42,6.41,6.41,0,0,1,4.83-2.17h0a6.41,6.41,0,0,1,4.83,2.17,1.06,1.06,0,0,1-.08,1.5A1.09,1.09,0,0,1,70.37,20.18Z"/><path class="cls-73" d="M35.17,23a3.38,3.38,0,0,1,3.38,3.39V34a3.38,3.38,0,0,1-3.38,3.38h0A3.38,3.38,0,0,1,31.79,34V26.41A3.37,3.37,0,0,1,35.17,23Z"/><path class="cls-73" d="M65.77,23a3.38,3.38,0,0,1,3.38,3.39V34a3.38,3.38,0,0,1-3.38,3.38h0A3.38,3.38,0,0,1,62.39,34V26.41A3.37,3.37,0,0,1,65.77,23Z"/><path class="cls-73" d="M50.83,40.25A6.86,6.86,0,0,0,44,47.09v9.28a1.27,1.27,0,0,0,1.27,1.27H56.42a1.27,1.27,0,0,0,1.27-1.27V47.11A6.86,6.86,0,0,0,50.83,40.25Z"/></svg> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_add_to_homescreen_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_add_to_homescreen_24.xml
new file mode 100644
index 0000000000..c9ab6e5d53
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_add_to_homescreen_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M6.25 4.5A0.75 0.75 0 0 1 7 3.75h10a0.75 0.75 0 0 1 0.75 0.75V5h1.75V4.5A2.5 2.5 0 0 0 17 2H7a2.5 2.5 0 0 0-2.5 2.5v15A2.5 2.5 0 0 0 7 22h10a2.5 2.5 0 0 0 2.5-2.5v-6h-1.75V17H6.25V4.5zM10 20.25h4v-1.5h-4v1.5z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13 13.5h-2v2h2v-2zm-2-3.25h2v2h-2v-2zm5.25 3.25h-2v2h2v-2zm-8.5 0h2v2h-2v-2zm7.78-6.017a0.75 0.75 0 0 0-1.28 0.53V11.5c0 0.414 0.336 0.75 0.75 0.75h3.487a0.75 0.75 0 0 0 0.53-1.28l-1.125-1.125L22 5.738 20.762 4.5l-4.107 4.108-1.125-1.125z"
+ tools:ignore="VectorRaster" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_24.xml
new file mode 100644
index 0000000000..6e30f173e1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.375 11.25h15.25V13H4.375v-1.75zm0 5h15.25V18H4.375v-1.75zm0-10.25h15.25v1.75H4.375V6z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_space_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_space_24.xml
new file mode 100644
index 0000000000..35f9896179
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_app_menu_space_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.375 11.25h15.25V13H4.375v-1.75zm0 5h15.25V18H4.375v-1.75zm0-10.25H12v1.75H4.375V6z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_down_left_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_down_left_24.xml
new file mode 100644
index 0000000000..6ff8a72414
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_down_left_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3.251 19.376c0 0.483 0.392 0.875 0.875 0.875h9.996V18.5H6.24L20.25 4.488l-1.237-1.237L5.001 17.265V9.334h-1.75v10.042z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_left_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_left_24.xml
new file mode 100644
index 0000000000..a3e053f9fc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_left_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.126 3.251a0.875 0.875 0 0 0-0.875 0.875v9.996h1.75V6.24l14.012 14.01 1.238-1.237L6.237 5.001h7.931v-1.75H4.126z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_right_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_right_24.xml
new file mode 100644
index 0000000000..ec4ac86fed
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_append_up_right_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M19.376,3.251c0.483,0 0.875,0.392 0.875,0.875v9.996H18.5V6.24L4.488,20.25l-1.237,-1.237L17.265,5.001H9.334v-1.75h10.042z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_arrow_clockwise_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_arrow_clockwise_24.xml
new file mode 100644
index 0000000000..f618ea5a92
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_arrow_clockwise_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M20.447 12.751h-1.751c-0.377 3.646-3.466 6.499-7.211 6.499-3.998 0-7.25-3.252-7.25-7.25s3.252-7.25 7.25-7.25c2.768 0 5.154 1.573 6.373 3.859l-1.452 1.452A0.55 0.55 0 0 0 16.795 11h4.171a0.55 0.55 0 0 0 0.55-0.55V6.279a0.55 0.55 0 0 0-0.939-0.389l-1.422 1.422C17.572 4.73 14.73 3 11.485 3c-4.963 0-9 4.037-9 9s4.037 9 9 9c4.709 0 8.578-3.637 8.962-8.249z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_24.xml
new file mode 100644
index 0000000000..d5fd8e11e5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.751 4.819V3.068C17.363 3.452 21 7.321 21 12.03c0 4.963-4.037 9-9 9s-9-4.037-9-9c0-3.245 1.73-6.087 4.313-7.669L5.891 2.939A0.55 0.55 0 0 1 6.28 2h4.17A0.55 0.55 0 0 1 11 2.55v4.17a0.55 0.55 0 0 1-0.939 0.389L8.609 5.657C6.323 6.876 4.75 9.262 4.75 12.03c0 3.998 3.252 7.25 7.25 7.25s7.25-3.252 7.25-7.25c0-3.745-2.853-6.834-6.499-7.211z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.5 9.055v5.89a0.803 0.803 0 0 0 1.202 0.697l5.154-2.945a0.803 0.803 0 0 0 0-1.395l-5.154-2.945A0.804 0.804 0 0 0 9.5 9.055z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_slash_24.xml
new file mode 100644
index 0000000000..2b90a56673
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_autoplay_slash_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 6.72a0.55 0.55 0 0 1-0.936 0.391L6.89 2.936A0.549 0.549 0 0 1 7.28 2h4.17A0.55 0.55 0 0 1 12 2.55v4.17zm7.395 8.72a7.21 7.21 0 0 0 0.855-3.41c0-3.744-2.852-6.834-6.499-7.211V3.068C18.363 3.452 22 7.321 22 12.03a8.93 8.93 0 0 1-1.33 4.685l-1.275-1.275zm-2.669-2.668l0.13-0.074a0.803 0.803 0 0 0 0-1.395l-3.734-2.134 3.604 3.603z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M22.25 20.762L3.488 2 2.25 3.238l3.5 3.499A8.87 8.87 0 0 0 4 12.03c0 4.963 4.037 9 9 9a8.92 8.92 0 0 0 5.301-1.741l2.711 2.71 1.238-1.237zM5.75 12.03c0-1.502 0.465-2.888 1.255-4.037l3.495 3.495v3.457a0.804 0.804 0 0 0 1.202 0.698l1.88-1.074 3.465 3.466A7.18 7.18 0 0 1 13 19.28c-3.998 0-7.25-3.252-7.25-7.25z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_24.xml
new file mode 100644
index 0000000000..0bf6b500f1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_24.xml
@@ -0,0 +1,18 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 6a3.006 3.006 0 0 0-2.897 3.799 2.967 2.967 0 0 0 2.098 2.098A3.006 3.006 0 0 0 15 9a3 3 0 0 0-3-3z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 3.75c4.549 0 8.25 3.701 8.25 8.25 0 4.549-3.701 8.25-8.25 8.25-4.549 0-8.25-3.701-8.25-8.25 0-4.549 3.701-8.25 8.25-8.25zM12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 18.75a6.753 6.753 0 0 0 5.908-3.492A2.491 2.491 0 0 0 15.75 14h-7.5c-0.926 0-1.726 0.51-2.158 1.258A6.753 6.753 0 0 0 12 18.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_fill_24.xml
new file mode 100644
index 0000000000..b4726ed624
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_circle_fill_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M10.979 21.948a10.074 10.074 0 0 0 2.48-0.054 9.958 9.958 0 0 0 4.791-2.095v0.002A9.986 9.986 0 0 0 22 12c0-5.514-4.486-10-10-10S2 6.486 2 12a9.986 9.986 0 0 0 3.75 7.8 9.951 9.951 0 0 0 5.229 2.15zM9.103 10.8A3.006 3.006 0 0 1 12 7a3 3 0 0 1 3 3 3.006 3.006 0 0 1-3.8 2.897 2.967 2.967 0 0 1-2.097-2.098zM12 19.75c2.488 0 4.7-1.183 6.119-3.012A2.492 2.492 0 0 0 15.75 15h-7.5a2.492 2.492 0 0 0-2.369 1.738A7.732 7.732 0 0 0 12 19.75z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_info_circle_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_info_circle_fill_24.xml
new file mode 100644
index 0000000000..c2bc674121
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_info_circle_fill_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M1 11C1 5.486 5.486 1 11 1s10 4.486 10 10c0 0.631-0.066 1.246-0.178 1.845A6.464 6.464 0 0 0 18.75 12.5a6.47 6.47 0 0 0-4.149 1.502v-0.001L14.603 14H7.25a2.492 2.492 0 0 0-2.369 1.738A7.732 7.732 0 0 0 11 18.75c0.434 0 0.855-0.048 1.269-0.117a9.483 9.483 0 0 1-0.007 0.107A3.72 3.72 0 0 0 12.25 19a6.5 6.5 0 0 0 0.277 1.871A9.976 9.976 0 0 1 11 21C5.486 21 1 16.514 1 11zm7.103-1.201a2.967 2.967 0 0 0 2.098 2.098A3.006 3.006 0 0 0 14 9a3 3 0 0 0-3-3 3.006 3.006 0 0 0-2.897 3.799z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M18.75 24c-2.757 0-5-2.243-5-5s2.243-5 5-5 5 2.243 5 5-2.243 5-5 5zm0.75-8v1.5H18V16h1.5zm0 2.75V22H18v-3.25h1.5z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_warning_circle_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_warning_circle_fill_24.xml
new file mode 100644
index 0000000000..f0787da169
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_avatar_warning_circle_fill_24.xml
@@ -0,0 +1,22 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="m11.021,20.209 l0.949,-1.523c-0.318,0.041 -0.641,0.064 -0.97,0.064a7.732,7.732 0,0 1,-6.119 -3.012A2.492,2.492 0,0 1,7.25 14h7.5c0.026,0 0.05,0.003 0.076,0.005l0.056,0.005 -2.237,3.592 3.483,-5.591c0.979,-1.571 3.266,-1.571 4.244,0l0.464,0.745A9.973,9.973 0,0 0,21 11c0,-5.514 -4.486,-10 -10,-10S1,5.486 1,11c0,5.418 4.334,9.833 9.715,9.986 0.06,-0.264 0.15,-0.526 0.306,-0.777zM8.103,9.799A3.006,3.006 0,0 1,11 6a3,3 0,0 1,3 3,3.006 3.006,0 0,1 -3.8,2.897 2.967,2.967 0,0 1,-2.097 -2.098z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M22.537,22.436h-8.574a1.25,1.25 0,0 1,-1.085 -1.87l4.285,-7.499a1.252,1.252 0,0 1,2.174 0l4.285,7.499a1.25,1.25 0,0 1,-1.085 1.87zM17.5,15L19,15v2.75h-1.5L17.5,15zM17.5,19L19,19v1.5h-1.5L17.5,19z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_back_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_back_24.xml
new file mode 100644
index 0000000000..e1e62043a9
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_back_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.387 5.375l-6.88 6.881a0.875 0.875 0 0 0 0 1.238l6.88 6.88 1.238-1.237-5.388-5.387H20.75V12H6.237l5.388-5.387-1.238-1.238z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_20.xml
new file mode 100644
index 0000000000..47030805a0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_20.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M10.208 4.085a0.252 0.252 0 0 0-0.42 0.07L9.787 4.157l-1.4 3.52a0.75 0.75 0 0 1-0.65 0.472L3.96 8.389a0.25 0.25 0 0 0-0.141 0.443v0.001l2.91 2.42a0.75 0.75 0 0 1 0.248 0.763l-0.942 3.676a0.217 0.217 0 0 0 0.004 0.14c0.015 0.039 0.045 0.08 0.09 0.112 0.089 0.064 0.188 0.07 0.28 0.012l3.2-2.02a0.75 0.75 0 0 1 0.801 0l3.206 2.024a0.246 0.246 0 0 0 0.367-0.277v-0.001l-0.94-3.666a0.75 0.75 0 0 1 0.247-0.763l2.912-2.42a0.25 0.25 0 0 0-0.141-0.445l-3.778-0.24a0.75 0.75 0 0 1-0.65-0.47l-1.4-3.52a0.77 0.77 0 0 1-0.025-0.073zm1.483-0.321a0.749 0.749 0 0 0-0.046-0.165c-0.589-1.455-2.669-1.477-3.252 0.005L8.392 3.606 7.169 6.682l-3.307 0.21H3.86c-1.574 0.105-2.222 2.081-1 3.095 0 0 0.001 0 0 0l2.546 2.116-0.822 3.209c-0.405 1.542 1.305 2.747 2.626 1.912l2.8-1.767 2.797 1.765c1.348 0.866 3.01-0.385 2.63-1.904l-0.823-3.215 2.544-2.115c1.223-1.014 0.576-2.991-0.998-3.096l-3.309-0.21-1.16-2.918z"
+ tools:ignore="VectorPath,VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_24.xml
new file mode 100644
index 0000000000..360c5809c2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_24.xml
@@ -0,0 +1,14 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7.23 21.5c-0.44 0-0.89-0.14-1.26-0.41a2.13 2.13 0 0 1-0.82-2.27l1.06-4.15-3.3-2.74c-0.68-0.57-0.95-1.48-0.67-2.32 0.27-0.84 1.02-1.43 1.91-1.48l4.28-0.28 1.58-3.98a2.15 2.15 0 0 1 2-1.36c0.89 0 1.67 0.53 2 1.36l1.58 3.98 4.28 0.28c0.88 0.06 1.63 0.64 1.91 1.48 0.27 0.84 0.01 1.76-0.67 2.32l-3.3 2.74 1.06 4.15c0.22 0.86-0.1 1.75-0.82 2.27s-1.67 0.55-2.42 0.08l-3.62-2.29-3.62 2.29c-0.35 0.22-0.75 0.34-1.15 0.34L7.23 21.5zM12 4.25c-0.1 0-0.29 0.03-0.37 0.25L9.84 9C9.72 9.31 9.42 9.53 9.08 9.55L4.25 9.86c-0.24 0.02-0.33 0.18-0.36 0.28-0.03 0.08-0.06 0.28 0.13 0.44l3.72 3.09c0.26 0.22 0.37 0.56 0.29 0.89l-1.19 4.69c-0.06 0.23 0.07 0.37 0.15 0.43 0.08 0.06 0.25 0.14 0.45 0.01l4.09-2.59c0.29-0.18 0.65-0.18 0.93 0l4.09 2.59c0.2 0.13 0.37 0.05 0.45-0.01 0.08-0.06 0.21-0.2 0.15-0.43l-1.2-4.69c-0.08-0.33 0.03-0.67 0.29-0.89l3.72-3.09c0.19-0.16 0.15-0.36 0.13-0.43a0.386 0.386 0 0 0-0.36-0.28L14.9 9.56a0.886 0.886 0 0 1-0.76-0.55l-1.79-4.5a0.378 0.378 0 0 0-0.37-0.25L12 4.25z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_badge_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_badge_fill_20.xml
new file mode 100644
index 0000000000..aa602c8e62
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_badge_fill_20.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="#fff"
+ android:pathData="M10 5.686c0.292 0 0.55 0.175 0.658 0.446l0.86 2.159 2.319 0.15a0.705 0.705 0 0 1 0.628 0.489 0.703 0.703 0 0 1-0.222 0.763l-1.788 1.484 0.574 2.253a0.708 0.708 0 0 1-1.065 0.774L10 12.962l-1.965 1.242a0.706 0.706 0 0 1-0.795-0.026 0.705 0.705 0 0 1-0.27-0.748l0.574-2.252-1.788-1.485A0.705 0.705 0 0 1 5.535 8.93a0.705 0.705 0 0 1 0.627-0.488l2.32-0.15 0.86-2.159A0.704 0.704 0 0 1 10 5.686zm0-1.25c-0.808 0-1.522 0.485-1.82 1.235L7.613 7.095 6.082 7.194a1.95 1.95 0 0 0-1.736 1.35 1.948 1.948 0 0 0 0.611 2.11l1.181 0.981-0.379 1.487a1.95 1.95 0 0 0 0.746 2.068 1.95 1.95 0 0 0 2.198 0.071L10 14.441l1.297 0.82a1.958 1.958 0 0 0 2.944-2.138l-0.379-1.487 1.18-0.98a1.946 1.946 0 0 0 0.612-2.111 1.948 1.948 0 0 0-1.735-1.35l-1.532-0.099-0.568-1.426A1.947 1.947 0 0 0 10 4.436z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7.656 14.314A0.708 0.708 0 0 1 6.97 13.43l0.574-2.252-1.788-1.485A0.705 0.705 0 0 1 5.535 8.93a0.705 0.705 0 0 1 0.627-0.488l2.32-0.15 0.86-2.159A0.704 0.704 0 0 1 10 5.686c0.292 0 0.55 0.175 0.658 0.446l0.86 2.159 2.319 0.15a0.705 0.705 0 0 1 0.628 0.489 0.703 0.703 0 0 1-0.222 0.763l-1.788 1.484 0.574 2.253a0.705 0.705 0 0 1-0.27 0.748 0.706 0.706 0 0 1-0.795 0.026L10 12.962l-1.965 1.242a0.706 0.706 0 0 1-0.379 0.11z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_20.xml
new file mode 100644
index 0000000000..61a9bfe15b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_20.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5.926 17.5c-0.254 0-0.507-0.079-0.723-0.237a1.225 1.225 0 0 1-0.469-1.3l0.997-3.915-3.108-2.581A1.224 1.224 0 0 1 2.239 8.14 1.225 1.225 0 0 1 3.33 7.292L7.362 7.03l1.495-3.754A1.22 1.22 0 0 1 10 2.5c0.508 0 0.956 0.304 1.144 0.776l1.495 3.754 4.032 0.261c0.507 0.033 0.936 0.366 1.092 0.849a1.223 1.223 0 0 1-0.386 1.327l-3.108 2.581 0.997 3.916a1.226 1.226 0 0 1-0.469 1.3c-0.41 0.298-0.951 0.316-1.381 0.045L10 15.149l-3.415 2.159A1.238 1.238 0 0 1 5.926 17.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_24.xml
new file mode 100644
index 0000000000..e5a17775e3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_fill_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6.84 21.5c-0.322 0-0.642-0.101-0.916-0.3a1.55 1.55 0 0 1-0.594-1.647l1.263-4.959-3.938-3.27a1.552 1.552 0 0 1-0.487-1.681A1.553 1.553 0 0 1 3.55 8.568l5.108-0.331 1.893-4.755A1.551 1.551 0 0 1 12 2.5c0.643 0 1.211 0.386 1.449 0.983l1.893 4.755 5.107 0.331a1.552 1.552 0 0 1 1.383 1.076 1.55 1.55 0 0 1-0.489 1.681l-3.936 3.269 1.263 4.96a1.551 1.551 0 0 1-0.595 1.647c-0.519 0.377-1.205 0.4-1.75 0.057L12 18.522l-4.326 2.735A1.565 1.565 0 0 1 6.84 21.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_slash_24.xml
new file mode 100644
index 0000000000..5527aceeef
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_slash_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3.238 1.99L22 20.752l-1.238 1.238-1.95-1.95c-0.14 0.41-0.404 0.776-0.773 1.044a2.142 2.142 0 0 1-2.416 0.078L12 18.873l-3.624 2.288a2.144 2.144 0 0 1-2.416-0.078 2.142 2.142 0 0 1-0.82-2.272l1.059-4.153-3.297-2.738a2.139 2.139 0 0 1-0.673-2.321 2.143 2.143 0 0 1 1.909-1.483l2.583-0.167-4.72-4.721L3.237 1.99zm5.13 7.605L4.251 9.862a0.382 0.382 0 0 0-0.357 0.277 0.383 0.383 0 0 0 0.126 0.434l3.722 3.092a0.872 0.872 0 0 1 0.289 0.889l-1.195 4.689a0.383 0.383 0 0 0 0.154 0.426 0.387 0.387 0 0 0 0.451 0.015l4.091-2.585a0.87 0.87 0 0 1 0.936 0l4.091 2.585a0.385 0.385 0 0 0 0.451-0.015 0.384 0.384 0 0 0 0.154-0.426L16.873 18.1 8.368 9.595z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M21.771 9.599a2.138 2.138 0 0 0-1.908-1.482L15.586 7.84 14 3.857A2.14 2.14 0 0 0 12 2.5a2.14 2.14 0 0 0-2 1.357L9.208 5.848l1.347 1.347 1.071-2.691A0.382 0.382 0 0 1 12 4.25c0.103 0 0.286 0.033 0.375 0.254l1.789 4.495a0.874 0.874 0 0 0 0.756 0.55l4.829 0.313a0.384 0.384 0 0 1 0.357 0.277 0.385 0.385 0 0 1-0.126 0.435l-3.304 2.743 1.243 1.243 3.178-2.639a2.143 2.143 0 0 0 0.674-2.322z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_24.xml
new file mode 100644
index 0000000000..2b35f1e963
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7.203 16.763a1.222 1.222 0 0 0 1.382 0.045L12 14.649l3.416 2.16c0.43 0.271 0.971 0.253 1.381-0.045 0.41-0.298 0.594-0.809 0.469-1.3l-0.997-3.916 3.108-2.581c0.391-0.324 0.543-0.845 0.386-1.327a1.225 1.225 0 0 0-1.092-0.849L14.639 6.53l-1.495-3.754A1.224 1.224 0 0 0 12 2a1.22 1.22 0 0 0-1.143 0.776L9.362 6.53 5.33 6.792A1.225 1.225 0 0 0 4.239 7.64a1.224 1.224 0 0 0 0.384 1.327l3.108 2.581-0.997 3.915a1.225 1.225 0 0 0 0.469 1.3z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5 19.5V17H3.25v2.5a2.5 2.5 0 0 0 2.5 2.5h12.5a2.5 2.5 0 0 0 2.5-2.5V17H19v2.5a0.75 0.75 0 0 1-0.75 0.75H5.75A0.75 0.75 0 0 1 5 19.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_fill_24.xml
new file mode 100644
index 0000000000..2b35f1e963
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_bookmark_tray_fill_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7.203 16.763a1.222 1.222 0 0 0 1.382 0.045L12 14.649l3.416 2.16c0.43 0.271 0.971 0.253 1.381-0.045 0.41-0.298 0.594-0.809 0.469-1.3l-0.997-3.916 3.108-2.581c0.391-0.324 0.543-0.845 0.386-1.327a1.225 1.225 0 0 0-1.092-0.849L14.639 6.53l-1.495-3.754A1.224 1.224 0 0 0 12 2a1.22 1.22 0 0 0-1.143 0.776L9.362 6.53 5.33 6.792A1.225 1.225 0 0 0 4.239 7.64a1.224 1.224 0 0 0 0.384 1.327l3.108 2.581-0.997 3.915a1.225 1.225 0 0 0 0.469 1.3z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5 19.5V17H3.25v2.5a2.5 2.5 0 0 0 2.5 2.5h12.5a2.5 2.5 0 0 0 2.5-2.5V17H19v2.5a0.75 0.75 0 0 1-0.75 0.75H5.75A0.75 0.75 0 0 1 5 19.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_briefcase.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_briefcase.xml
new file mode 100644
index 0000000000..748b164535
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_briefcase.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M23.1,5.3c0-1.4-1.2-2.7-2.8-2.7h-8.7c-1.4,0-2.7,1.2-2.7,2.7v4.4H7.1v19.6h17.8V9.8h-1.8V5.3z M20.8,9.8H11
+ V5.3c0-0.4,0.2-0.5,0.5-0.5h8.7c0.4,0,0.5,0.2,0.5,0.5V9.8z M1.8,9.8h2.7v19.6H1.8c-0.9,0-1.8-0.9-1.8-1.8v-16
+ C0,10.5,0.9,9.8,1.8,9.8z M32,11.6v16c0,0.9-0.7,1.8-1.8,1.8h-2.7V9.8h2.7C31.3,9.8,32,10.5,32,11.6z" />
+</vector>
+
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_broken_lock.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_broken_lock.xml
new file mode 100644
index 0000000000..1f670e0029
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_broken_lock.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7 7.562V11H6.5A2.5 2.5 0 0 0 4 13.5v6A2.5 2.5 0 0 0 6.5 22h11c1.066 0 1.97-0.67 2.329-1.61L18.5 19.061V19.7l-0.8 0.8H6.3l-0.8-0.8v-6.4l0.8-0.8h5.638l-1.5-1.5H8.5V9.062L7 7.562z" />
+ <path
+ android:name="line"
+ android:fillColor="#FF4F5E"
+ android:pathData="M4.78 3.22l17.5 17.5A0.748 0.748 0 0 1 21.749 22a0.748 0.748 0 0 1-0.53-0.22L3.719 4.281A0.75 0.75 0 1 1 4.78 3.22z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 3.5c1.93 0 3.5 1.57 3.5 3.5v4h-0.809l1.5 1.5H17.7l0.8 0.8v1.509l1.5 1.5V13.5a2.5 2.5 0 0 0-2.5-2.5H17V7a5 5 0 0 0-5-5 4.99 4.99 0 0 0-4.127 2.182L8.971 5.28C9.574 4.222 10.698 3.5 12 3.5z" />
+
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_24.xml
new file mode 100644
index 0000000000..e244e12aca
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 7.017a2.5 2.5 0 0 1 2.5-2.5h9.75a2.5 2.5 0 0 1 2.5 2.5v0.255l0.982-0.983C19.308 4.714 22 5.83 22 8.057v7.887c0 2.228-2.692 3.343-4.268 1.768L16.75 16.73v0.253a2.5 2.5 0 0 1-2.5 2.5H4.5a2.5 2.5 0 0 1-2.5-2.5V7.017zm2.5-0.75a0.75 0.75 0 0 0-0.75 0.75v9.966c0 0.414 0.336 0.75 0.75 0.75h9.75a0.75 0.75 0 0 0 0.75-0.75v-2.366a0.875 0.875 0 0 1 1.494-0.619l2.476 2.476a0.75 0.75 0 0 0 1.28-0.53V8.057a0.75 0.75 0 0 0-1.28-0.53l-2.476 2.476A0.875 0.875 0 0 1 15 9.384V7.017a0.75 0.75 0 0 0-0.75-0.75H4.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_slash_24.xml
new file mode 100644
index 0000000000..fb59ea92ff
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_camera_slash_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M1.238 1.99L20 20.752l-1.238 1.238-2.66-2.66a2.443 2.443 0 0 1-0.852 0.153H5.5a2.502 2.502 0 0 1-2.5-2.5V7.018c0-0.24 0.035-0.472 0.1-0.69L0 3.228 1.238 1.99zM4.75 7.977v9.006c0 0.413 0.337 0.75 0.75 0.75h9.005L4.75 7.977z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M21.457 5.747a2.463 2.463 0 0 0-2.726 0.542L17.75 7.271V7.018c0-1.38-1.121-2.5-2.5-2.5H5.876l1.749 1.75h7.625c0.413 0 0.75 0.337 0.75 0.75v2.366a0.876 0.876 0 0 0 1.494 0.619l2.475-2.476a0.738 0.738 0 0 1 0.818-0.162 0.736 0.736 0 0 1 0.463 0.692v7.887a0.734 0.734 0 0 1-0.463 0.692 0.74 0.74 0 0 1-0.817-0.161l-2.476-2.477A0.875 0.875 0 0 0 16 14.616v0.362l2.737 2.737c0.729 0.726 1.772 0.93 2.72 0.538A2.461 2.461 0 0 0 23 15.943V8.057a2.461 2.461 0 0 0-1.543-2.31z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cart.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cart.xml
new file mode 100644
index 0000000000..c29759e94d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cart.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M26.9,21.4H9.4c-0.7,0-1.3,0.5-1.3,1.3s0.5,1.3,1.3,1.3h17.5c0.7,0,1.3-0.5,1.3-1.3
+ C28.5,21.9,27.8,21.4,26.9,21.4z M13.3,30.1c1.3,0,2.7-1.2,2.7-2.7c0-1.3-1.2-2.7-2.7-2.7s-2.7,1.2-2.7,2.7
+ C10.6,29,12,30.1,13.3,30.1z M23.9,30.1c1.3,0,2.7-1.2,2.7-2.7c0-1.3-1.2-2.7-2.7-2.7c-1.5,0-2.7,1.2-2.7,2.7
+ C21.4,29,22.6,30.1,23.9,30.1z M31.5,7.4L31.5,7.4H7.6V7.2L5.7,2.5C5.4,2.2,5.1,1.9,4.6,1.9H0.7C0,1.9,0,2.5,0,2.9
+ C0,3.5-0.2,4,0.7,4.2h2.7l0.7,1.5l4,13.3c0,0.2,0.2,0.5,0.8,0.5h18.5c0.3,0,0.7-0.2,0.7-0.5L32,8.3C32,8.1,31.8,7.4,31.5,7.4z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_checkmark_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_checkmark_24.xml
new file mode 100644
index 0000000000..e3e97451ef
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_checkmark_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M22 6.37L10.384 17.987a0.875 0.875 0 0 1-1.238 0L2.001 10.84l1.237-1.237 6.527 6.527L20.762 5.133 22 6.37z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_20.xml
new file mode 100644
index 0000000000..f362622f33
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_20.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10 12.19L5.06 7.25 4 8.31l5.47 5.47a0.75 0.75 0 0 0 1.06 0L16 8.31l-1.061-1.06L10 12.19z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_24.xml
new file mode 100644
index 0000000000..995c2045df
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 14.887l6.263-6.263 1.238 1.238-6.882 6.882a0.875 0.875 0 0 1-1.238 0l-6.88-6.882 1.237-1.238L12 14.887z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_8.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_8.xml
new file mode 100644
index 0000000000..9ce948fafe
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_down_8.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="8dp"
+ android:height="8dp"
+ android:viewportWidth="8"
+ android:viewportHeight="8">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4 4.293l2.647-2.647 0.707 0.708-3 3a0.5 0.5 0 0 1-0.708 0l-3-3 0.708-0.707L4 4.293z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_left_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_left_24.xml
new file mode 100644
index 0000000000..2bf58b14ee
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_left_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.256 11.987l6.882-6.88 1.238 1.237-6.264 6.262 6.264 6.263-1.238 1.238-6.882-6.882a0.875 0.875 0 0 1 0-1.238z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_right_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_right_24.xml
new file mode 100644
index 0000000000..038db30bf7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_right_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M14.887 11.606L8.624 5.344l1.238-1.238 6.882 6.881a0.875 0.875 0 0 1 0 1.238l-6.882 6.882-1.238-1.238 6.263-6.263z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_20.xml
new file mode 100644
index 0000000000..e313fba3c1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_20.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10 7a0.75 0.75 0 0 1 0.53 0.22L16 12.69l-1.061 1.06L10 8.81l-4.94 4.94L4 12.69l5.47-5.47A0.75 0.75 0 0 1 10 7z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_24.xml
new file mode 100644
index 0000000000..b50e8547aa
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chevron_up_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.381 7.247a0.875 0.875 0 0 1 1.238 0l6.882 6.881-1.238 1.238L12 9.103l-6.262 6.263L4.5 14.128l6.881-6.88z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chill.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chill.xml
new file mode 100644
index 0000000000..36017ece6b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_chill.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.1,18.5l-5.7,5.9C3.2,23.8,3,23.3,3,22.6c0-2.5,2-4.4,4.4-4.4C7.8,18.1,8.5,18.3,9.1,18.5 M26.5,18.5l-5.7,5.9
+ c-0.2-0.5-0.4-1.1-0.4-1.8c0-2.5,2-4.4,4.4-4.4C25.4,18.1,26,18.3,26.5,18.5 M24.7,2L24.7,2c-0.7,0-1.4,0.7-1.4,1.4s0.7,1.4,1.4,1.4
+ c2.5,0,4.4,2,4.4,4.4v7.6c-1.6-1.2-3.6-1.8-5.5-1.4c-2.1,0.4-3.9,1.6-5,3.4c-1.6-1.2-3.9-1.2-5.5,0c-1.1-1.8-2.8-3-5-3.4
+ c-2-0.4-3.9,0.2-5.5,1.4V9.2c0-2.5,2-4.4,4.4-4.4c0.5,0,0.9-0.4,1.2-0.7c0.2-0.4,0.2-0.9,0-1.4C8.2,2.3,7.6,2,7.1,2
+ C3.2,2,0,5.2,0,9.2v13.5C0,26.7,3.2,30,7.1,30l0,0c3.9,0,7.1-3.2,7.1-7.3c0-0.2,0-0.4,0-0.5c0.2-0.9,0.9-1.4,1.8-1.4
+ s1.6,0.5,1.8,1.4v0.2c0,0.2,0,0.2,0,0.4c0,2,0.7,3.7,2.1,5c1.4,1.4,3,2.1,5,2.1l0,0c2,0,3.6-0.7,5-2.1c1.4-1.2,2.1-3.2,2.1-5V9.2
+ C32,5.2,28.8,2,24.7,2" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_circle.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_circle.xml
new file mode 100644
index 0000000000..e3f75f3aff
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_circle.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="@color/mozac_ui_icons_fill" />
+ <size android:height="24dp" android:width="24dp" />
+</shape>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_clipboard_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_clipboard_24.xml
new file mode 100644
index 0000000000..f8207ab859
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_clipboard_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.75 10.25h6.5V12h-6.5v-1.75zm0 4h3.972V16H8.75v-1.75z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M17 3h-1.535A3.999 3.999 0 0 0 12 1c-1.48 0-2.773 0.804-3.465 2H7a2.5 2.5 0 0 0-2.5 2.5v14A2.5 2.5 0 0 0 7 22h10a2.5 2.5 0 0 0 2.5-2.5v-14A2.5 2.5 0 0 0 17 3zM9.5 8A1.5 1.5 0 0 1 8 6.5V5c0-0.084 0.003-0.167 0.008-0.25H7A0.75 0.75 0 0 0 6.25 5.5v14c0 0.414 0.336 0.75 0.75 0.75h10a0.75 0.75 0 0 0 0.75-0.75v-14A0.75 0.75 0 0 0 17 4.75h-1.008C15.997 4.833 16 4.916 16 5v1.5A1.5 1.5 0 0 1 14.5 8h-5zM11 5.5v-2h2v2h-2z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_collection_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_collection_24.xml
new file mode 100644
index 0000000000..c71981eae3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_collection_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M16.75 13.5h-9.5v-1.75h9.5v1.75zm-9.5 4h9.5v-1.75h-9.5v1.75z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M8.057 2C7.17 2 6.347 2.47 5.9 3.237l-2.53 4.32A0.875 0.875 0 0 0 3.25 8v11.5a2.5 2.5 0 0 0 2.5 2.5h12.5a2.5 2.5 0 0 0 2.5-2.5V8a0.876 0.876 0 0 0-0.12-0.442L18.1 3.236A2.502 2.502 0 0 0 15.944 2H8.057zM7.41 4.12a0.749 0.749 0 0 1 0.647-0.37h7.886c0.266 0 0.513 0.142 0.648 0.372l1.831 3.128H5.578L7.41 4.12zM5 9v10.5c0 0.414 0.336 0.75 0.75 0.75h12.5A0.75 0.75 0 0 0 19 19.5V9H5z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_competitiveness_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_competitiveness_24.xml
new file mode 100644
index 0000000000..8de4dda69f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_competitiveness_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M5.793 3.875C5.793 3.392 6.185 3 6.668 3h10.664c0.483 0 0.875 0.392 0.875 0.875v2.123h2.918C21.608 5.998 22 6.39 22 6.873v3.146c0 2.53-2.022 4.59-4.539 4.65a6.211 6.211 0 0 1-4.586 3.193v2.388h4.143V22H6.982v-1.75h4.143v-2.388a6.211 6.211 0 0 1-4.586-3.193A4.652 4.652 0 0 1 2 10.019V6.873C2 6.39 2.392 5.998 2.875 5.998h2.918V3.875zm12.316 8.944a2.903 2.903 0 0 0 2.141-2.8V7.748h-2.043v3.968c0 0.377-0.034 0.745-0.098 1.103zM5.793 11.716c0 0.377 0.034 0.745 0.098 1.103a2.903 2.903 0 0 1-2.141-2.8V7.748h2.043v3.968zm1.75-6.966v6.966a4.457 4.457 0 1 0 8.914 0V4.75H7.543z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_24.xml
new file mode 100644
index 0000000000..3955146580
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M21.976 11.488A8.767 8.767 0 0 1 20 11.828V13h-2.5v-1.347c-3.905-0.877-6.833-4.366-6.833-8.532 0-0.365 0.03-0.724 0.073-1.077C5.82 2.667 2 6.87 2 11.956c0 5.514 4.486 10 10 10s10-4.486 10-10c0-0.158-0.016-0.312-0.024-0.468zM6.5 13H4v-2.5h2.5V13zm3.5 5.5H7.5V16H10v2.5zM10 8H7.5V5.5H10V8zm3.5 5H11v-2.5h2.5V13zm3.5 5.5h-2.5V16H17v2.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_slash_24.xml
new file mode 100644
index 0000000000..9b9adcdcf5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cookies_slash_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5.379 4.487L7.5 6.609V5.5H10V8H8.891l10.58 10.58A9.95 9.95 0 0 0 22 11.956c0-0.105-0.007-0.209-0.014-0.313l-0.01-0.155A8.767 8.767 0 0 1 20 11.828V13h-2.5v-1.347c-3.905-0.877-6.833-4.366-6.833-8.532 0-0.365 0.03-0.724 0.073-1.077a9.971 9.971 0 0 0-5.361 2.443z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3.304 7.041A9.883 9.883 0 0 0 2 11.956c0 5.514 4.486 10 10 10a9.929 9.929 0 0 0 4.92-1.299L19.262 23l1.238-1.238-2.117-2.117 0.018-0.015L4.333 5.562A8.69 8.69 0 0 0 4.318 5.58L1.738 3 0.5 4.238 3.304 7.04zM6.5 13H4v-2.5h2.5V13zm3.5 5.5H7.5V16H10v2.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_copy_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_copy_24.xml
new file mode 100644
index 0000000000..7fb92271da
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_copy_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.25 3a2.5 2.5 0 0 0-2.5 2.5H8.5a0.75 0.75 0 0 1 0.75-0.75h8A0.75 0.75 0 0 1 18 5.5v10a0.75 0.75 0 0 1-0.75 0.75V18a2.5 2.5 0 0 0 2.5-2.5v-10a2.5 2.5 0 0 0-2.5-2.5h-8z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5.25 7a2.5 2.5 0 0 0-2.5 2.5v10a2.5 2.5 0 0 0 2.5 2.5h8a2.5 2.5 0 0 0 2.5-2.5v-10a2.5 2.5 0 0 0-2.5-2.5h-8zM4.5 9.5a0.75 0.75 0 0 1 0.75-0.75h8A0.75 0.75 0 0 1 14 9.5v10a0.75 0.75 0 0 1-0.75 0.75h-8A0.75 0.75 0 0 1 4.5 19.5v-10z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_credit_card_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_credit_card_24.xml
new file mode 100644
index 0000000000..69721f0c35
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_credit_card_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9 13.125H6v1.75h3v-1.75z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M2 6.5A2.5 2.5 0 0 1 4.5 4h15A2.5 2.5 0 0 1 22 6.5v10a2.5 2.5 0 0 1-2.5 2.5h-15A2.5 2.5 0 0 1 2 16.5v-10zm2.5-0.75A0.75 0.75 0 0 0 3.75 6.5v1.75h16.5V6.5a0.75 0.75 0 0 0-0.75-0.75h-15zM3.75 16.5V10h16.5v6.5a0.75 0.75 0 0 1-0.75 0.75h-15a0.75 0.75 0 0 1-0.75-0.75z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_24.xml
new file mode 100644
index 0000000000..364f898f93
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.125 17v-1.75h1.75V17h-1.75zm0-10v6.5h1.75V7h-1.75z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12zm10-8.25a8.25 8.25 0 1 0 0 16.5 8.25 8.25 0 0 0 0-16.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_fill_24.xml
new file mode 100644
index 0000000000..e81b1bd08a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_critical_fill_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M12 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10zm-0.875-5v-1.75h1.75V17h-1.75zm0-10v6.25h1.75V7h-1.75z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_20.xml
new file mode 100644
index 0000000000..07a4a4f9cb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_20.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.06 10L16 5.06 14.938 4l-4.94 4.94L5.06 4 4 5.062l4.939 4.94L4 14.938l1.06 1.06L10 11.061l4.939 4.938 1.06-1.06L11.06 10z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_24.xml
new file mode 100644
index 0000000000..6af42311d3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 10.753L5.238 3.99 4 5.228l6.762 6.762L4 18.752l1.238 1.238L12 13.227l6.762 6.763L20 18.752l-6.763-6.762L20 5.228 18.762 3.99 12 10.753z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_24.xml
new file mode 100644
index 0000000000..98e4a06d50
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 10.763L9.238 8 8 9.238 10.762 12 8 14.762 9.238 16 12 13.237 14.762 16 16 14.762 13.237 12 16 9.238 14.762 8 12 10.763z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 3.75a8.25 8.25 0 1 0 0 16.5 8.25 8.25 0 0 0 0-16.5zM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_20.xml
new file mode 100644
index 0000000000..937bd3d312
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_20.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M18,10a8,8 0,1 1,-16 0,8 8,0 0,1 16,0zM6.5,12.439 L8.94,10l-2.44,-2.439 1.061,-1.06L10,8.939l2.439,-2.44 1.06,1.061L11.06,10l2.44,2.439 -1.061,1.06 -2.44,-2.438 -2.438,2.438 -1.06,-1.06z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_24.xml
new file mode 100644
index 0000000000..b7255c0764
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cross_circle_fill_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 12c0 5.514 4.486 10 10 10s10-4.486 10-10S17.514 2 12 2 2 6.486 2 12zm7.238-4L12 10.763 14.762 8 16 9.238 13.237 12 16 14.762 14.762 16 12 13.237 9.238 16 8 14.762 10.762 12 8 9.238 9.238 8z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cryptominer_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cryptominer_24.xml
new file mode 100644
index 0000000000..aa6e3d7453
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_cryptominer_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13 4.5V2h-1.75v2.5H7.604c-0.401 0-0.784 0.16-1.065 0.444L4.935 6.562C4.656 6.843 4.5 7.222 4.5 7.618V9.25a1.5 1.5 0 0 0 1.5 1.5h5.25V22H13V10.75h5a1.5 1.5 0 0 0 1.5-1.5V6A1.5 1.5 0 0 0 18 4.5h-5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_data_clearance_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_data_clearance_24.xml
new file mode 100644
index 0000000000..a6c54e16b8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_data_clearance_24.xml
@@ -0,0 +1,14 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6.63 19.94c1.39 1.37 3.23 2.05 5.06 2.05l-0.01-0.01c1.84 0 3.68-0.68 5.08-2.05 1.75-1.76 2.71-4.12 2.71-6.67 0-1.73-0.48-3.42-1.39-4.9a0.873 0.873 0 0 0-0.74-0.42c-0.3 0-0.58 0.16-0.74 0.42a7.56 7.56 0 0 1-1.24 1.53c-0.43-3.58-2.92-6.65-6.46-7.85a0.864 0.864 0 0 0-0.89 0.2C7.78 2.47 7.69 2.82 7.79 3.13c0.78 2.5 0.2 5.24-1.5 7.23L6.2 10.45c-0.03 0.04-0.09 0.11-0.09 0.11l-0.05 0.06a0.265 0.265 0 0 0-0.025 0.03 0.22 0.22 0 0 1-0.025 0.03c-2.17 2.76-1.93 6.77 0.62 9.26zm1.22-1.25c-1.94-1.89-2.12-4.85-0.45-6.95v-0.02a9.416 9.416 0 0 0 2.42-7.36c2.36 1.38 3.86 3.89 3.86 6.64 0 0.19-0.01 0.38-0.02 0.57-0.02 0.33 0.14 0.64 0.42 0.81 0.28 0.18 0.63 0.17 0.91 0 0.83-0.52 1.58-1.16 2.21-1.9 0.35 0.88 0.53 1.82 0.53 2.78 0 2.08-0.78 4.01-2.19 5.43a5.413 5.413 0 0 1-1.298 0.937A4.92 4.92 0 0 0 14.5 18.07c0-1.78-0.87-3.37-2.24-4.01a0.593 0.593 0 0 0-0.52 0c-1.37 0.64-2.24 2.23-2.24 4.01 0 0.665 0.134 1.294 0.362 1.864A5.424 5.424 0 0 1 7.85 18.69z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_debug_drawer_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_debug_drawer_24.xml
new file mode 100644
index 0000000000..cf9df6537b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_debug_drawer_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M15.484,2 L14.11,4.382A5.973,5.973 0,0 0,12 4c-0.742,0 -1.453,0.135 -2.109,0.383L8.516,2 7,2.876l1.36,2.356a6.017,6.017 0,0 0,-2.144 3.169L4.75,7.508V4H3v4c0,0.306 0.16,0.589 0.42,0.748L6,10.318v5.364l-2.58,1.57A0.875,0.875 0,0 0,3 18v4h1.75v-3.508l1.466,-0.893A6.01,6.01 0,0 0,12 22a6.01,6.01 0,0 0,5.784 -4.4l1.466,0.892V22H21v-4a0.875,0.875 0,0 0,-0.42 -0.747L18,15.683v-5.365l2.58,-1.57A0.875,0.875 0,0 0,21 8V4h-1.75v3.508l-1.466,0.893a6.017,6.017 0,0 0,-2.145 -3.169l1.36,-2.357L15.485,2z" />
+ <path
+ android:fillColor="#fff"
+ android:pathData="M15.05,12.914c-0.16,-0.26 -0.587,-0.26 -0.748,0a3.96,3.96 0,0 1,-0.623 0.77c-0.218,-1.797 -1.467,-3.341 -3.244,-3.942a0.44,0.44 0,0 0,-0.56 0.546,3.831 3.831,0 0,1 -0.753,3.628c-0.015,0.014 -0.03,0.028 -0.044,0.044l-0.046,0.054 -0.027,0.032 -0.024,0.03a3.477,3.477 0,0 0,-0.732 1.926A3.75,3.75 0,0 0,15.75 16v-0.624c0,-0.87 -0.242,-1.722 -0.7,-2.462z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_delete_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_delete_24.xml
new file mode 100644
index 0000000000..295ed43ac7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_delete_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.75 10v8H9v-8h1.75zM15 10v8h-1.75v-8H15z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M10.5 2A2.5 2.5 0 0 0 8 4.5V6H3.25v1.75H4.5V19.5A2.5 2.5 0 0 0 7 22h10a2.5 2.5 0 0 0 2.5-2.5V7.75h1.25V6H16V4.5A2.5 2.5 0 0 0 13.5 2h-3zm3.75 4V4.5a0.75 0.75 0 0 0-0.75-0.75h-3A0.75 0.75 0 0 0 9.75 4.5V6h4.5zm3.5 1.75H6.25V19.5c0 0.414 0.336 0.75 0.75 0.75h10a0.75 0.75 0 0 0 0.75-0.75V7.75z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_24.xml
new file mode 100644
index 0000000000..a0d1de4e7c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.5 4A2.5 2.5 0 0 0 2 6.5v10A2.5 2.5 0 0 0 4.5 19H1v1.75h22V19h-3.5a2.5 2.5 0 0 0 2.5-2.5v-10A2.5 2.5 0 0 0 19.5 4h-15zM3.75 6.5A0.75 0.75 0 0 1 4.5 5.75h15a0.75 0.75 0 0 1 0.75 0.75v10a0.75 0.75 0 0 1-0.75 0.75h-15a0.75 0.75 0 0 1-0.75-0.75v-10z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_send_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_send_24.xml
new file mode 100644
index 0000000000..3668554e2a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_desktop_send_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.5 4A2.5 2.5 0 0 0 2 6.5v3h1.75v-3A0.75 0.75 0 0 1 4.5 5.75h15a0.75 0.75 0 0 1 0.75 0.75v10a0.75 0.75 0 0 1-0.75 0.75h-15a0.75 0.75 0 0 1-0.75-0.75v-2H2v2A2.5 2.5 0 0 0 4.5 19H1v1.75h22V19h-3.5a2.5 2.5 0 0 0 2.5-2.5v-10A2.5 2.5 0 0 0 19.5 4h-15z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.28 14.996A0.75 0.75 0 0 1 8 14.466V12.75H1v-1.5h7V9.534a0.75 0.75 0 0 1 1.28-0.53l2.466 2.465a0.75 0.75 0 0 1 0 1.061L9.28 14.996z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_mobile_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_mobile_24.xml
new file mode 100644
index 0000000000..30b9f1eac2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_device_mobile_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M7.5,2A2.5,2.5 0,0 0,5 4.5v15A2.5,2.5 0,0 0,7.5 22h9a2.5,2.5 0,0 0,2.5 -2.5v-15A2.5,2.5 0,0 0,16.5 2h-9zM6.75,4.5a0.75,0.75 0,0 1,0.75 -0.75h9a0.75,0.75 0,0 1,0.75 0.75L17.25,17L6.75,17L6.75,4.5zM10,20.25h4v-1.5h-4v1.5z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dollar.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dollar.xml
new file mode 100644
index 0000000000..b0ddfbf563
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dollar.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M16.2,0c-8.9,0-16,7.3-16,16c0,8.9,7.1,16,15.8,16s15.8-7.1,15.8-16C32,7.3,24.9,0,16.2,0z M17.1,25.1v1.6
+ c0,0.4-0.4,0.5-0.7,0.5c-0.4,0-0.7-0.2-0.7-0.5v-1.6c-3.2-0.2-5-1.8-5.5-4.3c0-0.2,0-0.2,0-0.4c0-0.5,0.4-0.9,0.9-0.9
+ c0.2,0,0.2,0,0.4,0c0.5,0,0.9,0.2,1.1,0.7c0.4,1.8,1.2,2.7,3.4,2.8v-6.8c-3.6-0.4-5.3-1.8-5.3-4.6c0-3,2.5-4.6,5.2-4.8V5.7
+ c0-0.4,0.4-0.5,0.7-0.5c0.4,0,0.7,0.2,0.7,0.5v1.1c2.7,0.4,4.4,1.8,5,3.9c0,0.2,0,0.2,0,0.4c0,0.5-0.4,0.7-0.7,0.9
+ c-0.2,0-0.2,0-0.4,0c-0.4,0-0.7-0.2-0.9-0.7c-0.4-1.4-1.2-2.3-3-2.5v6c3.2,0.7,5.5,1.8,5.5,5.2C22.8,23.5,20.1,25.1,17.1,25.1z
+ M12.4,11.6c0,1.6,0.7,2.5,3.2,3V8.7C13.7,8.9,12.4,10,12.4,11.6z M17.1,16.9v6.4c2.3-0.2,3.6-1.2,3.6-3.2
+ C20.6,17.8,19.2,17.2,17.1,16.9z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_download_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_download_24.xml
new file mode 100644
index 0000000000..c79a08a8ba
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_download_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.875 15.012V3h-1.75v12.013l-3.888-3.888L6 12.362l5.381 5.382a0.875 0.875 0 0 0 1.238 0l5.38-5.382-1.237-1.237-3.887 3.887z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5 17v2.5c0 0.414 0.336 0.75 0.75 0.75h12.5A0.75 0.75 0 0 0 19 19.5V17h1.75v2.5a2.5 2.5 0 0 1-2.5 2.5H5.75a2.5 2.5 0 0 1-2.5-2.5V17H5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dropdown_arrow.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dropdown_arrow.xml
new file mode 100644
index 0000000000..11e35191b8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_dropdown_arrow.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7 10L12 15L17 10H7Z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_edit_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_edit_24.xml
new file mode 100644
index 0000000000..4cc97d5cf7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_edit_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M5.277 2.732a2.5 2.5 0 0 1 3.536 0l12.93 12.931A0.875 0.875 0 0 1 22 16.282v4.843A0.875 0.875 0 0 1 21.125 22h-4.843a0.875 0.875 0 0 1-0.619-0.256L2.733 8.813a2.5 2.5 0 0 1 0-3.536l2.544-2.545zM6.515 3.97a0.75 0.75 0 0 1 1.06 0l1.768 1.767-3.606 3.606L3.97 7.575a0.75 0.75 0 0 1 0-1.06L6.515 3.97zm0.46 6.61l9.67 9.67h3.605v-3.606l-9.67-9.67-3.605 3.607z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_horizontal_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_horizontal_24.xml
new file mode 100644
index 0000000000..a75ad8f3e2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_horizontal_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6.5 11.75H4v2.5h2.5v-2.5zm6.75 0h-2.5v2.5h2.5v-2.5zm6.75 0h-2.5v2.5H20v-2.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_vertical_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_vertical_24.xml
new file mode 100644
index 0000000000..e5d6a89b19
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_ellipsis_vertical_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11 17.5V20h2.5v-2.5H11zm0-6.75v2.5h2.5v-2.5H11zM11 4v2.5h2.5V4H11z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_experiments_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_experiments_24.xml
new file mode 100644
index 0000000000..949626f212
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_experiments_24.xml
@@ -0,0 +1,28 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M16.75 6a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 9.125a2.875 2.875 0 1 0 0 5.75 2.875 2.875 0 0 0 0-5.75zM10.875 12a1.125 1.125 0 1 1 2.25 0 1.125 1.125 0 0 1-2.25 0z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6 16.75a1.25 1.25 0 1 0 2.5 0 1.25 1.25 0 0 0-2.5 0z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M21.035 9.616A14.057 14.057 0 0 1 19.988 12c0.436 0.799 0.793 1.599 1.049 2.384 0.815 2.52 0.55 4.62-0.74 5.912-0.8 0.8-1.908 1.205-3.234 1.205-0.817 0-1.717-0.155-2.678-0.465A14.057 14.057 0 0 1 12 19.989c-0.8 0.436-1.6 0.793-2.384 1.047-0.961 0.311-1.861 0.465-2.678 0.465-1.326 0-2.434-0.406-3.234-1.205-1.292-1.293-1.555-3.393-0.74-5.912 0.254-0.785 0.61-1.585 1.047-2.384a14.057 14.057 0 0 1-1.047-2.384c-0.815-2.519-0.552-4.619 0.74-5.911 1.292-1.293 3.39-1.555 5.91-0.74 0.786 0.254 1.586 0.611 2.385 1.047a14.09 14.09 0 0 1 2.383-1.048c2.52-0.814 4.618-0.552 5.912 0.74 1.292 1.293 1.555 3.392 0.74 5.912zM6.953 4.253c-0.86 0-1.554 0.231-2.011 0.689-0.792 0.792-0.906 2.3-0.314 4.136 0.126 0.389 0.288 0.785 0.468 1.183a21.376 21.376 0 0 1 5.164-5.164c-0.397-0.18-0.793-0.342-1.183-0.468-0.776-0.251-1.494-0.376-2.124-0.376zm7.97 15.118c1.834 0.594 3.342 0.481 4.135-0.313 0.792-0.792 0.906-2.3 0.314-4.136a11.508 11.508 0 0 0-0.468-1.183 21.31 21.31 0 0 1-2.36 2.803l-0.001 0.001a21.375 21.375 0 0 1-2.803 2.36c0.397 0.18 0.793 0.342 1.183 0.468zm3.98-9.111c0.18-0.397 0.342-0.793 0.468-1.183 0.593-1.835 0.479-3.343-0.314-4.136-0.457-0.458-1.152-0.689-2.011-0.689-0.63 0-1.347 0.125-2.124 0.376-0.39 0.126-0.785 0.288-1.183 0.468 0.264 0.186 0.524 0.393 0.784 0.6l0.167 0.132a2.487 2.487 0 0 0-0.395 1.929A18.529 18.529 0 0 0 12 6.036a19.128 19.128 0 0 0-3.306 2.658A19.128 19.128 0 0 0 6.036 12a18.606 18.606 0 0 0 1.73 2.305 2.483 2.483 0 0 0-1.933 0.39 78.202 78.202 0 0 0-0.116-0.146 16.845 16.845 0 0 1-0.62-0.809c-0.18 0.397-0.342 0.793-0.468 1.183-0.594 1.835-0.48 3.343 0.313 4.135 0.792 0.793 2.298 0.907 4.135 0.313 0.389-0.126 0.785-0.288 1.183-0.468-0.268-0.19-0.532-0.4-0.796-0.61l-0.16-0.126a2.48 2.48 0 0 0 0.392-1.933c0.75 0.654 1.524 1.238 2.305 1.729a19.068 19.068 0 0 0 3.305-2.657v-0.001A19.125 19.125 0 0 0 17.965 12a18.55 18.55 0 0 0-1.727-2.302 2.482 2.482 0 0 0 1.928-0.397c0.04 0.051 0.08 0.102 0.122 0.153 0.212 0.267 0.425 0.534 0.616 0.806z"
+ tools:ignore="VectorPath,VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_24.xml
new file mode 100644
index 0000000000..67a37d7624
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.5 3.75a1.75 1.75 0 0 0-1.75 1.75v2.375A0.875 0.875 0 0 1 9.875 8.75H6.5A0.75 0.75 0 0 0 5.75 9.5V11h1.5a3.5 3.5 0 1 1 0 7h-1.5v1.5c0 0.414 0.336 0.75 0.75 0.75h12a0.75 0.75 0 0 0 0.75-0.75v-10a0.75 0.75 0 0 0-0.75-0.75h-3.375a0.875 0.875 0 0 1-0.875-0.875V5.5a1.75 1.75 0 0 0-1.75-1.75zM9 5.5a3.5 3.5 0 1 1 7 0V7h2.5A2.5 2.5 0 0 1 21 9.5v10a2.5 2.5 0 0 1-2.5 2.5h-12A2.5 2.5 0 0 1 4 19.5v-2.375c0-0.483 0.392-0.875 0.875-0.875H7.25a1.75 1.75 0 1 0 0-3.5H4.875A0.875 0.875 0 0 1 4 11.875V9.5A2.5 2.5 0 0 1 6.5 7H9V5.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_cog_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_cog_24.xml
new file mode 100644
index 0000000000..596a85a3e4
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_cog_24.xml
@@ -0,0 +1,17 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3.5,19.25h7.986a2.424,2.424 0,0 0,0.176 1.75H3.5A2.503,2.503 0,0 1,1 18.5v-2.375c0,-0.483 0.392,-0.875 0.875,-0.875H4.25c0.965,0 1.75,-0.785 1.75,-1.75s-0.785,-1.75 -1.75,-1.75H1.875A0.875,0.875 0,0 1,1 10.875V8.5C1,7.122 2.121,6 3.5,6H6V4.5C6,2.57 7.57,1 9.5,1S13,2.57 13,4.5V6h2.5C16.879,6 18,7.122 18,8.5V11h-0.439c-0.478,0 -0.928,0.149 -1.311,0.398V8.5a0.75,0.75 0,0 0,-0.75 -0.75h-3.375a0.875,0.875 0,0 1,-0.875 -0.875V4.5c0,-0.965 -0.785,-1.75 -1.75,-1.75s-1.75,0.785 -1.75,1.75v2.375a0.875,0.875 0,0 1,-0.875 0.875H3.5a0.75,0.75 0,0 0,-0.75 0.75V10h1.5c1.93,0 3.5,1.57 3.5,3.5S6.18,17 4.25,17h-1.5v1.5c0,0.414 0.337,0.75 0.75,0.75z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="m22.022,18.397 l0.835,0.881a0.92,0.92 0,0 1,0.129 1.089l-0.441,0.764a0.924,0.924 0,0 1,-1.015 0.431l-1.155,-0.288a4.037,4.037 0,0 1,-0.714 0.43l-0.338,1.14a0.923,0.923 0,0 1,-0.879 0.656h-0.883a0.92,0.92 0,0 1,-0.881 -0.664l-0.324,-1.127a4.005,4.005 0,0 1,-0.73 -0.435l-1.154,0.288a0.92,0.92 0,0 1,-1.015 -0.431l-0.441,-0.764a0.921,0.921 0,0 1,0.129 -1.09l0.834,-0.879 -0.004,-0.03a2.62,2.62 0,0 1,-0.033 -0.367c0,-0.136 0.018,-0.267 0.036,-0.398l0.003,-0.019 -0.829,-0.858a0.92,0.92 0,0 1,-0.135 -1.095l0.442,-0.764a0.923,0.923 0,0 1,1.007 -0.433l1.174,0.282c0.244,-0.178 0.48,-0.318 0.716,-0.424l0.324,-1.127a0.921,0.921 0,0 1,0.881 -0.664h0.883c0.403,0 0.764,0.27 0.879,0.656l0.338,1.14c0.227,0.104 0.453,0.238 0.699,0.418l1.174,-0.282a0.923,0.923 0,0 1,1.008 0.433l0.441,0.764a0.922,0.922 0,0 1,-0.134 1.095l-0.829,0.858 0.003,0.019a2.9,2.9 0,0 1,0.036 0.398c0,0.118 -0.015,0.233 -0.03,0.347l-0.007,0.05zM16.5,18a1.5,1.5 0,1 0,3.001 -0.001A1.5,1.5 0,0 0,16.5 18z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_fill_24.xml
new file mode 100644
index 0000000000..52b50249fa
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_extension_fill_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M18.5 22h-12A2.5 2.5 0 0 1 4 19.5v-2.125C4 16.892 4.392 16.5 4.875 16.5H7A2.25 2.25 0 1 0 7 12H4.875A0.875 0.875 0 0 1 4 11.125V9.5A2.5 2.5 0 0 1 6.5 7H10V4.875a2.875 2.875 0 1 1 5.75 0V7h2.75A2.5 2.5 0 0 1 21 9.5v10a2.5 2.5 0 0 1-2.5 2.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_external_link_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_external_link_24.xml
new file mode 100644
index 0000000000..79e00bceb8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_external_link_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5.5,4A2.5,2.5 0,0 0,3 6.5v12A2.5,2.5 0,0 0,5.5 21h12a2.5,2.5 0,0 0,2.5 -2.5V12h-1.75v6.5a0.75,0.75 0,0 1,-0.75 0.75h-12a0.75,0.75 0,0 1,-0.75 -0.75v-12a0.75,0.75 0,0 1,0.75 -0.75H12V4H5.5z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M14.788,4h4.462a0.75,0.75 0,0 1,0.75 0.75v4.541a0.75,0.75 0,0 1,-1.285 0.526l-1.633,-1.662L12.238,13 11,11.762l4.856,-4.855 -1.603,-1.631A0.75,0.75 0,0 1,14.788 4z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_24.xml
new file mode 100644
index 0000000000..9cba339370
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 9a3.375 3.375 0 1 0 0 6.75A3.375 3.375 0 0 0 12 9zm-1.625 3.375a1.625 1.625 0 1 1 3.25 0 1.625 1.625 0 0 1-3.25 0z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 5.269c-4.497 0-8.3 2.837-9.8 6.796a0.875 0.875 0 0 0 0 0.62c1.5 3.96 5.303 6.796 9.8 6.796 4.497 0 8.3-2.837 9.8-6.796a0.874 0.874 0 0 0 0-0.62C20.3 8.105 16.497 5.27 12 5.27zm0 12.462c-3.62 0-6.71-2.21-8.04-5.356C5.29 9.228 8.38 7.019 12 7.019c3.62 0 6.71 2.21 8.04 5.356-1.33 3.147-4.42 5.356-8.04 5.356z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_slash_24.xml
new file mode 100644
index 0000000000..2d0c82ea6c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_eye_slash_24.xml
@@ -0,0 +1,24 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M8.227 5.99l-3.74-3.74L3.25 3.488 6.573 6.81A10.552 10.552 0 0 0 2.2 12.065a0.885 0.885 0 0 0 0 0.621c1.54 4.064 5.479 6.795 9.8 6.795a10.4 10.4 0 0 0 5.595-1.648l2.917 2.917 1.238-1.238-2.75-2.75 0.004-0.003-1.221-1.22-0.004 0.003-2.475-2.476 0.001-0.006-3.99-3.99-0.006 0.001-1.71-1.71h0.006L8.232 5.986 8.227 5.988zm4.988 7.463l-2.293-2.293a1.622 1.622 0 0 0-0.547 1.215 1.623 1.623 0 0 0 2.84 1.078zm-4.59-1.078a3.36 3.36 0 0 1 1.06-2.453L7.838 8.077a8.7 8.7 0 0 0-3.88 4.298C5.337 15.64 8.457 17.731 12 17.731c1.57 0 3.054-0.411 4.342-1.152l-1.889-1.888A3.365 3.365 0 0 1 12 15.75a3.379 3.379 0 0 1-3.375-3.375z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.427 7.061a6.95 6.95 0 0 0 0.203-0.018c0.122-0.012 0.245-0.024 0.37-0.024 3.544 0 6.664 2.091 8.04 5.356a8.909 8.909 0 0 1-1.233 2.066l1.236 1.236a10.466 10.466 0 0 0 1.757-2.992 0.885 0.885 0 0 0 0-0.621C20.26 8 16.321 5.269 12 5.269c-0.726 0-1.439 0.083-2.134 0.231l1.561 1.561z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M14.526 10.16a3.381 3.381 0 0 0-0.311-0.311l0.311 0.311z"
+ tools:ignore="VectorRaster" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fence.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fence.xml
new file mode 100644
index 0000000000..ccd01bd3c7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fence.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M28,4l-2,2v4h-4V6l-2-2l-2,2v4h-4V6l-2-2l-2,2v4H6V6L4,4L2,6v22h4v-4h4v4h4v-4h4v4h4v-4h4v4h4V6L28,4z M6,22V12 h4v10H6z M14,22V12h4v10H14z M22,22V12h4v10H22z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fingerprinter_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fingerprinter_24.xml
new file mode 100644
index 0000000000..a1eccfd3a8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fingerprinter_24.xml
@@ -0,0 +1,18 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.439 2.284c3.823-0.958 8.078 0.618 10.116 3.76 2.536 3.902 1.498 9.15-2.925 14.773l-1.375-1.082c3.923-4.988 4.929-9.51 2.833-12.738-1.645-2.533-5.102-3.802-8.221-3.015-2.965 0.751-4.826 3.16-5.103 6.607L5.73 11H3.976l0.045-0.552c0.342-4.24 2.681-7.216 6.418-8.164z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.253 21.173l-0.891-1.506 0.753-0.445a9.99 9.99 0 0 0 0.69-0.448c4.12-2.935 4.307-8.107 4.308-8.159l0.011-0.115c0.232-1.445-0.94-2.839-2.614-3.108-0.97-0.158-1.996 0.103-2.694 0.67-0.327 0.267-0.724 0.72-0.754 1.363V11c0 2.206-1.794 4-4 4H2v-1.75h4.062c1.24 0 2.25-1.01 2.25-2.25V9.384C8.36 8.336 8.856 7.398 9.711 6.703c1.091-0.887 2.614-1.272 4.076-1.041 2.607 0.42 4.423 2.682 4.073 5.06-0.03 0.672-0.418 6.186-5.041 9.478-0.26 0.184-0.529 0.36-0.813 0.527l-0.753 0.446z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.062 10v1.625A5.38 5.38 0 0 1 6.687 17H2v1.75h4.688a7.133 7.133 0 0 0 7.125-7.125V10h-1.751z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_24.xml
new file mode 100644
index 0000000000..d63d873480
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.5 5.25A0.75 0.75 0 0 0 3.75 6v12c0 0.414 0.336 0.75 0.75 0.75h15A0.75 0.75 0 0 0 20.25 18V9a0.75 0.75 0 0 0-0.75-0.75h-6.83a0.875 0.875 0 0 1-0.62-0.258L9.543 5.471A0.748 0.748 0 0 0 9.011 5.25H4.5zM2 6a2.5 2.5 0 0 1 2.5-2.5h4.511a2.5 2.5 0 0 1 1.773 0.737l2.25 2.263H19.5A2.5 2.5 0 0 1 22 9v9a2.5 2.5 0 0 1-2.5 2.5h-15A2.5 2.5 0 0 1 2 18V6z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_add_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_add_24.xml
new file mode 100644
index 0000000000..c6938d1006
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_folder_add_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3.5 4.75A0.75 0.75 0 0 0 2.75 5.5v12c0 0.414 0.336 0.75 0.75 0.75h11V20h-11A2.5 2.5 0 0 1 1 17.5v-12A2.5 2.5 0 0 1 3.5 3h4.511a2.5 2.5 0 0 1 1.773 0.737L12.034 6H18.5A2.5 2.5 0 0 1 21 8.5v5.125h-1.75V8.5a0.75 0.75 0 0 0-0.75-0.75h-6.83a0.875 0.875 0 0 1-0.62-0.258L8.543 4.971A0.748 0.748 0 0 0 8.011 4.75H3.5z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M19.125 20H16v-1.75h3.125v-3.125h1.75v3.125H24V20h-3.125v3.125h-1.75V20z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_font.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_font.xml
new file mode 100644
index 0000000000..9e5d320ba6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_font.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M18.9,16.1c-0.5,0.4 -1,0.6 -1.5,0.8 -0.4,0.2 -0.9,0.3 -1.3,0.3 -0.6,0 -1.1,-0.2 -1.5,-0.6 -0.4,-0.4 -0.6,-0.9 -0.6,-1.6 0,-0.8 0.3,-1.3 0.9,-1.8 0.6,-0.5 1.9,-0.9 4.1,-1.3v-0.4c0,-0.6 -0.1,-1 -0.4,-1.3 -0.2,-0.3 -0.6,-0.4 -1.2,-0.4L17,9.8c-0.1,0 -0.3,0 -0.4,0.1v1.5h-1.5c-0.3,0 -0.4,0 -0.6,-0.1 -0.1,-0.1 -0.2,-0.2 -0.2,-0.5 0,-0.5 0.3,-0.9 1,-1.3s1.5,-0.6 2.5,-0.6c1.1,0 1.9,0.2 2.4,0.6 0.5,0.4 0.7,1.2 0.7,2.2L20.9,16l0.2,0.2 0.9,0.1v0.7h-2.9l-0.2,-0.9zM18.9,15.4v-2.6c-1.1,0.2 -1.8,0.5 -2.2,0.8 -0.4,0.3 -0.6,0.7 -0.6,1.1 0,0.4 0.1,0.7 0.3,0.9 0.2,0.2 0.5,0.3 0.9,0.3 0.2,0 0.4,0 0.7,-0.1 0.3,-0.1 0.6,-0.2 0.9,-0.4zM6.6,6h1.7L12,16l1,0.2v0.8L8.7,17v-0.8l1,-0.1 0.1,-0.2 -1,-2.8L5.3,13.1l-1,2.7 0.2,0.2 1,0.1v0.9L2,17v-0.8l1,-0.2L6.6,6zM7,8.2l-1.4,4h2.9L7,8.2z"
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillAlpha=".8"/>
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_food.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_food.xml
new file mode 100644
index 0000000000..d82801ad65
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_food.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M14.1,0.9v5.3h-1.4V0.9c0-1.1-1.4-1.1-1.4,0v5.3h-1.2V0.9c0-1.1-1.4-1.1-1.4,0v5.3H7.2V0.9c0-1.2-1.6-1.1-1.6,0
+ v10.4c0,1.8,1.2,3,2.8,3v15.2c0,1.6,1.1,2.5,2.1,2.5s2.1-0.9,2.1-2.5V14.3c1.6,0,2.8-1.4,2.8-2.8V0.9C15.6-0.4,14.1-0.2,14.1,0.9z
+ M19.8,3.7v25.8c0,3.2,4.2,3.2,4.2,0V17.1h2.3V3.7C26.5-1.2,19.8-1.2,19.8,3.7z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_forward_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_forward_24.xml
new file mode 100644
index 0000000000..8b66c40787
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_forward_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M17.638 13.75H3.125V12h14.513L12.25 6.613l1.238-1.238 6.88 6.881a0.875 0.875 0 0 1 0 1.238l-6.88 6.88-1.238-1.237 5.387-5.387z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fruit.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fruit.xml
new file mode 100644
index 0000000000..250b848431
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_fruit.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M16.5,8c-2.1-0.9-3.9-1.2-6.6-0.9C4.6,8,1.8,12.6,1.8,18c0,5.9,4.8,14,9.8,14c1.6,0,3.9-1.2,4.4-1.2
+ c0.5,0,2.8,1.2,4.4,1.2c5,0,9.8-8.4,9.8-14c0-5.9-3.2-10.8-9.8-10.8C19,7.1,17.8,7.5,16.5,8z M11.7,0c1.1,0.2,3.2,0.9,4.1,2.3
+ c0.9,1.4,0.5,3.6,0.2,4.6c-1.2-0.2-3.2-0.7-4.1-2.3C11,3.2,11.4,1.1,11.7,0L11.7,0z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_gift.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_gift.xml
new file mode 100644
index 0000000000..8bb994b81f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_gift.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M30.3,8.1h-4.5V8c0.7-0.7,1.3-1.9,1.3-3.2c0-2.6-2.1-4.7-4.9-4.7c-1.5,0-4.5,1.5-6.4,3.4C14,1.6,11,0.1,9.5,0.1
+ c-2.6,0-4.9,2.1-4.9,4.7C4.7,6.1,5.2,7.2,6,8H1.7C0.6,8,0,8.7,0,9.6v4.5c0,0.2,0.2,0.4,0.4,0.4h13.8V9.6h3.2v4.9h14.2
+ c0.2,0,0.4-0.2,0.4-0.4V9.6C32,8.7,31.4,8.1,30.3,8.1z M9.5,6.5C8.6,6.5,8,5.9,8,4.8s0.6-1.5,1.5-1.5s3.7,1.9,4.7,2.8
+ C13.7,6.3,9.5,6.5,9.5,6.5z M22.3,6.5c0,0-4.1-0.2-4.7-0.4c0.9-1.1,3.7-2.8,4.7-2.8S24,3.8,24,4.8S23.2,6.5,22.3,6.5z M1.7,17.7
+ h12.7v14.2H1.7V17.7z M17.6,17.7h12.7v14.2H17.6V17.7z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_globe_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_globe_24.xml
new file mode 100644
index 0000000000..2bedff87fb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_globe_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zM9.731 4.066a8.257 8.257 0 0 0-5.938 7.09h3.266a13.027 13.027 0 0 1 2.672-7.09zm-2.672 8.84h-3.26a8.258 8.258 0 0 0 5.873 7.01 13.025 13.025 0 0 1-2.613-7.01zm4.911 7.01a11.295 11.295 0 0 1-3.157-7.01h6.369a11.296 11.296 0 0 1-3.212 7.01zm-3.157-8.76a11.298 11.298 0 0 1 3.217-7.072 11.299 11.299 0 0 1 3.161 7.072H8.813zm8.132 0a13.027 13.027 0 0 0-2.616-7.073 8.257 8.257 0 0 1 5.878 7.073h-3.262zm-0.008 1.75a13.026 13.026 0 0 1-2.669 7.028 8.257 8.257 0 0 0 5.933-7.028h-3.264z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid.xml
new file mode 100644
index 0000000000..ddd9e4b881
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="24dp"
+ android:height="24dp">
+ <path
+ android:pathData="M9.667 3L4.333 3C3.597 3 3 3.597 3 4.333L3 9.667C3 10.403 3.597 11 4.333 11l5.334 0C10.403 11 11 10.403 11 9.667L11 4.333C11 3.597 10.403 3 9.667 3m10 0l-5.334 0C13.597 3 13 3.597 13 4.333l0 5.334C13 10.403 13.597 11 14.333 11l5.334 0C20.403 11 21 10.403 21 9.667L21 4.333C21 3.597 20.403 3 19.667 3m-10 10l-5.334 0C3.597 13 3 13.597 3 14.333l0 5.334C3 20.403 3.597 21 4.333 21l5.334 0C10.403 21 11 20.403 11 19.667l0 -5.334C11 13.597 10.403 13 9.667 13m10 0l-5.334 0C13.597 13 13 13.597 13 14.333l0 5.334C13 20.403 13.597 21 14.333 21l5.334 0C20.403 21 21 20.403 21 19.667l0 -5.334C21 13.597 20.403 13 19.667 13"
+ android:fillColor="@color/mozac_ui_icons_fill"/>
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid_add_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid_add_24.xml
new file mode 100644
index 0000000000..ca83cc4f1d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_grid_add_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3,5.5A2.5,2.5 0,0 1,5.5 3h3A2.5,2.5 0,0 1,11 5.5v3A2.5,2.5 0,0 1,8.5 11h-3A2.5,2.5 0,0 1,3 8.5v-3zM5.5,4.75a0.75,0.75 0,0 0,-0.75 0.75v3c0,0.414 0.336,0.75 0.75,0.75h3a0.75,0.75 0,0 0,0.75 -0.75v-3a0.75,0.75 0,0 0,-0.75 -0.75h-3zM12.75,5.5a2.5,2.5 0,0 1,2.5 -2.5h3a2.5,2.5 0,0 1,2.5 2.5v3a2.5,2.5 0,0 1,-2.5 2.5h-3a2.5,2.5 0,0 1,-2.5 -2.5v-3zM15.25,4.75a0.75,0.75 0,0 0,-0.75 0.75v3c0,0.414 0.336,0.75 0.75,0.75h3A0.75,0.75 0,0 0,19 8.5v-3a0.75,0.75 0,0 0,-0.75 -0.75h-3zM5.5,12.75a2.5,2.5 0,0 0,-2.5 2.5v3a2.5,2.5 0,0 0,2.5 2.5h3a2.5,2.5 0,0 0,2.5 -2.5v-3a2.5,2.5 0,0 0,-2.5 -2.5h-3zM4.75,15.25a0.75,0.75 0,0 1,0.75 -0.75h3a0.75,0.75 0,0 1,0.75 0.75v3a0.75,0.75 0,0 1,-0.75 0.75h-3a0.75,0.75 0,0 1,-0.75 -0.75v-3z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M15.875,15.875V13h1.75v2.875H20.5v1.75h-2.875V20.5h-1.75v-2.875H13v-1.75h2.875z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_24.xml
new file mode 100644
index 0000000000..352515dbe6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13 16h-1.75v1.75H13V16zm-1.75-2.73v0.98H13v-0.98c0-0.27 0.18-0.52 0.46-0.65a3.165 3.165 0 0 0 1.82-2.86 3.15 3.15 0 1 0-6.3 0h1.75c0-0.77 0.63-1.4 1.4-1.4 0.77 0 1.4 0.63 1.4 1.4 0 0.54-0.32 1.04-0.81 1.27-0.91 0.42-1.47 1.28-1.47 2.24z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 22C6.49 22 2 17.51 2 12S6.49 2 12 2s10 4.49 10 10-4.49 10-10 10zm0-18.25c-4.55 0-8.25 3.7-8.25 8.25s3.7 8.25 8.25 8.25 8.25-3.7 8.25-8.25-3.7-8.25-8.25-8.25z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_fill_24.xml
new file mode 100644
index 0000000000..a4f9cf8aec
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_help_circle_fill_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M2 12c0 5.51 4.49 10 10 10s10-4.49 10-10S17.51 2 12 2 2 6.49 2 12zm9.25 2.25v-0.98c0-0.96 0.56-1.82 1.47-2.24 0.49-0.23 0.81-0.73 0.81-1.27 0-0.77-0.63-1.4-1.4-1.4-0.77 0-1.4 0.63-1.4 1.4H8.98a3.15 3.15 0 1 1 6.3 0c0 1.22-0.71 2.34-1.82 2.86C13.18 12.75 13 13 13 13.27v0.98h-1.75zM13 16h-1.75v1.75H13V16z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_history_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_history_24.xml
new file mode 100644
index 0000000000..328727849e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_history_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 3.75a8.25 8.25 0 1 0 0 16.5 8.25 8.25 0 0 0 0-16.5zM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.125 12V7h1.75v4.495l3.74 2.16-0.874 1.515-4.178-2.412A0.875 0.875 0 0 1 11.125 12z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_home_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_home_24.xml
new file mode 100644
index 0000000000..43b4264c5f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_home_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M2.445 11.78l0.805-0.698V18.5a2.5 2.5 0 0 0 2.5 2.5h12.5a2.5 2.5 0 0 0 2.5-2.5v-7.419l0.806 0.7 1.146-1.323-9.042-7.842a2.533 2.533 0 0 0-3.32 0L1.3 10.458l1.146 1.322zm10.069-7.842a0.783 0.783 0 0 0-1.026 0L5 9.564V18.5c0 0.414 0.336 0.75 0.75 0.75h2.5v-4.5a2.5 2.5 0 0 1 2.5-2.5h2.5a2.5 2.5 0 0 1 2.5 2.5v4.5h2.5A0.75 0.75 0 0 0 19 18.5V9.564l-6.486-5.626zM14 19.25v-4.5A0.75 0.75 0 0 0 13.25 14h-2.5A0.75 0.75 0 0 0 10 14.75v4.5h4z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_24.xml
new file mode 100644
index 0000000000..1d12948178
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M18.25 20.75H5.75a2.503 2.503 0 0 1-2.5-2.5V5.75c0-1.379 1.122-2.5 2.5-2.5h12.5c1.379 0 2.5 1.121 2.5 2.5v12.5c0 1.379-1.121 2.5-2.5 2.5zM5.75 5A0.75 0.75 0 0 0 5 5.75v12.5C5 18.663 5.336 19 5.75 19h12.5c0.413 0 0.75-0.337 0.75-0.75V5.75A0.752 0.752 0 0 0 18.25 5H5.75z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M16.5 17.25h-9a0.75 0.75 0 0 1-0.75-0.75v-2.301c0-0.264 0.105-0.518 0.291-0.705l2.783-2.799a1.001 1.001 0 0 1 1.415-0.004L14 13.439l0.792-0.747a1 1 0 0 1 1.396 0.023l0.773 0.779c0.186 0.187 0.29 0.44 0.29 0.704V16.5a0.752 0.752 0 0 1-0.751 0.75zM17.25 8h-2.5v2.5h2.5V8z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_slash_24.xml
new file mode 100644
index 0000000000..49ed64618e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_image_slash_24.xml
@@ -0,0 +1,24 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M3.238 2l1.48 1.48 0.001-0.001 1.521 1.52H6.237l8.11 8.111 0.002-0.001 2.9 2.9v0.003L19 17.762V17.76l1.521 1.52v0.003L22 20.763 20.762 22l-1.476-1.477a2.47 2.47 0 0 1-1.036 0.227H5.75a2.503 2.503 0 0 1-2.5-2.5V5.75c0-0.37 0.081-0.72 0.226-1.036L2 3.238 3.238 2zm6.403 8.878L7.04 13.494a1.001 1.001 0 0 0-0.291 0.705v2.3c0 0.415 0.336 0.75 0.75 0.75h8.514l1.75 1.75H5.75A0.75 0.75 0 0 1 5 18.249V6.238l4.64 4.641z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M17.25 8h-2.5v2.5h2.5V8z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M18.25 5H8.361l-1.75-1.75H18.25c1.379 0 2.5 1.12 2.5 2.5v11.639L19 15.639v-9.89a0.752 0.752 0 0 0-0.75-0.75z"
+ tools:ignore="VectorRaster" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_24.xml
new file mode 100644
index 0000000000..24be636c52
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 3.75a8.25 8.25 0 1 0 0 16.5 8.25 8.25 0 0 0 0-16.5zM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.875 7v1.75h-1.75V7h1.75zm0 3.5V17h-1.75v-6.5h1.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_fill_24.xml
new file mode 100644
index 0000000000..ec7aea93c8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_information_fill_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm0.875-15v1.75h-1.75V7h1.75zm0 10v-6.25h-1.75V17h1.75z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lightbulb_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lightbulb_24.xml
new file mode 100644
index 0000000000..0b3ddafe53
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lightbulb_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.5 9.5a7.5 7.5 0 1 1 15 0c0 2.568-1.3 4.812-3.254 6.16l-0.559 2.17a0.875 0.875 0 0 1-0.847 0.657H9.161c-0.4 0-0.748-0.27-0.847-0.657l-0.559-2.17C5.8 14.312 4.5 12.068 4.5 9.5zM12 3.75A5.75 5.75 0 0 0 6.25 9.5c0 2.057 1.091 3.852 2.73 4.87 0.191 0.12 0.33 0.308 0.385 0.526l0.474 1.841h4.323l0.474-1.841a0.875 0.875 0 0 1 0.385-0.525c1.638-1.019 2.729-2.814 2.729-4.871A5.75 5.75 0 0 0 12 3.75zM15.5 22h-7v-1.75h7V22z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_link_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_link_24.xml
new file mode 100644
index 0000000000..d08122a767
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_link_24.xml
@@ -0,0 +1,18 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5.37 13.28C5.85 13.76 6.47 14 7.1 14l0.01 0.01c0.62 0 1.25-0.24 1.73-0.72l0.38-0.38-1.24-1.24-0.38 0.38c-0.26 0.27-0.72 0.27-0.99 0L3.97 9.41a0.754 0.754 0 0 1 0-1.06l4.38-4.38c0.29-0.29 0.77-0.29 1.06 0l2.64 2.64c0.14 0.13 0.21 0.3 0.21 0.49s-0.08 0.37-0.21 0.5l-0.38 0.38 1.24 1.24 0.38-0.38c0.96-0.96 0.96-2.51 0-3.47l-2.64-2.64c-0.98-0.97-2.56-0.97-3.54 0L2.73 7.1c-0.97 0.98-0.97 2.56 0 3.54l2.64 2.64z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.066 7.821L7.829 9.06l7.106 7.106 1.237-1.237L9.066 7.82z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M15.12 22c-0.64 0-1.28-0.24-1.77-0.73l-2.64-2.64a2.45 2.45 0 0 1 0-3.47l0.38-0.38 1.24 1.24-0.38 0.38c-0.13 0.13-0.21 0.31-0.21 0.5s0.07 0.36 0.21 0.49l2.64 2.64c0.29 0.29 0.77 0.29 1.06 0l4.38-4.38c0.29-0.29 0.29-0.77 0-1.06l-2.64-2.64c-0.26-0.27-0.73-0.26-0.99 0l-0.38 0.38-1.24-1.24 0.38-0.38a2.45 2.45 0 0 1 3.47 0l2.64 2.64c0.97 0.98 0.97 2.56 0 3.54l-4.38 4.38C16.4 21.76 15.76 22 15.12 22z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_24.xml
new file mode 100644
index 0000000000..2ea1d78e61
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.25 10.5c0 2.07 1.68 3.75 3.75 3.75 2.07 0 3.75-1.68 3.75-3.75 0-2.07-1.68-3.75-3.75-3.75-2.07 0-3.75 1.68-3.75 3.75zm1.75 0c0-1.1 0.9-2 2-2s2 0.9 2 2-0.9 2-2 2-2-0.9-2-2z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.31 21.34C10.79 21.78 11.4 22 12 22c0.61 0 1.21-0.22 1.69-0.66 2.64-2.42 7.06-7.02 7.06-10.59C20.75 5.92 16.82 2 12 2s-8.75 3.93-8.75 8.75c0 3.57 4.42 8.17 7.06 10.59zM5 10.75a7.008 7.008 0 0 1 6.995-7 7.008 7.008 0 0 1 6.995 7c0 2.09-2.42 5.56-6.49 9.3-0.29 0.26-0.72 0.26-1.01 0C7.43 16.32 5 12.84 5 10.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_slash_24.xml
new file mode 100644
index 0000000000..db74edb5a5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_location_slash_24.xml
@@ -0,0 +1,18 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7.128 5.737A6.969 6.969 0 0 1 12 3.752a7.005 7.005 0 0 1 6.997 6.997c0 1.181-0.777 2.806-2.186 4.67l1.246 1.246c1.506-1.952 2.69-4.07 2.69-5.916 0-4.823-3.924-8.747-8.747-8.747A8.714 8.714 0 0 0 5.891 4.5l1.237 1.237z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M15.85 16.612L6.153 6.915l0.013-0.02-1.253-1.252-0.014 0.019L3.238 4 2 5.238l1.997 1.997a8.641 8.641 0 0 0-0.744 3.514c0 3.57 4.423 8.168 7.061 10.59a2.488 2.488 0 0 0 1.687 0.663c0.604 0 1.206-0.221 1.687-0.662a45.793 45.793 0 0 0 2.227-2.187L18.762 22 20 20.762l-2.909-2.908 0.016-0.02-1.242-1.24-0.015 0.018zm-1.173 1.303a43.43 43.43 0 0 1-2.174 2.136 0.738 0.738 0 0 1-1.006 0c-4.066-3.736-6.494-7.213-6.494-9.302 0-0.756 0.121-1.483 0.344-2.164l9.33 9.33z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.537 9.146A1.99 1.99 0 0 1 12 8.5c1.103 0 2 0.897 2 2a1.99 1.99 0 0 1-0.646 1.463l1.237 1.237a3.733 3.733 0 0 0 1.159-2.7A3.755 3.755 0 0 0 12 6.75a3.734 3.734 0 0 0-2.7 1.16l1.237 1.236z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_20.xml
new file mode 100644
index 0000000000..17978486c7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_20.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M7,9L7,7a3,3 0,1 1,6 0v2h0.25c0.69,0 1.25,0.56 1.25,1.25v4.5c0,0.69 -0.56,1.25 -1.25,1.25h-6.5c-0.69,0 -1.25,-0.56 -1.25,-1.25v-4.5C5.5,9.56 6.06,9 6.75,9L7,9zM8.25,7a1.75,1.75 0,1 1,3.5 0v2h-3.5L8.25,7z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_24.xml
new file mode 100644
index 0000000000..fd8eeb959f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M7 11V7a5 5 0 0 1 10 0v4a2.5 2.5 0 0 1 2.5 2.5v6A2.5 2.5 0 0 1 17 22H7a2.5 2.5 0 0 1-2.5-2.5v-6A2.5 2.5 0 0 1 7 11zm1.75-4a3.25 3.25 0 0 1 6.5 0v4h-6.5V7zm-2.5 6.5A0.75 0.75 0 0 1 7 12.75h10a0.75 0.75 0 0 1 0.75 0.75v6A0.75 0.75 0 0 1 17 20.25H7a0.75 0.75 0 0 1-0.75-0.75v-6z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_20.xml
new file mode 100644
index 0000000000..48d0d4a80c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_20.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13,9h0.25c0.69,0 1.25,0.56 1.25,1.25v2.592L10.658,9h1.092V7a1.745,1.745 0,0 0,-3.455 -0.363l-0.967,-0.967A2.988,2.988 0,0 1,10 4c1.654,0 3,1.346 3,3v2zM5.5,10.25C5.5,9.56 6.06,9 6.75,9h2.138l5.612,5.612v0.138c0,0.69 -0.56,1.25 -1.25,1.25h-6.5c-0.69,0 -1.25,-0.56 -1.25,-1.25v-4.5z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="m4.385,4.501 l12.114,12.114 -0.884,0.884L3.501,5.385l0.884,-0.884z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_24.xml
new file mode 100644
index 0000000000..b31e23b456
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_slash_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.13 5.508A3.242 3.242 0 0 1 12 3.75 3.254 3.254 0 0 1 15.25 7v4h-0.628l1.75 1.75H17a0.75 0.75 0 0 1 0.75 0.75v0.627l1.75 1.75V13.5c0-1.379-1.121-2.5-2.5-2.5V7c0-2.757-2.243-5-5-5-1.73 0-3.256 0.884-4.154 2.224L9.13 5.508z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M19.5 18.013v-0.015l-1.75-1.75v0.015l-3.513-3.513h0.014L12.501 11h-0.014L8.75 7.263V7.249L7.195 5.694l-0.003 0.01L3.988 2.5 2.75 3.738 7 7.988V11a2.503 2.503 0 0 0-2.5 2.5v6C4.5 20.879 5.622 22 7 22h10a2.504 2.504 0 0 0 2.354-1.658L21.012 22l1.238-1.238-2.75-2.75zm-1.75 0.724V19.5A0.75 0.75 0 0 1 17 20.25H7a0.75 0.75 0 0 1-0.75-0.75v-6A0.75 0.75 0 0 1 7 12.75h4.762l5.988 5.988zm-9-9V11h1.262L8.75 9.738z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_20.xml
new file mode 100644
index 0000000000..2e854faba6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_20.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M8.963,18.436h8.574a1.25,1.25 0,0 0,1.085 -1.87l-4.285,-7.499a1.252,1.252 0,0 0,-2.174 0l-4.285,7.499a1.25,1.25 0,0 0,1.085 1.87zM14,11.5h-1.5v2.75L14,14.25L14,11.5zM14,15.5h-1.5L12.5,17L14,17v-1.5zM3,7L3,5a3,3 0,1 1,6 0v2h0.25c0.69,0 1.25,0.56 1.25,1.25v1.711L8.192,14L2.75,14c-0.69,0 -1.25,-0.56 -1.25,-1.25v-4.5C1.5,7.56 2.06,7 2.75,7L3,7zM4.25,5a1.75,1.75 0,1 1,3.5 0v2h-3.5L4.25,5z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_24.xml
new file mode 100644
index 0000000000..92a72604ac
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_lock_warning_24.xml
@@ -0,0 +1,18 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M22.799 20.749L18.8 13.755a1.496 1.496 0 0 0-2.599 0l-3.999 6.994C11.628 21.751 12.349 23 13.501 23H21.5c1.151 0 1.872-1.249 1.299-2.251z" />
+ <path
+ android:fillColor="#fff"
+ android:pathData="M18.25 16h-1.5v3h1.5v-3zm0 4h-1.5v1.5h1.5V20z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.899 20.004l0.431-0.754H5a0.752 0.752 0 0 1-0.75-0.75v-6c0-0.413 0.337-0.75 0.75-0.75h10c0.289 0 0.533 0.17 0.658 0.41a2.93 2.93 0 0 1 1.644-0.634A2.503 2.503 0 0 0 15 10V6c0-2.757-2.243-5-5-5S5 3.243 5 6v4a2.502 2.502 0 0 0-2.5 2.5v6C2.5 19.879 3.621 21 5 21h5.563c0.059-0.342 0.155-0.68 0.336-0.996zM6.75 6A3.254 3.254 0 0 1 10 2.75 3.254 3.254 0 0 1 13.25 6v4h-6.5V6z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_login_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_login_24.xml
new file mode 100644
index 0000000000..5b1261437e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_login_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 12a5 5 0 0 1 9.9-1H22v1.75h-2.25V16H18v-3.25h-6.056A5.001 5.001 0 0 1 2 12zm5-3.25a3.25 3.25 0 1 0 0 6.5 3.25 3.25 0 0 0 0-6.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_chrome_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_chrome_24.xml
new file mode 100644
index 0000000000..99a9ace127
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_chrome_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12zm17.214-4A8.257 8.257 0 0 0 12 3.75a8.235 8.235 0 0 0-6.264 2.886l2.446 4.235C8.671 9.215 10.186 8 12 8h7.214zm0.565 1.25h-4.886a3.978 3.978 0 0 1 0.411 5.002l-3.462 5.996C11.894 20.25 11.947 20.25 12 20.25c4.549 0 8.25-3.701 8.25-8.25 0-0.964-0.166-1.89-0.471-2.75zm-9.3 10.86l2.44-4.226C12.623 15.954 12.318 16 12 16a3.995 3.995 0 0 1-3.339-1.804l-0.002 0.001-3.725-6.452A8.2 8.2 0 0 0 3.75 12c0 4.03 2.904 7.394 6.73 8.11zM12 14.75A2.754 2.754 0 0 0 14.75 12 2.754 2.754 0 0 0 12 9.25 2.754 2.754 0 0 0 9.25 12c0 0.565 0.172 1.091 0.465 1.528l0.006 0.01A2.75 2.75 0 0 0 12 14.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_firefox_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_firefox_24.xml
new file mode 100644
index 0000000000..cb2d61d9c1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_firefox_24.xml
@@ -0,0 +1,14 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M21.334 8.852a5.478 5.478 0 0 0-2.008-2.457c0.491 0.92 0.833 1.913 1.014 2.941v0.021c-1.125-2.731-3.051-3.832-4.624-6.228L15.48 2.754a3.38 3.38 0 0 1-0.11-0.201 1.692 1.692 0 0 1-0.154-0.396 0.035 0.035 0 0 0-0.011-0.01 0.033 0.033 0 0 0-0.024 0h-0.007a7.04 7.04 0 0 0-3.443 5.383c0.117-0.007 0.234-0.017 0.352-0.017a5.078 5.078 0 0 1 4.387 2.479 3.543 3.543 0 0 0-2.413-0.566 3.996 3.996 0 0 1 1.971 4.745 4.004 4.004 0 0 1-4.327 2.77 4.55 4.55 0 0 1-1.765-0.443 4.093 4.093 0 0 1-2.359-3.165s0.461-1.667 3.308-1.667a2.386 2.386 0 0 0 1.205-1.071 15.96 15.96 0 0 1-2.426-1.397c-0.363-0.349-0.536-0.516-0.69-0.641a2.947 2.947 0 0 0-0.259-0.19A4.356 4.356 0 0 1 8.688 6a7.386 7.386 0 0 0-2.41 1.802 5.12 5.12 0 0 1-0.345-2.427 1.956 1.956 0 0 0-0.334 0.173A7.23 7.23 0 0 0 4.62 6.359a8.682 8.682 0 0 0-0.934 1.084 8.076 8.076 0 0 0-1.35 2.934c0 0.011-0.095 0.406-0.164 0.893l-0.031 0.227a6.357 6.357 0 0 0-0.06 0.555v0.029c-0.006 0.095-0.014 0.2-0.02 0.322v0.05a9.853 9.853 0 0 0 10.008 9.686 9.926 9.926 0 0 0 9.873-8.048l0.045-0.375a9.634 9.634 0 0 0-0.653-4.864z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_safari_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_safari_24.xml
new file mode 100644
index 0000000000..0a5384c40a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_safari_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.101 16.703l5.346-2.617c0.298-0.139 0.503-0.354 0.651-0.642l2.599-5.337c0.298-0.633-0.158-1.118-0.81-0.801L10.56 9.904c-0.289 0.14-0.485 0.335-0.643 0.652L7.3 15.902c-0.298 0.615 0.186 1.099 0.801 0.801zm3.894-3.453a1.245 1.245 0 0 1-1.245-1.255c0-0.694 0.551-1.245 1.245-1.245 0.694 0 1.255 0.551 1.255 1.245 0 0.694-0.561 1.255-1.255 1.255z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12zm18.25 0c0-4.549-3.701-8.25-8.25-8.25-4.549 0-8.25 3.701-8.25 8.25 0 4.549 3.701 8.25 8.25 8.25 4.549 0 8.25-3.701 8.25-8.25z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_24.xml
new file mode 100644
index 0000000000..e74647aa45
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.25 5.75a3.75 3.75 0 1 1 7.5 0v4.75a3.75 3.75 0 1 1-7.5 0V5.75zm3.75-2a2 2 0 0 0-2 2v4.75a2 2 0 1 0 4 0V5.75a2 2 0 0 0-2-2z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.125 17.686a7.251 7.251 0 0 1-6.375-7.198H6.5a5.5 5.5 0 1 0 11 0h1.75a7.251 7.251 0 0 1-6.375 7.198v2.564H17V22H7v-1.75h4.125v-2.564z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_slash_24.xml
new file mode 100644
index 0000000000..4fe5205213
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_microphone_slash_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10 7.636V5.75c0-1.103 0.897-2 2-2s2 0.897 2 2v4.75c0 0.328-0.087 0.634-0.228 0.908l1.269 1.269A3.718 3.718 0 0 0 15.75 10.5V5.75A3.755 3.755 0 0 0 12 2a3.755 3.755 0 0 0-3.75 3.75v0.136L10 7.636zm7.529 7.53a7.216 7.216 0 0 0 1.721-4.679H17.5c0 1.3-0.456 2.494-1.213 3.436l1.242 1.243zM8.25 8.013L3.238 3 2 4.238l6.25 6.25V10.5A3.755 3.755 0 0 0 12 14.25h0.012l1.519 1.518c-0.486 0.143-1 0.219-1.531 0.219a5.507 5.507 0 0 1-5.5-5.5H4.75c0 3.702 2.788 6.764 6.375 7.197v2.566H7V22h10v-1.75h-4.125v-2.566a7.157 7.157 0 0 0 2.018-0.554l4.87 4.87L21 20.762l-4.558-4.558 0.003-0.002-1.248-1.248-0.003 0.002-1.26-1.26 0.003-0.002-1.306-1.306-0.004 0.001L10 9.763V9.757l-1.75-1.75v0.006z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_more_grid_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_more_grid_24.xml
new file mode 100644
index 0000000000..a3ff0f9ee2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_more_grid_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4 4.5h2.5V7H4V4.5zm2.5 6H4V13h2.5v-2.5zm6.75 0h-2.5V13h2.5v-2.5zm4.25 0H20V13h-2.5v-2.5zm-11 6H4V19h2.5v-2.5zm4.25 0h2.5V19h-2.5v-2.5zm9.25 0h-2.5V19H20v-2.5zm-6.75-12h-2.5V7h2.5V4.5zm4.25 0H20V7h-2.5V4.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_mozilla.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_mozilla.xml
new file mode 100644
index 0000000000..e06824d921
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_mozilla.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
+ <path android:pathData="M0 0h24v24H0zm20.4 15.035v-4.764c0-2.436-1.694-3.565-3.565-3.565-1.623 0-2.788 0.847-3.353 2.223-0.494-1.517-1.87-2.223-3.353-2.223-1.447 0-2.505 0.67-3.14 1.765V6.918H2.646v2.258h1.377V15H2.647v2.259H9V15H7.023v-3.6c0-1.412 0.565-2.435 1.977-2.435 1.165 0 1.765 0.67 1.765 2.47v5.824h4.34V15H13.73v-3.6c0-1.412 0.565-2.435 1.977-2.435 1.165 0 1.765 0.67 1.765 2.47v5.86h4.34v-2.26z" android:fillColor="@color/mozac_ui_icons_fill"/>
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_night_mode_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_night_mode_24.xml
new file mode 100644
index 0000000000..33b152e9cd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_night_mode_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.98 22c-0.34 0-0.67-0.02-1.01-0.05-4.87-0.49-8.72-4.56-8.95-9.46a9.967 9.967 0 0 1 7.9-10.27 1.371 1.371 0 0 1 1.41 2.11c-0.97 1.5-1.31 3.3-0.94 5.09 0.54 2.64 2.7 4.73 5.36 5.2 1.23 0.22 2.43 0.12 3.57-0.3 0.54-0.2 1.13-0.06 1.51 0.36 0.38 0.41 0.47 0.99 0.24 1.49a10.02 10.02 0 0 1-9.1 5.81L11.98 22zM9.42 4.17a8.213 8.213 0 0 0-5.66 8.24c0.19 4.04 3.37 7.39 7.38 7.8 3.22 0.31 6.3-1.25 7.93-3.96-1.17 0.29-2.4 0.34-3.62 0.12-3.36-0.6-6.08-3.24-6.77-6.57-0.4-1.94-0.14-3.9 0.73-5.62l0.01-0.01z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_24.xml
new file mode 100644
index 0000000000..c657fa63bd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M18 8H6V6.25h12V8zM6 12h7v-1.75H6V12z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 4.5A2.5 2.5 0 0 1 4.5 2h15A2.5 2.5 0 0 1 22 4.5v10a2.5 2.5 0 0 1-2.5 2.5H18v4.125a0.875 0.875 0 0 1-1.494 0.619L11.763 17H4.5A2.5 2.5 0 0 1 2 14.5v-10zm2.5-0.75A0.75 0.75 0 0 0 3.75 4.5v10c0 0.414 0.336 0.75 0.75 0.75h7.625c0.232 0 0.455 0.092 0.619 0.256l3.506 3.507v-2.888c0-0.483 0.392-0.875 0.875-0.875H19.5a0.75 0.75 0 0 0 0.75-0.75v-10a0.75 0.75 0 0 0-0.75-0.75h-15z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_dot_badge_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_dot_badge_fill_20.xml
new file mode 100644
index 0000000000..ccc3d2277a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_dot_badge_fill_20.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="#fff"
+ android:pathData="M10 15.5a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10 14a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_slash_24.xml
new file mode 100644
index 0000000000..2fac0b2e16
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_notification_slash_24.xml
@@ -0,0 +1,24 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M18.237 17L22 20.762 20.762 22 18 19.237v1.888a0.876 0.876 0 0 1-1.494 0.619L11.763 17H4.5A2.502 2.502 0 0 1 2 14.5v-10c0-0.37 0.081-0.72 0.227-1.036L1 2.238 2.238 1l1.23 1.23 0.001-0.001L4.99 3.75H4.987l6.5 6.5h0.003L13 11.76v0.003l3.648 3.647 0.002-0.001L18.24 17h-0.003zm-9.224-6.75H6V12h4.763l5.487 5.487v1.526l-3.506-3.507a0.876 0.876 0 0 0-0.619-0.256H4.5a0.752 0.752 0 0 1-0.75-0.75V4.987l5.263 5.263z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7.111 3.75H19.5c0.413 0 0.75 0.337 0.75 0.75v10c0 0.413-0.337 0.75-0.75 0.75h-0.889l1.626 1.626A2.494 2.494 0 0 0 22 14.5v-10C22 3.121 20.879 2 19.5 2H5.361l1.75 1.75z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.361 8H18V6.25H9.611L11.361 8z"
+ tools:ignore="VectorRaster" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_open_in.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_open_in.xml
new file mode 100644
index 0000000000..22ed8d0e8e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_open_in.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
+ <path android:fillColor="@color/mozac_ui_icons_fill" android:pathData="M7 5C5.895 5 5 5.895 5 7v10c0 1.105 0.895 2 2 2h10c1.105 0 2-0.895 2-2v-1c0-0.552 0.448-1 1-1s1 0.448 1 1v1c0 2.21-1.79 4-4 4H7c-2.21 0-4-1.79-4-4V7c0-2.21 1.79-4 4-4h1c0.552 0 1 0.448 1 1S8.552 5 8 5H7zm6 0c-0.552 0-1-0.448-1-1s0.448-1 1-1h7c0.552 0 1 0.448 1 1v7c0 0.552-0.448 1-1 1s-1-0.448-1-1V6.414l-6.293 6.293c-0.39 0.39-1.024 0.39-1.414 0-0.39-0.39-0.39-1.024 0-1.414L17.586 5H13z"/>
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_packaging_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_packaging_24.xml
new file mode 100644
index 0000000000..cb11947a79
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_packaging_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M5.5 3A2.5 2.5 0 0 0 3 5.5v13A2.5 2.5 0 0 0 5.5 21h13a2.5 2.5 0 0 0 2.5-2.5v-13A2.5 2.5 0 0 0 18.5 3h-13zM4.75 5.5A0.75 0.75 0 0 1 5.5 4.75H8v6.754a0.875 0.875 0 0 0 1.3 0.765l2.7-1.5 2.7 1.5a0.875 0.875 0 0 0 1.3-0.765V4.75h2.5a0.75 0.75 0 0 1 0.75 0.75v13a0.75 0.75 0 0 1-0.75 0.75h-13a0.75 0.75 0 0 1-0.75-0.75v-13zm9.5-0.75h-4.5v5.267l1.825-1.014a0.875 0.875 0 0 1 0.85 0l1.825 1.014V4.75z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_24.xml
new file mode 100644
index 0000000000..4656a7edfc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.625 16v-3.625H7v-1.75h3.625V7h1.75v3.625H16v1.75h-3.625V16h-1.75z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2.004 11.224c0.14-4.952 4.27-9.08 9.222-9.22C16.589 1.852 21 6.171 21 11.5v7a2.5 2.5 0 0 1-2.5 2.5h-7c-5.33 0-9.65-4.413-9.496-9.776zM3.75 11.5c0 4.273 3.477 7.75 7.75 7.75s7.75-3.477 7.75-7.75-3.477-7.75-7.75-7.75-7.75 3.477-7.75 7.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_fill_24.xml
new file mode 100644
index 0000000000..7618b38421
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_page_zoom_fill_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.226,2.004c-4.952,0.14 -9.081,4.268 -9.222,9.22C1.85,16.587 6.17,21 11.5,21h7a2.5,2.5 0,0 0,2.5 -2.5v-7c0,-5.33 -4.411,-9.648 -9.774,-9.496zM10.625,16v-3.625H7v-1.75h3.625V7h1.75v3.625H16v1.75h-3.625V16h-1.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_passkey_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_passkey_24.xml
new file mode 100644
index 0000000000..1c21042887
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_passkey_24.xml
@@ -0,0 +1,18 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M14,7a4,4 0,1 1,-8 0,4 4,0 0,1 8,0z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M19.375,15.883a3.505,3.505 0,0 0,2.505 -4.315,3.461 3.461,0 0,0 -2.447,-2.447A3.724,3.724 0,0 0,18.5 9a3.5,3.5 0,0 0,-3.5 3.5,3.491 3.491,0 0,0 2.625,3.376V22h1.75v-1H21v-2.5h-1.625v-2.617zM16.75,12.5c0,-0.965 0.785,-1.75 1.75,-1.75 0.162,0 0.328,0.022 0.495,0.065a1.705,1.705 0,0 1,1.191 1.191,1.77 1.77,0 0,1 -0.3,1.564 1.752,1.752 0,0 1,-3.136 -1.07z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M16.375,16.736a4.733,4.733 0,0 1,-2.607 -3.986H6.75A4.75,4.75 0,0 0,2 17.5V21h14.375v-4.264z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pause_badge_fill_16.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pause_badge_fill_16.xml
new file mode 100644
index 0000000000..0ce77d4936
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pause_badge_fill_16.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="16dp"
+ android:height="16dp"
+ android:viewportWidth="16"
+ android:viewportHeight="16">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6 12H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1zm5 0h-1a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_permissions_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_permissions_24.xml
new file mode 100644
index 0000000000..0320b89369
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_permissions_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M2 6.5A2.5 2.5 0 0 1 4.5 4h15A2.5 2.5 0 0 1 22 6.5v10a2.5 2.5 0 0 1-2.5 2.5h-15A2.5 2.5 0 0 1 2 16.5v-10zm17.5 10.75H12V5.75h7.5a0.75 0.75 0 0 1 0.75 0.75v10a0.75 0.75 0 0 1-0.75 0.75zM6.908 13.561L10.5 9.97 9.439 8.91l-3.061 3.061-1.817-1.817-1.06 1.061 2.347 2.347a0.75 0.75 0 0 0 1.06 0z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13.125 9.56l1.06-1.06 1.94 1.94 1.939-1.94 1.06 1.061-1.938 1.94 1.938 1.938-1.06 1.06-1.94-1.938-1.939 1.94-1.06-1.061 1.94-1.94-1.94-1.94z"
+ tools:ignore="VectorRaster" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pet.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pet.xml
new file mode 100644
index 0000000000..2294410c09
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pet.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M28.5,8.1c0-1.1-1-1.9-2.1-2.4V3.7c-0.2-0.2-0.3-0.3-0.6-0.3c-0.6,0-1.1,0.8-1.3,2.1c-0.2,0-0.3,0-0.5,0l0,0
+ c0-0.2,0-0.3-0.2-0.5c-0.3-1.1-0.8-1.9-1.3-2.6C22,2.6,21.7,3.2,21.7,4L22,6.3c-0.3,0.2-0.6,0.3-1,0.6l-3.5,3.7l0,0
+ c0,0-6.3-0.8-10.9,0.2c-0.6,0-1,0.2-1.1,0.3c-0.5,0.2-0.8,0.3-1.1,0.6c-1.1-0.8-2.2-2.1-3.2-4c0-0.3-0.5-0.5-0.8-0.5s-0.5,0.6-0.3,1
+ c0.8,2.1,2.1,3.5,3.4,4.5c-0.5,0.5-0.8,1-1,1.6c0,0-0.3,2.2-0.3,5.5l1.4,8c0,1,0.8,1.8,1.9,1.8c1,0,1.9-0.8,1.9-1.8V23l0.5-1.3h8.8
+ l0.8,1.3v4.7c0,1,0.8,1.8,1.9,1.8c1,0,1.6-0.6,1.8-1.4l0,0l1.9-9l0,0l2.1-6.4h3c3.4,0,3.7-2.9,3.7-2.9L28.5,8.1z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_24.xml
new file mode 100644
index 0000000000..48c5ab7837
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M12.172 3.238L10.78 4.629l3.823 3.824 3.266 0.072c1.875 0.041 2.786 2.31 1.46 3.637l-2.965 2.964L22 20.762 20.762 22l-5.636-5.636-2.964 2.964c-1.327 1.328-3.594 0.415-3.637-1.458l-0.073-3.267L4.63 10.78l-1.391 1.392L2 10.934 10.934 2l1.238 1.238zM5.866 9.543l3.676-3.676 4.32 4.32 3.969 0.088a0.38 0.38 0 0 1 0.26 0.65l-7.167 7.167a0.38 0.38 0 0 1-0.65-0.262l-0.088-3.967-4.32-4.32z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_badge_fill_16.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_badge_fill_16.xml
new file mode 100644
index 0000000000..6838f756f5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_badge_fill_16.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="16dp"
+ android:height="16dp"
+ android:viewportWidth="16"
+ android:viewportHeight="16">
+ <path
+ android:fillColor="#fff"
+ android:pathData="M7.428 3.416l0.598 0.598 0.287 0.287L7.71 4.905 9.115 6.31l1.751 0.088a0.836 0.836 0 0 1 0.747 0.542 0.835 0.835 0 0 1-0.191 0.902l-1.347 1.347 2.51 2.51-0.143 0.143-0.598 0.598-0.143 0.143-2.51-2.51-1.347 1.347a0.836 0.836 0 0 1-0.902 0.191 0.836 0.836 0 0 1-0.542-0.747L6.31 9.115 4.905 7.71 4.301 8.313l-0.22-0.22-0.067-0.066-0.598-0.599 4.012-4.012zm0-1.416L6.72 2.708 2.708 6.72 2 7.428l0.708 0.708 0.598 0.598 0.068 0.067 0.219 0.219 0.708 0.708 0.604-0.604 0.425 0.427 0.069 1.366a1.848 1.848 0 0 0 3.152 1.213l0.639-0.639 1.802 1.802L11.699 14l0.708-0.708 0.143-0.143 0.598-0.598 0.144-0.144L14 11.699l-0.708-0.708-1.802-1.802 0.64-0.639a1.827 1.827 0 0 0 0.418-1.969 1.848 1.848 0 0 0-1.631-1.183L9.551 5.33 9.126 4.905 9.73 4.301 9.022 3.593 8.735 3.306 8.136 2.708 7.428 2z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.866 6.399L9.115 6.31 7.71 4.905l0.604-0.604-0.287-0.287-0.599-0.598-4.012 4.012 0.598 0.598 0.067 0.067 0.22 0.22 0.604-0.603L6.31 9.115l0.088 1.751a0.836 0.836 0 0 0 0.542 0.747 0.835 0.835 0 0 0 0.902-0.191l1.347-1.347 2.51 2.51 0.143-0.143 0.598-0.598 0.143-0.143-2.51-2.51 1.347-1.347a0.835 0.835 0 0 0 0.191-0.902 0.83 0.83 0 0 0-0.745-0.543z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_fill_24.xml
new file mode 100644
index 0000000000..98e17c09f4
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_fill_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.172 3.238L10.78 4.629l3.823 3.823 3.864 0.086a1.85 1.85 0 0 1 1.698 1.176 1.847 1.847 0 0 1-0.414 2.024l-3.388 3.388L22 20.762 20.762 22l-5.636-5.637-3.389 3.389a1.853 1.853 0 0 1-2.024 0.414 1.871 1.871 0 0 1-1.177-1.698l-0.085-3.864-3.822-3.823-1.391 1.39L2 10.935 10.934 2l1.238 1.238z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_filled.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_filled.xml
new file mode 100644
index 0000000000..80394cc3be
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_filled.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.617 2.076a1 1 0 0 1 1.09 0.217l8 8A1 1 0 0 1 21 12c-1.034 0-1.886 0.007-2.6 0.212-0.647 0.184-1.149 0.522-1.506 1.235-0.189 0.378-0.293 0.773-0.379 1.247-0.026 0.144-0.053 0.314-0.082 0.5-0.057 0.357-0.123 0.77-0.207 1.148-0.288 1.297-0.875 2.721-2.519 4.365a1 1 0 0 1-1.414 0L8.5 16.914l-4.793 4.793a1 1 0 1 1-1.414-1.414L7.086 15.5l-3.793-3.793a1 1 0 0 1 0-1.414c1.644-1.644 3.068-2.23 4.365-2.52 0.378-0.083 0.79-0.149 1.149-0.206 0.185-0.029 0.355-0.056 0.498-0.082 0.475-0.086 0.87-0.19 1.248-0.38 0.713-0.356 1.05-0.858 1.235-1.505C11.993 4.885 12 4.034 12 3a1 1 0 0 1 0.617-0.924z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_24.xml
new file mode 100644
index 0000000000..a7a930a25e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_24.xml
@@ -0,0 +1,20 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 10.933L10.933 2l1.238 1.238-1.39 1.39 2.793 2.795-1.237 1.238-2.794-2.794-3.676 3.676 2.795 2.794-1.238 1.238-2.795-2.794-1.391 1.39L2 10.933z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M12.163 19.328l2.963-2.963L20.761 22l1.238-1.238-5.635-5.635 2.966-2.966A2.103 2.103 0 0 0 19.8 9.86a2.102 2.102 0 0 0-1.931-1.336l-0.774-0.017 4.52-4.52-1.238-1.237-5.703 5.703h-0.008l-1.268 1.268 0.004 0.004-3.676 3.676-0.004-0.004-1.268 1.268v0.008l-6.34 6.34 1.238 1.237 5.156-5.156 0.017 0.774c0.02 0.867 0.531 1.606 1.337 1.93a2.108 2.108 0 0 0 2.301-0.47zm-1.942-3.947l0.054 2.448a0.362 0.362 0 0 0 0.238 0.345c0.089 0.036 0.257 0.07 0.411-0.084l7.167-7.167a0.362 0.362 0 0 0 0.084-0.411 0.362 0.362 0 0 0-0.345-0.238l-2.448-0.054-5.161 5.161z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_fill_24.xml
new file mode 100644
index 0000000000..468269cd9f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_pin_slash_fill_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="m13.57,7.42 l-1.23,1.24 -4.92,4.92 -2.79,-2.8 -1.39,1.39L2,10.93 10.93,2l1.24,1.24 -1.39,1.39 2.79,2.79zM16.36,15.12 L22,20.76h0.01L20.77,22l-5.64,-5.64 -2.96,2.96c-0.42,0.41 -0.95,0.63 -1.5,0.63 -0.27,0 -0.55,-0.05 -0.81,-0.16a2.092,2.092 0,0 1,-1.34 -1.93l-0.02,-0.77 -5.15,5.15L2.11,21l6.34,-6.35 1.27,-1.26L20.37,2.74l1.24,1.24 -4.52,4.52 0.77,0.02c0.87,0.02 1.61,0.54 1.93,1.34 0.32,0.8 0.14,1.69 -0.47,2.3l-2.96,2.96z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_play_badge_fill_16.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_play_badge_fill_16.xml
new file mode 100644
index 0000000000..4381c247f8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_play_badge_fill_16.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="16dp"
+ android:height="16dp"
+ android:viewportWidth="16"
+ android:viewportHeight="16">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4 11.998V4a1 1 0 0 1 1.496-0.868l7 3.999a1 1 0 0 1 0 1.736l-7 3.999A1 1 0 0 1 4 11.998z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plugin_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plugin_24.xml
new file mode 100644
index 0000000000..762c701245
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plugin_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.25 6V4a1 1 0 0 0-1-1h-3a1 1 0 0 0-1 1v2H4.5A2.5 2.5 0 0 0 2 8.5v10A2.5 2.5 0 0 0 4.5 21h15a2.5 2.5 0 0 0 2.5-2.5v-10A2.5 2.5 0 0 0 19.5 6h-0.75V4a1 1 0 0 0-1-1h-3a1 1 0 0 0-1 1v2h-3.5zm-6.5 2.5A0.75 0.75 0 0 1 4.5 7.75h15a0.75 0.75 0 0 1 0.75 0.75v10a0.75 0.75 0 0 1-0.75 0.75h-15a0.75 0.75 0 0 1-0.75-0.75v-10z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plus_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plus_24.xml
new file mode 100644
index 0000000000..57d12452ff
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_plus_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.125 12.875v7.875h1.75v-7.875h7.875v-1.75h-7.875V3.25h-1.75v7.875H3.25v1.75h7.875z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_preferences.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_preferences.xml
new file mode 100644
index 0000000000..9085f636b0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_preferences.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="16dp"
+ android:height="16dp"
+ android:autoMirrored="true"
+ android:viewportWidth="16"
+ android:viewportHeight="16">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M15,7h-2.1a4.967,4.967 0,0 0,-0.732 -1.753l1.49,-1.49a1,1 0,0 0,-1.414 -1.414l-1.49,1.49A4.968,4.968 0,0 0,9 3.1V1a1,1 0,0 0,-2 0v2.1a4.968,4.968 0,0 0,-1.753 0.732l-1.49,-1.49a1,1 0,0 0,-1.414 1.415l1.49,1.49A4.967,4.967 0,0 0,3.1 7H1a1,1 0,0 0,0 2h2.1a4.968,4.968 0,0 0,0.737 1.763c-0.014,0.013 -0.032,0.017 -0.045,0.03l-1.45,1.45a1,1 0,1 0,1.414 1.414l1.45,-1.45c0.013,-0.013 0.018,-0.031 0.03,-0.045A4.968,4.968 0,0 0,7 12.9V15a1,1 0,0 0,2 0v-2.1a4.968,4.968 0,0 0,1.753 -0.732l1.49,1.49a1,1 0,0 0,1.414 -1.414l-1.49,-1.49A4.967,4.967 0,0 0,12.9 9H15a1,1 0,0 0,0 -2zM5,8a3,3 0,1 1,3 3,3 3,0 0,1 -3,-3z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_price_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_price_24.xml
new file mode 100644
index 0000000000..dbcc92a58f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_price_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.317 7.637l-1.591 1.59-1.591-1.59 1.59-1.591 1.592 1.59z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2.75 2a0.875 0.875 0 0 0-0.875 0.875v8.584c0 0.232 0.092 0.455 0.256 0.619l8.18 8.179a2.5 2.5 0 0 0 3.535 0l6.285-6.285a2.5 2.5 0 0 0 0-3.536l-8.18-8.18A0.875 0.875 0 0 0 11.334 2H2.75zm0.875 9.097V3.75h7.345l7.923 7.924a0.75 0.75 0 0 1 0 1.06l-6.285 6.285a0.75 0.75 0 0 1-1.06 0l-7.923-7.922z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_print_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_print_24.xml
new file mode 100644
index 0000000000..681fffdff0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_print_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7 3.5A2.5 2.5 0 0 1 9.5 1h5A2.5 2.5 0 0 1 17 3.5V7h2.5A2.5 2.5 0 0 1 22 9.5v6a2.5 2.5 0 0 1-2.5 2.5H17v1.5a2.5 2.5 0 0 1-2.5 2.5h-5A2.5 2.5 0 0 1 7 19.5V18H4.5A2.5 2.5 0 0 1 2 15.5v-6A2.5 2.5 0 0 1 4.5 7H7V3.5zM8.75 7h6.5V3.5a0.75 0.75 0 0 0-0.75-0.75h-5A0.75 0.75 0 0 0 8.75 3.5V7zm0 7v5.5c0 0.414 0.336 0.75 0.75 0.75h5a0.75 0.75 0 0 0 0.75-0.75V14h-6.5zM19 10h-2v2h2v-2z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_24.xml
new file mode 100644
index 0000000000..5d3237c2ce
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_24.xml
@@ -0,0 +1,14 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M21.914,8.849c0.05,-0.99 -0.62,-1.873 -1.587,-2.093a7.425,7.425 0,0 0,-6.702 1.804l-0.308,0.286a1.939,1.939 0,0 1,-2.643 -0.001l-0.301,-0.28a7.427,7.427 0,0 0,-6.707 -1.808h-0.002A2.043,2.043 0,0 0,2.08 8.844v0.006c-0.247,0.975 0.134,4.575 0.35,5.141 0.434,2.287 2.303,4.007 4.543,4.007 1.12,0 2.132,-0.447 2.933,-1.161l0.488,-0.418a2.436,2.436 0,0 1,3.139 -0.025l0.734,0.606v-0.003c0.772,0.621 1.718,1.001 2.754,1.001 2.24,0 4.109,-1.72 4.543,-4.007 0.216,-0.567 0.611,-4.152 0.35,-5.142zM9.79,12.69c-0.533,0.603 -1.36,0.991 -2.29,0.991 -0.93,0 -1.757,-0.388 -2.29,-0.991a0.866,0.866 0,0 1,0 -1.131c0.533,-0.603 1.36,-0.991 2.29,-0.991 0.93,0 1.757,0.388 2.29,0.991 0.28,0.317 0.28,0.815 0,1.131zM18.79,12.69c-0.533,0.603 -1.36,0.991 -2.29,0.991 -0.93,0 -1.757,-0.388 -2.29,-0.991a0.866,0.866 0,0 1,0 -1.131c0.533,-0.603 1.36,-0.991 2.29,-0.991 0.93,0 1.757,0.388 2.29,0.991 0.28,0.317 0.28,0.815 0,1.131z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_20.xml
new file mode 100644
index 0000000000..b6ce9a33e8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_20.xml
@@ -0,0 +1,17 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="?mozac_ic_private_mode_circle_fill_background_color"
+ android:pathData="M10,18c-4.411,0 -8,-3.589 -8,-8s3.589,-8 8,-8 8,3.589 8,8 -3.589,8 -8,8z" />
+ <path
+ android:fillColor="?mozac_ic_private_mode_circle_fill_icon_color"
+ android:pathData="M14.957,8.51a1.02,1.02 0,0 0,-0.793 -1.046,3.714 3.714,0 0,0 -3.351,0.902l-0.154,0.143a0.968,0.968 0,0 1,-1.321 0l-0.15,-0.14a3.712,3.712 0,0 0,-3.354 -0.905c-0.482,0.11 -0.817,0.549 -0.794,1.043v0.003c-0.123,0.488 0.067,2.287 0.175,2.571 0.217,1.144 1.152,2.004 2.272,2.004 0.56,0 1.066,-0.223 1.467,-0.581l0.244,-0.209a1.219,1.219 0,0 1,1.57 -0.012l0.366,0.303v-0.002c0.386,0.31 0.859,0.5 1.377,0.5 1.12,0 2.055,-0.86 2.272,-2.004 0.107,-0.283 0.304,-2.075 0.174,-2.57zM8.874,10.511c-0.32,0.387 -0.816,0.637 -1.374,0.637a1.775,1.775 0,0 1,-1.374 -0.637,0.587 0.587,0 0,1 0,-0.727c0.32,-0.387 0.816,-0.636 1.374,-0.636 0.558,0 1.054,0.249 1.374,0.637a0.586,0.586 0,0 1,0 0.726zM13.874,10.511c-0.32,0.387 -0.816,0.637 -1.374,0.637a1.775,1.775 0,0 1,-1.374 -0.637,0.587 0.587,0 0,1 0,-0.727c0.32,-0.387 0.816,-0.637 1.374,-0.637 0.558,0 1.054,0.249 1.374,0.637a0.587,0.587 0,0 1,0 0.727z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_24.xml
new file mode 100644
index 0000000000..bcb350e8fd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_24.xml
@@ -0,0 +1,17 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="?mozac_ic_private_mode_circle_fill_background_color"
+ android:pathData="M12,22C6.486,22 2,17.514 2,12S6.486,2 12,2s10,4.486 10,10 -4.486,10 -10,10z" />
+ <path
+ android:fillColor="?mozac_ic_private_mode_circle_fill_icon_color"
+ android:pathData="M18.196,10.053a1.275,1.275 0,0 0,-0.992 -1.308,4.642 4.642,0 0,0 -4.189,1.127l-0.192,0.179a1.208,1.208 0,0 1,-1.651 -0.001l-0.188,-0.175a4.643,4.643 0,0 0,-4.192 -1.13,1.277 1.277,0 0,0 -0.992,1.304v0.004c-0.154,0.609 0.084,2.859 0.219,3.213 0.271,1.429 1.439,2.505 2.84,2.505 0.699,0 1.332,-0.279 1.833,-0.726l0.305,-0.261a1.524,1.524 0,0 1,1.962 -0.016l0.458,0.379v-0.002a2.734,2.734 0,0 0,1.72 0.626c1.4,0 2.569,-1.075 2.841,-2.505 0.134,-0.354 0.38,-2.594 0.218,-3.213zM10.603,12.524A2.072,2.072 0,0 1,9 13.267c-0.651,0 -1.23,-0.291 -1.603,-0.743a0.685,0.685 0,0 1,0 -0.848A2.072,2.072 0,0 1,9 10.933c0.65,0 1.23,0.291 1.603,0.743a0.685,0.685 0,0 1,0 0.848zM16.603,12.524a2.072,2.072 0,0 1,-1.603 0.743c-0.651,0 -1.23,-0.291 -1.603,-0.743a0.685,0.685 0,0 1,0 -0.848A2.072,2.072 0,0 1,15 10.933c0.651,0 1.23,0.291 1.603,0.743a0.685,0.685 0,0 1,0 0.848z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_48.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_48.xml
new file mode 100644
index 0000000000..dfb4091077
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_48.xml
@@ -0,0 +1,17 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <path
+ android:fillColor="?mozac_ic_private_mode_circle_fill_background_color"
+ android:pathData="M24,24m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0" />
+ <path
+ android:fillColor="?mozac_ic_private_mode_circle_fill_icon_color"
+ android:pathData="M33.914,20.849c0.05,-0.99 -0.62,-1.873 -1.587,-2.093a7.425,7.425 0,0 0,-6.702 1.804l-0.308,0.286a1.939,1.939 0,0 1,-2.643 -0.001l-0.301,-0.28a7.427,7.427 0,0 0,-6.707 -1.808h-0.002a2.043,2.043 0,0 0,-1.584 2.087v0.006c-0.247,0.975 0.134,4.575 0.35,5.141 0.434,2.287 2.303,4.007 4.543,4.007 1.119,0 2.132,-0.447 2.933,-1.161l0.488,-0.418a2.436,2.436 0,0 1,3.139 -0.025l0.734,0.606v-0.003c0.772,0.621 1.718,1.001 2.754,1.001 2.24,0 4.109,-1.72 4.543,-4.007 0.216,-0.567 0.611,-4.152 0.35,-5.142zM21.79,24.69c-0.533,0.603 -1.36,0.991 -2.29,0.991 -0.93,0 -1.757,-0.388 -2.29,-0.991a0.866,0.866 0,0 1,0 -1.131c0.533,-0.603 1.36,-0.991 2.29,-0.991 0.93,0 1.757,0.388 2.29,0.991 0.28,0.317 0.28,0.815 0,1.131zM30.79,24.69c-0.533,0.603 -1.36,0.991 -2.29,0.991 -0.93,0 -1.757,-0.388 -2.29,-0.991a0.866,0.866 0,0 1,0 -1.131c0.533,-0.603 1.36,-0.991 2.29,-0.991 0.93,0 1.757,0.388 2.29,0.991 0.28,0.317 0.28,0.815 0,1.131z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_stroke_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_stroke_20.xml
new file mode 100644
index 0000000000..2ee67055dd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_private_mode_circle_fill_stroke_20.xml
@@ -0,0 +1,22 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_private_mode_circle_fill"
+ android:pathData="M1.5 10c0 4.686 3.814 8.5 8.5 8.5s8.5-3.814 8.5-8.5-3.814-8.5-8.5-8.5S1.5 5.314 1.5 10z"
+ android:strokeWidth="1"
+ android:strokeColor="#fff"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M12.49 6.99h1.28c0.67 0 1.21 0.54 1.21 1.21v2c0 1.01-0.5 1.95-1.34 2.51l-0.16 0.11c-0.2 0.13-0.43 0.2-0.67 0.2h-0.34c-0.25 0-0.49-0.08-0.7-0.23l-1.13-0.81a0.897 0.897 0 0 0-0.52-0.17H9.84c-0.19 0-0.37 0.06-0.52 0.17l-1.13 0.81c-0.2 0.15-0.45 0.23-0.7 0.23H7.15c-0.24 0-0.47-0.07-0.67-0.2l-0.16-0.11a3.01 3.01 0 0 1-1.34-2.51v-2c0-0.67 0.54-1.21 1.21-1.21h1.3c0.71 0 1.37 0.32 1.81 0.87 0.17 0.21 0.42 0.33 0.69 0.33 0.27 0 0.52-0.12 0.69-0.33 0.44-0.55 1.11-0.87 1.81-0.87zm-3.62 3.2c-0.32 0.36-0.82 0.59-1.37 0.59-0.55 0-1.05-0.23-1.37-0.59a0.517 0.517 0 0 1 0-0.68C6.45 9.15 6.95 8.92 7.5 8.92c0.55 0 1.05 0.23 1.37 0.59 0.17 0.19 0.17 0.49 0 0.68zm2.26 0c0.32 0.36 0.82 0.59 1.37 0.59 0.55 0 1.05-0.23 1.37-0.59 0.17-0.19 0.17-0.49 0-0.68-0.32-0.36-0.82-0.59-1.37-0.59-0.55 0-1.05 0.23-1.37 0.59-0.17 0.19-0.17 0.49 0 0.68z"
+ tools:ignore="VectorPath,VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_qr_code_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_qr_code_24.xml
new file mode 100644
index 0000000000..d3765da043
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_qr_code_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5.5 3A2.5 2.5 0 0 0 3 5.5V9h1.75V5.5A0.75 0.75 0 0 1 5.5 4.75H9V3H5.5zm5.5 7.25A0.75 0.75 0 0 1 10.25 11h-2.5A0.75 0.75 0 0 1 7 10.25v-2.5A0.75 0.75 0 0 1 7.75 7h2.5A0.75 0.75 0 0 1 11 7.75v2.5zM17 15h-2v-2h2v-2h-2V9h2V7h-2v2h-2v2h2v2h-2v2h-2v-2H9v2H7v2h2v-2h2v2h2v-2h2v2h2v-2zM3 18.5V15h1.75v3.5c0 0.414 0.336 0.75 0.75 0.75H9V21H5.5A2.5 2.5 0 0 1 3 18.5zM15 3h3.5A2.5 2.5 0 0 1 21 5.5V9h-1.75V5.5a0.75 0.75 0 0 0-0.75-0.75H15V3zm6 15.5V15h-1.75v3.5a0.75 0.75 0 0 1-0.75 0.75H15V21h3.5a2.5 2.5 0 0 0 2.5-2.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_quality_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_quality_24.xml
new file mode 100644
index 0000000000..e087551b52
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_quality_24.xml
@@ -0,0 +1,17 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.042 13.996l3.457-3.46L14.262 9.3l-2.84 2.84-1.685-1.685L8.5 11.692l2.305 2.304a0.875 0.875 0 0 0 1.237 0z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13.732 2.674a2.449 2.449 0 0 0-3.463 0L8.774 4.17H6.66a2.448 2.448 0 0 0-2.448 2.448v2.114l-1.495 1.494a2.449 2.449 0 0 0 0 3.463l1.495 1.494v2.114a2.448 2.448 0 0 0 2.448 2.448h2.114l1.494 1.495a2.449 2.449 0 0 0 3.463 0l1.494-1.495h2.114a2.448 2.448 0 0 0 2.448-2.448v-2.114l1.494-1.494a2.446 2.446 0 0 0 0.002-3.463l-1.495-1.494V6.617a2.448 2.448 0 0 0-2.448-2.448h-2.114l-1.494-1.495zm-2.225 1.238a0.7 0.7 0 0 1 0.987 0l1.751 1.75a0.875 0.875 0 0 0 0.619 0.257h2.476c0.386 0 0.698 0.312 0.698 0.698v2.476c0 0.232 0.092 0.455 0.256 0.619l1.751 1.75a0.696 0.696 0 0 1 0 0.987l-1.752 1.752a0.875 0.875 0 0 0-0.256 0.619v2.476a0.698 0.698 0 0 1-0.698 0.698h-2.476a0.875 0.875 0 0 0-0.619 0.256l-1.75 1.751a0.7 0.7 0 0 1-0.988 0l-1.751-1.75a0.875 0.875 0 0 0-0.619-0.257H6.66a0.698 0.698 0 0 1-0.698-0.698V14.82a0.875 0.875 0 0 0-0.256-0.619l-1.751-1.75a0.7 0.7 0 0 1 0-0.988l1.75-1.751a0.875 0.875 0 0 0 0.257-0.619V6.617c0-0.386 0.312-0.698 0.698-0.698h2.476a0.875 0.875 0 0 0 0.619-0.256l1.752-1.751z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_24.xml
new file mode 100644
index 0000000000..6ee608ecfd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M7 3.75A0.75 0.75 0 0 0 6.25 4.5v14c0 0.414 0.336 0.75 0.75 0.75h10a0.75 0.75 0 0 0 0.75-0.75v-14A0.75 0.75 0 0 0 17 3.75H7zM4.5 4.5A2.5 2.5 0 0 1 7 2h10a2.5 2.5 0 0 1 2.5 2.5v14A2.5 2.5 0 0 1 17 21H7a2.5 2.5 0 0 1-2.5-2.5v-14z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.75 6.25h6.5V8h-6.5V6.25zm0 4h6.5V12h-6.5v-1.75zm0 4h3.972V16H8.75v-1.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_fill_24.xml
new file mode 100644
index 0000000000..f170cc57e7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reader_view_fill_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M4.5,4.5A2.5,2.5 0,0 1,7 2h10a2.5,2.5 0,0 1,2.5 2.5v14A2.5,2.5 0,0 1,17 21L7,21a2.5,2.5 0,0 1,-2.5 -2.5v-14zM8.75,6.25h6.5L15.25,8h-6.5L8.75,6.25zM8.75,10.25h6.5L15.25,12h-6.5v-1.75zM8.75,14.25h3.972L12.722,16L8.75,16v-1.75z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_24.xml
new file mode 100644
index 0000000000..632926fcbf
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#000"
+ android:pathData="M3 5.5A2.5 2.5 0 0 1 5.5 3h4.75a0.88 0.88 0 0 1 0.434 0.115L12 3.867l1.316-0.752A0.875 0.875 0 0 1 13.75 3h4.75A2.5 2.5 0 0 1 21 5.5v13a2.5 2.5 0 0 1-2.5 2.5h-4.518l-1.548 0.885a0.875 0.875 0 0 1-0.868 0L10.018 21H5.5A2.5 2.5 0 0 1 3 18.5v-13zm2.5-0.75A0.75 0.75 0 0 0 4.75 5.5v13c0 0.414 0.336 0.75 0.75 0.75h4.75a0.88 0.88 0 0 1 0.434 0.115L12 20.117l1.316-0.752a0.874 0.874 0 0 1 0.434-0.115h4.75a0.75 0.75 0 0 0 0.75-0.75v-13a0.75 0.75 0 0 0-0.75-0.75h-4.518l-1.548 0.885a0.875 0.875 0 0 1-0.868 0L10.018 4.75H5.5z" />
+ <path
+ android:fillColor="#000"
+ android:pathData="M12 13H7v-1.75h5V13zm-1 4H7v-1.75h4V17zm1-8H7V7.25h5V9z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_add_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_add_24.xml
new file mode 100644
index 0000000000..13e979a615
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reading_list_add_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11 21a0.87 0.87 0 0 1-0.434-0.115L9.018 20H4.5A2.503 2.503 0 0 1 2 17.5v-13C2 3.121 3.122 2 4.5 2h4.75a0.88 0.88 0 0 1 0.434 0.115L11 2.867l1.316-0.752A0.88 0.88 0 0 1 12.75 2h4.75C18.878 2 20 3.121 20 4.5V13h-1.75V4.5a0.75 0.75 0 0 0-0.75-0.75h-4.518l-1.548 0.885a0.873 0.873 0 0 1-0.868 0L9.018 3.75H4.5A0.75 0.75 0 0 0 3.75 4.5v13c0 0.413 0.336 0.75 0.75 0.75h4.75a0.88 0.88 0 0 1 0.434 0.115L11 19.117l1.316-0.752a0.88 0.88 0 0 1 0.434-0.115H13v1.746l-1.566 0.889A0.87 0.87 0 0 1 11 21zm9-2.75V15h-1.75v3.25H15V20h3.25v3H20v-3h3v-1.75h-3z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6 12h5v-1.75H6V12zm4 4H6v-1.75h4V16zM6 8h5V6.25H6V8z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reorder.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reorder.xml
new file mode 100644
index 0000000000..0be284c3ff
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_reorder.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0">
+ <path android:pathData="M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z" android:fillColor="@color/mozac_ui_icons_fill"/>
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket.xml
new file mode 100644
index 0000000000..248a5018d5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:autoMirrored="true"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M22,3a1,1 0,0 0,-1 -1C16.3,2 10.873,5.66 7.089,10H4a1,1 0,0 0,-0.895 0.553l-1,2a1,1 0,0 0,0.579 1.395l1.67,0.557a1,1 0,0 0,0.111 0.212,21.8 21.8,0 0,0 4.818,4.818 0.791,0.791 0,0 0,0.082 0.042l0.7,1.789a1,1 0,0 0,1.378 0.529l2,-1A1,1 0,0 0,14 20V16.911C18.34,13.127 22,7.705 22,3ZM12.326,15.729A24.182,24.182 0,0 1,9.909 17.5,19.674 19.674,0 0,1 6.5,14.09a24.65,24.65 0,0 1,1.761 -2.4C11.623,7.659 16.23,4.6 19.921,4.079 19.4,7.765 16.349,12.365 12.326,15.729Z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M17.33,7.578a4.906,4.906 0,0 0,-0.915 -0.913,0.416 0.416,0 0,0 -0.378,-0.061A10.162,10.162 0,0 0,13.829 7.92a0.417,0.417 0,0 0,-0.041 0.625l1.667,1.667a0.42,0.42 0,0 0,0.295 0.121h0.029a0.414,0.414 0,0 0,0.3 -0.164,11.312 11.312,0 0,0 1.309,-2.189A0.422,0.422 0,0 0,17.33 7.578Z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket_filled.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket_filled.xml
new file mode 100644
index 0000000000..f10710664d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_rocket_filled.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:autoMirrored="true"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6.623,19.222a10.637,10.637 0,0 1,-2.548 0.7,10.637 10.637,0 0,1 0.7,-2.548 1,1 0,1 0,-1.851 -0.754A11.638,11.638 0,0 0,2 21a1,1 0,0 0,1 1,11.638 11.638,0 0,0 4.377,-0.927 1,1 0,1 0,-0.754 -1.851Z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.411,10L4,10a1,1 0,0 0,-0.895 0.553l-1,2a1,1 0,0 0,0.579 1.395l3,1a1,1 0,0 0,0.27 0.045,20.877 20.877,0 0,0 3,3.011 1,1 0,0 0,0.032 0.612l1.083,2.75a1,1 0,0 0,1.378 0.529l2,-1A1,1 0,0 0,14 20L14,15.589C17.968,11.922 21,7.029 21,3 16.971,3 12.078,6.032 8.411,10ZM14.083,8.25A9.92,9.92 0,0 1,16.167 7,4.48 4.48,0 0,1 17,7.833a11.121,11.121 0,0 1,-1.25 2.084Z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_24.xml
new file mode 100644
index 0000000000..9c821755e0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6,4.5A2.5,2.5 0,0 1,8.5 2h8A2.5,2.5 0,0 1,19 4.5v15.625a0.875,0.875 0,0 1,-1.315 0.756L12.5,17.863 7.315,20.88A0.875,0.875 0,0 1,6 20.125L6,4.5zM8.5,3.75a0.75,0.75 0,0 0,-0.75 0.75v14.103l4.31,-2.51a0.875,0.875 0,0 1,0.88 0l4.31,2.51L17.25,4.5a0.75,0.75 0,0 0,-0.75 -0.75h-8z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_file_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_file_24.xml
new file mode 100644
index 0000000000..e9c274bfc8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_save_file_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2,4.5A2.5,2.5 0,0 1,4.5 2h7c0.232,0 0.455,0.092 0.619,0.256l4.625,4.625A0.875,0.875 0,0 1,17 7.5V11h-1.75V8.5H11.5a1,1 0,0 1,-1 -1V3.75h-6a0.75,0.75 0,0 0,-0.75 0.75v14c0,0.414 0.336,0.75 0.75,0.75H13V21H4.5A2.5,2.5 0,0 1,2 18.5v-14zM19,13h-1.75v4h-1.612a0.756,0.756 0,0 0,-0.535 1.291l2.487,2.487a0.757,0.757 0,0 0,1.07 0l2.487,-2.487A0.756,0.756 0,0 0,20.612 17H19v-4z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_search_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_search_24.xml
new file mode 100644
index 0000000000..370db05187
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_search_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10 3a7 7 0 1 0 4.292 12.53L19.763 21l1.238-1.238-5.471-5.47A7 7 0 0 0 10 3zm-5.25 7a5.25 5.25 0 1 1 10.5 0 5.25 5.25 0 0 1-10.5 0z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_select_all.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_select_all.xml
new file mode 100644
index 0000000000..1445bed499
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_select_all.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M15.222,22L5.778,22A3.778,3.778 0,0 1,2 18.222L2,8.778A3.778,3.778 0,0 1,5.778 5h9.444A3.778,3.778 0,0 1,19 8.778v9.444A3.778,3.778 0,0 1,15.222 22zM5.857,7A1.857,1.857 0,0 0,4 8.857v9.286C4,19.169 4.831,20 5.857,20h9.286A1.857,1.857 0,0 0,17 18.143L17,8.857A1.857,1.857 0,0 0,15.143 7L5.857,7zM6,4a2,2 0,0 1,2 -2h7.987a6,6 0,0 1,6 6v0.016l-0.024,7.987a2,2 0,0 1,-2.006 1.994l0.03,-9.986L19.987,8a4,4 0,0 0,-4 -4L6,4zM14.284,9.752a1,1 0,0 1,1.432 1.396l-5.95,6.1a1,1 0,0 1,-1.429 0.003l-3.05,-3.1a1,1 0,0 1,1.426 -1.402l2.334,2.372 5.237,-5.37z"
+ android:fillColor="@color/mozac_ui_icons_fill" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_settings_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_settings_24.xml
new file mode 100644
index 0000000000..ce46e1f161
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_settings_24.xml
@@ -0,0 +1,17 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.25 12c0-2.07 1.68-3.75 3.75-3.75 2.07 0 3.75 1.68 3.75 3.75 0 2.07-1.68 3.75-3.75 3.75-2.07 0-3.75-1.68-3.75-3.75zM14 12c0-1.1-0.9-2-2-2s-2 0.9-2 2 0.9 2 2 2 2-0.9 2-2z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M9.19 20.46c0.26 0.91 1.1 1.54 2.05 1.54h1.52l0.05 0.02c0.94 0 1.78-0.63 2.05-1.53l0.51-1.72c0.28-0.15 0.57-0.32 0.87-0.53l1.73 0.43c0.92 0.24 1.89-0.18 2.36-1l0.76-1.31c0.47-0.82 0.35-1.86-0.3-2.54l-1.25-1.32c0.02-0.16 0.03-0.32 0.03-0.49 0-0.18-0.02-0.35-0.04-0.52l1.23-1.28c0.65-0.68 0.78-1.73 0.31-2.55l-0.76-1.31a2.157 2.157 0 0 0-2.35-1.01l-1.77 0.42c-0.29-0.2-0.57-0.37-0.85-0.51l-0.51-1.72C14.56 2.63 13.72 2 12.78 2h-1.51c-0.95 0-1.79 0.63-2.05 1.54L8.73 5.23C8.44 5.37 8.15 5.55 7.85 5.75L6.08 5.33C5.16 5.11 4.2 5.53 3.73 6.34L2.97 7.65C2.49 8.47 2.62 9.52 3.28 10.2l1.23 1.28C4.48 11.65 4.47 11.82 4.47 12c0 0.17 0.01 0.33 0.03 0.49l-1.25 1.32c-0.65 0.68-0.77 1.73-0.3 2.54l0.76 1.31c0.47 0.82 1.44 1.23 2.36 1l1.73-0.43c0.3 0.21 0.6 0.39 0.9 0.54l0.49 1.69zm-0.67-3.88a0.85 0.85 0 0 0-0.53-0.18L8 16.42c-0.07 0-0.14 0.01-0.21 0.03l-2.13 0.53a0.376 0.376 0 0 1-0.42-0.18l-0.76-1.31a0.376 0.376 0 0 1 0.05-0.46l1.54-1.62A0.88 0.88 0 0 0 6.3 12.7l-0.03-0.22-0.003-0.027A3.501 3.501 0 0 1 6.23 12.01c0-0.127 0.017-0.255 0.034-0.383L6.28 11.5l0.03-0.2a0.897 0.897 0 0 0-0.24-0.72L4.54 9a0.395 0.395 0 0 1-0.06-0.46l0.76-1.31a0.37 0.37 0 0 1 0.42-0.18l2.16 0.52c0.25 0.06 0.52 0.01 0.73-0.15 0.43-0.33 0.83-0.56 1.23-0.73 0.24-0.11 0.43-0.31 0.5-0.57l0.6-2.08c0.05-0.17 0.2-0.28 0.37-0.28h1.51c0.17 0 0.32 0.11 0.37 0.27l0.62 2.1c0.08 0.25 0.26 0.46 0.5 0.56 0.39 0.16 0.77 0.39 1.21 0.72 0.21 0.15 0.48 0.21 0.73 0.15l2.16-0.52c0.17-0.04 0.34 0.03 0.42 0.18l0.76 1.31c0.08 0.15 0.06 0.34-0.06 0.46l-1.53 1.58c-0.19 0.19-0.27 0.46-0.24 0.72l0.03 0.2 0.017 0.13c0.017 0.124 0.033 0.246 0.033 0.38 0 0.16-0.02 0.32-0.04 0.47l-0.03 0.22c-0.04 0.26 0.05 0.52 0.23 0.71l1.54 1.62c0.11 0.13 0.14 0.31 0.05 0.46l-0.76 1.31c-0.08 0.15-0.26 0.22-0.42 0.18l-2.13-0.53a0.852 0.852 0 0 0-0.74 0.15c-0.45 0.34-0.84 0.58-1.23 0.74-0.24 0.1-0.43 0.31-0.5 0.56l-0.62 2.1c-0.05 0.16-0.2 0.27-0.37 0.27h-1.52c-0.17 0-0.32-0.12-0.37-0.28l-0.6-2.08a0.84 0.84 0 0 0-0.5-0.57c-0.4-0.17-0.81-0.42-1.25-0.75z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_android_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_android_24.xml
new file mode 100644
index 0000000000..426216f346
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_android_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M14 6.5a3.5 3.5 0 1 1 0.947 2.395l-5.052 2.251a3.507 3.507 0 0 1-0.003 1.72l5.047 2.248a3.5 3.5 0 1 1-0.837 1.543l-5.058-2.253a3.5 3.5 0 1 1 0.009-4.798l5.052-2.252A3.505 3.505 0 0 1 14 6.5zm3.5-1.75a1.75 1.75 0 1 0 0 3.5 1.75 1.75 0 0 0 0-3.5zm-11 5.5a1.75 1.75 0 1 0 0 3.5 1.75 1.75 0 0 0 0-3.5zm9.25 7.25a1.75 1.75 0 1 1 3.5 0 1.75 1.75 0 0 1-3.5 0z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_apple_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_apple_24.xml
new file mode 100644
index 0000000000..993051d08a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_share_apple_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 3c0.232 0 0.455 0.092 0.619 0.256l5.38 5.382-1.237 1.237-3.887-3.887V18h-1.75V5.987L7.237 9.875 6 8.638l5.381-5.382A0.875 0.875 0 0 1 12 3z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5 17v2.5c0 0.414 0.336 0.75 0.75 0.75h12.5A0.75 0.75 0 0 0 19 19.5V17h1.75v2.5a2.5 2.5 0 0 1-2.5 2.5H5.75a2.5 2.5 0 0 1-2.5-2.5V17H5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_24.xml
new file mode 100644
index 0000000000..47b961d4d1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 22a3 3 0 0 1-1.46-0.38c-2.08-1.16-3.99-2.96-5.39-5.08-0.71-1.08-1.21-2.38-1.49-3.89L2.95 8.8C2.71 7.52 3.33 6.24 4.47 5.62l6.02-3.26a3 3 0 0 1 2.85 0l6.17 3.32c1.15 0.62 1.77 1.9 1.53 3.19l-0.71 3.79c-0.28 1.5-0.78 2.8-1.48 3.87-1.4 2.12-3.31 3.92-5.39 5.09C13.01 21.87 12.5 22 12 22zM11.92 3.75c-0.2 0-0.41 0.05-0.59 0.15L5.31 7.16C4.83 7.42 4.58 7.95 4.68 8.49l0.71 3.85c0.23 1.27 0.65 2.36 1.23 3.24 1.24 1.88 2.94 3.49 4.78 4.52 0.38 0.21 0.84 0.21 1.22 0 1.84-1.03 3.54-2.63 4.78-4.52 0.58-0.88 0.99-1.96 1.22-3.23l0.71-3.79c0.1-0.54-0.16-1.07-0.64-1.33l-6.17-3.32c-0.19-0.1-0.39-0.15-0.59-0.15l-0.01-0.01z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_slash_24.xml
new file mode 100644
index 0000000000..9d2077dcad
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shield_slash_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.692 5.327L11.328 3.9a1.26 1.26 0 0 1 1.187-0.001l6.174 3.322c0.48 0.259 0.736 0.792 0.637 1.328l-0.705 3.793a9.696 9.696 0 0 1-0.688 2.224l1.307 1.307c0.503-0.934 0.878-2.006 1.102-3.211l0.705-3.794a2.988 2.988 0 0 0-1.528-3.188l-6.174-3.322a2.993 2.993 0 0 0-2.849 0.003L7.401 4.035l1.291 1.292z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M18.409 17.171l3.59 3.591L20.763 22l-3.465-3.466c-1.134 1.248-2.445 2.31-3.831 3.085a3.005 3.005 0 0 1-1.464 0.378 3.005 3.005 0 0 1-1.464-0.378c-2.08-1.161-3.992-2.965-5.388-5.079-0.71-1.075-1.21-2.384-1.487-3.888L2.954 8.8a2.991 2.991 0 0 1 1.46-3.148L2 3.238 3.238 2 6.02 4.783 6.025 4.78l1.29 1.291-0.004 0.003 9.834 9.833 0.003-0.004 1.264 1.264-0.003 0.004zm-2.358 0.117L5.704 6.943 5.308 7.157a1.248 1.248 0 0 0-0.635 1.326l0.709 3.852c0.235 1.272 0.647 2.362 1.227 3.24 1.244 1.886 2.942 3.49 4.78 4.517a1.27 1.27 0 0 0 1.222 0c1.248-0.698 2.423-1.666 3.438-2.804z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shipping_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shipping_24.xml
new file mode 100644
index 0000000000..67ac9492d1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shipping_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M15.227 18.75A2.996 2.996 0 0 0 17.664 20a2.996 2.996 0 0 0 2.437-1.25h0.275c0.897 0 1.625-0.728 1.625-1.625V11.7a0.875 0.875 0 0 0-0.117-0.437l-2.203-3.825A0.875 0.875 0 0 0 18.923 7h-3.23a2.501 2.501 0 0 0-2.486-2.233H4.5a2.5 2.5 0 0 0-2.5 2.5v8.983c0 1.151 0.778 2.12 1.837 2.411A2.997 2.997 0 0 0 6.336 20a2.996 2.996 0 0 0 2.437-1.25h6.454zM4.5 6.517a0.75 0.75 0 0 0-0.75 0.75v8.211A3 3 0 0 1 9.336 17h4.621V7.267a0.75 0.75 0 0 0-0.75-0.75H4.5zM15.707 12h4.544v-0.066L18.417 8.75h-2.71V12zM5.086 17a1.25 1.25 0 1 1 2.5 0 1.25 1.25 0 0 1-2.5 0zm11.328 0a1.25 1.25 0 1 1 2.5 0 1.25 1.25 0 0 1-2.5 0z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shopping_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shopping_24.xml
new file mode 100644
index 0000000000..662fb38991
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_shopping_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13.452 2H6v1.75h7.088l6.629 6.656 1.24-1.234-6.885-6.914A0.875 0.875 0 0 0 13.452 2zM8.933 12.379l1.414-1.415L8.933 9.55l-1.415 1.414 1.415 1.415z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3.5 6.375C3.5 5.892 3.892 5.5 4.375 5.5h7.265c0.232 0 0.455 0.092 0.619 0.256l6.735 6.735a2.5 2.5 0 0 1 0 3.536l-5.215 5.215a2.5 2.5 0 0 1-3.536 0l-6.487-6.487A0.875 0.875 0 0 1 3.5 14.136V6.375zM5.25 7.25v6.524l6.23 6.23a0.75 0.75 0 0 0 1.061 0l5.215-5.215a0.75 0.75 0 0 0 0-1.06L11.278 7.25H5.25z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_social_tracker_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_social_tracker_24.xml
new file mode 100644
index 0000000000..8ed2638b8a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_social_tracker_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M5.25 16h-2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1zm13.686 1a2.5 2.5 0 0 0 2.372-3.291l-2.083-6.25a2.5 2.5 0 0 0-2.372-1.709H8v9.164l2.009 3.064c0.118 0.18 0.213 0.375 0.281 0.58l0.951 2.852c0.117 0.352 0.447 0.59 0.818 0.59h0.003a1.874 1.874 0 0 0 1.875-1.875V17h4.999z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sparkle_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sparkle_24.xml
new file mode 100644
index 0000000000..71ae38b99e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sparkle_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.837 17.376l0.232-1.08c0.11-0.512 0.84-0.512 0.95 0l0.232 1.08c0.04 0.187 0.186 0.333 0.373 0.373l1.08 0.232c0.512 0.11 0.512 0.84 0 0.95l-1.08 0.232a0.485 0.485 0 0 0-0.373 0.373l-0.232 1.08c-0.11 0.512-0.84 0.512-0.95 0l-0.232-1.08a0.485 0.485 0 0 0-0.373-0.373l-1.08-0.232c-0.512-0.11-0.512-0.84 0-0.95l1.08-0.232a0.485 0.485 0 0 0 0.373-0.373zm0-12.912l0.232-1.08c0.11-0.512 0.84-0.512 0.95 0l0.232 1.08c0.04 0.187 0.186 0.333 0.373 0.373l1.08 0.232c0.512 0.11 0.512 0.84 0 0.95l-1.08 0.232a0.485 0.485 0 0 0-0.373 0.373l-0.232 1.08c-0.11 0.512-0.84 0.512-0.95 0l-0.232-1.08a0.485 0.485 0 0 0-0.373-0.373l-1.08-0.232c-0.512-0.11-0.512-0.84 0-0.95l1.08-0.232a0.485 0.485 0 0 0 0.373-0.373z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M14.16 6.981l-1.034 2.623a2.707 2.707 0 0 1-1.52 1.522L8.98 12.161a0.365 0.365 0 0 0 0 0.679l2.623 1.034a2.703 2.703 0 0 1 1.522 1.522l1.034 2.623a0.365 0.365 0 0 0 0.679 0l1.034-2.623a2.703 2.703 0 0 1 1.522-1.522l2.622-1.034a0.366 0.366 0 0 0 0-0.68l-2.622-1.034a2.703 2.703 0 0 1-1.522-1.522L14.84 6.981a0.365 0.365 0 0 0-0.679 0zm-1.628-0.642c0.704-1.786 3.23-1.786 3.935 0l1.034 2.623c0.097 0.245 0.29 0.44 0.536 0.536l2.622 1.034c1.786 0.704 1.786 3.232 0 3.936l-2.622 1.034a0.952 0.952 0 0 0-0.536 0.536l-1.034 2.623c-0.704 1.785-3.23 1.786-3.935 0l-1.034-2.623a0.952 0.952 0 0 0-0.536-0.536L8.34 14.468c-1.785-0.704-1.786-3.23 0-3.935L10.96 9.5a0.959 0.959 0 0 0 0.538-0.538l1.034-2.623z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_fill_20.xml
new file mode 100644
index 0000000000..a8c7f438ce
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_fill_20.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6.741 16a0.982 0.982 0 0 1-0.579-0.189 0.98 0.98 0 0 1-0.375-1.04l0.798-3.132-2.487-2.066a0.979 0.979 0 0 1-0.307-1.062 0.98 0.98 0 0 1 0.873-0.679L7.89 7.623 9.086 4.62A0.978 0.978 0 0 1 10 4a0.98 0.98 0 0 1 0.915 0.621l1.196 3.003 3.226 0.209a0.979 0.979 0 0 1 0.873 0.679 0.978 0.978 0 0 1-0.309 1.061l-2.486 2.064 0.798 3.133a0.981 0.981 0 0 1-0.375 1.04 0.98 0.98 0 0 1-1.105 0.036L10 14.119l-2.732 1.727A0.984 0.984 0 0 1 6.741 16z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_half_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_half_fill_20.xml
new file mode 100644
index 0000000000..fa35cd5990
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_half_fill_20.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10 14.119l-2.732 1.727a0.984 0.984 0 0 1-1.481-1.075l0.798-3.132-2.487-2.066a0.979 0.979 0 0 1-0.307-1.062 0.98 0.98 0 0 1 0.873-0.679L7.89 7.623 9.086 4.62A0.978 0.978 0 0 1 10 4v10.119z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_one_half_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_one_half_fill_20.xml
new file mode 100644
index 0000000000..c3871dcb8f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_star_one_half_fill_20.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="@color/mozac_ic_star_unfilled"
+ android:pathData="M6.741 16a0.982 0.982 0 0 1-0.579-0.189 0.98 0.98 0 0 1-0.375-1.04l0.798-3.132-2.487-2.066a0.979 0.979 0 0 1-0.307-1.062 0.98 0.98 0 0 1 0.873-0.679L7.89 7.623 9.086 4.62A0.978 0.978 0 0 1 10 4a0.98 0.98 0 0 1 0.915 0.621l1.196 3.003 3.226 0.209a0.979 0.979 0 0 1 0.873 0.679 0.978 0.978 0 0 1-0.309 1.061l-2.486 2.064 0.798 3.133a0.981 0.981 0 0 1-0.375 1.04 0.98 0.98 0 0 1-1.105 0.036L10 14.119l-2.732 1.727A0.984 0.984 0 0 1 6.741 16z" />
+ <path
+ android:fillColor="@color/mozac_ic_star_filled"
+ android:pathData="M10 14.119l-2.732 1.727a0.984 0.984 0 0 1-1.481-1.075l0.798-3.132-2.487-2.066a0.979 0.979 0 0 1-0.307-1.062 0.98 0.98 0 0 1 0.873-0.679L7.89 7.623 9.086 4.62A0.978 0.978 0 0 1 10 4v10.119z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_stop.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_stop.xml
new file mode 100644
index 0000000000..cbc5269212
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_stop.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M10.367,12.573 L4.22,18.72a0.75,0.75 0,1 0,1.06 1.06l6.156,-6.156h1.127l6.156,6.156a0.748,0.748 0,0 0,1.06 0,0.75 0.75,0 0,0 0,-1.061l-6.147,-6.147 0.001,-1.146L19.78,5.28a0.75,0.75 0,1 0,-1.061 -1.061l-6.156,6.156h-1.128L5.28,4.22a0.75,0.75 0,1 0,-1.061 1.061l6.146,6.146 0.002,1.146z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_24.xml
new file mode 100644
index 0000000000..0b0408778e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.5 7.75A0.75 0.75 0 0 0 3.75 8.5v7c0 0.414 0.336 0.75 0.75 0.75h15a0.75 0.75 0 0 0 0.75-0.75v-7a0.75 0.75 0 0 0-0.75-0.75h-15zM2 8.5A2.5 2.5 0 0 1 4.5 6h15A2.5 2.5 0 0 1 22 8.5v7a2.5 2.5 0 0 1-2.5 2.5h-15A2.5 2.5 0 0 1 2 15.5v-7z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.5 10.75H6v2.5h2.5v-2.5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_slash_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_slash_24.xml
new file mode 100644
index 0000000000..6efcb91aef
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_storage_slash_24.xml
@@ -0,0 +1,24 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6 11h2.25v2.25H6V11z"
+ tools:ignore="VectorRaster" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M22 20.752L3.238 1.99 2 3.228 4.773 6H4.5A2.502 2.502 0 0 0 2 8.5v7C2 16.879 3.121 18 4.5 18h12.273l3.99 3.99L22 20.752zm-6.977-4.502l-8.5-8.5H4.5A0.752 0.752 0 0 0 3.75 8.5v7c0 0.413 0.337 0.75 0.75 0.75h10.523z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.109 7.75H19.5c0.413 0 0.75 0.337 0.75 0.75v7a0.744 0.744 0 0 1-0.659 0.732l1.325 1.325A2.497 2.497 0 0 0 22 15.5v-7C22 7.121 20.879 6 19.5 6H9.359l1.75 1.75z"
+ tools:ignore="VectorRaster" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_24.xml
new file mode 100644
index 0000000000..8b4e07514e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M4.75 12.03c0-3.998 3.252-7.25 7.25-7.25 0.028 0 0.055 0.006 0.083 0.006v2.163c0 0.49 0.592 0.735 0.939 0.389l2.949-2.949a0.55 0.55 0 0 0 0-0.778l-2.949-2.949a0.55 0.55 0 0 0-0.939 0.389v1.985c-0.028 0-0.055-0.006-0.083-0.006-4.963 0-9 4.037-9 9a8.983 8.983 0 0 0 3.236 6.904L7.48 17.69a7.239 7.239 0 0 1-2.73-5.66zm12.977-6.937l-1.248 1.248a7.237 7.237 0 0 1 2.771 5.69c0 3.998-3.252 7.25-7.25 7.25-0.028 0-0.055-0.006-0.083-0.007v-2.223a0.55 0.55 0 0 0-0.939-0.389l-2.949 2.949a0.55 0.55 0 0 0 0 0.778l2.949 2.949a0.55 0.55 0 0 0 0.939-0.389v-1.922c0.028 0 0.055 0.003 0.083 0.003 4.963 0 9-4.037 9-9a8.984 8.984 0 0 0-3.273-6.937z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_tabs_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_tabs_24.xml
new file mode 100644
index 0000000000..5e776b729e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_sync_tabs_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M0 4.75a2.5 2.5 0 0 1 2.5-2.5h8a2.5 2.5 0 0 1 2.5 2.5v4.5a2.5 2.5 0 0 1-2.5 2.5h-8A2.5 2.5 0 0 1 0 9.25v-4.5zM2.5 4a0.75 0.75 0 0 0-0.75 0.75v4.5C1.75 9.664 2.086 10 2.5 10h7.75V4H2.5z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M20.275 7.75H14.75V6h5.525a2.5 2.5 0 0 1 2.5 2.5v9.75c0 0.818-0.393 1.544-1 2H24V22H2v-1.75h3.25a2.497 2.497 0 0 1-1-2V13.5H6v4.75C6 18.664 6.336 19 6.75 19h13.525a0.75 0.75 0 0 0 0.75-0.75V8.5a0.75 0.75 0 0 0-0.75-0.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab.xml
new file mode 100644
index 0000000000..8be248636b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="16"
+ android:viewportWidth="16">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M15,11h-1V5a2,2 0,0 0,-2 -2H4a2,2 0,0 0,-2 2v6H1a1,1 0,0 0,0 2h14a1,1 0,1 0,0 -2z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_badge_fill_20.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_badge_fill_20.xml
new file mode 100644
index 0000000000..f99ada90d9
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_badge_fill_20.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:fillColor="#fff"
+ android:pathData="M14.75 5c0.966 0 1.75 0.784 1.75 1.75v6.5A1.75 1.75 0 0 1 14.75 15h-9.5a1.75 1.75 0 0 1-1.75-1.75v-6.5C3.5 5.784 4.284 5 5.25 5h9.5zm0-1.5h-9.5A3.254 3.254 0 0 0 2 6.75v6.5a3.254 3.254 0 0 0 3.25 3.25h9.5A3.254 3.254 0 0 0 18 13.25v-6.5a3.254 3.254 0 0 0-3.25-3.25z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M14.75 5h-9.5A1.75 1.75 0 0 0 3.5 6.75v6.5C3.5 14.216 4.284 15 5.25 15h9.5a1.75 1.75 0 0 0 1.75-1.75v-6.5A1.75 1.75 0 0 0 14.75 5z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_new.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_new.xml
new file mode 100644
index 0000000000..8822eb5979
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_new.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="16"
+ android:viewportWidth="16">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11,11L11,9a1,1 0,0 1,1 -1h1a1,1 0,0 1,1 1L14,5a2,2 0,0 0,-2 -2L4,3a2,2 0,0 0,-2 2v6L1,11a1,1 0,0 0,0 2h7v-1a1,1 0,0 1,1 -1zM15.5,12L13,12L13,9.5a0.5,0.5 0,0 0,-1 0L12,12L9.5,12a0.5,0.5 0,0 0,0 1L12,13v2.5a0.5,0.5 0,0 0,1 0L13,13h2.5a0.5,0.5 0,0 0,0 -1z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_number_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_number_24.xml
new file mode 100644
index 0000000000..30b357c61c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_number_24.xml
@@ -0,0 +1,17 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 6.5A2.5 2.5 0 0 1 4.5 4h15A2.5 2.5 0 0 1 22 6.5v10a2.5 2.5 0 0 1-2.5 2.5h-15A2.5 2.5 0 0 1 2 16.5v-10zm2.5-0.75A0.75 0.75 0 0 0 3.75 6.5v10c0 0.414 0.336 0.75 0.75 0.75h15a0.75 0.75 0 0 0 0.75-0.75v-10a0.75 0.75 0 0 0-0.75-0.75h-15z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M8.641 15.1c1.64 0 2.82-0.878 2.823-2.057-0.003-0.909-0.703-1.651-1.576-1.797v-0.05a1.633 1.633 0 0 0 1.306-1.611c-0.003-1.126-1.083-1.957-2.553-1.957-1.473 0-2.553 0.83-2.55 1.957a1.615 1.615 0 0 0 1.307 1.612v0.05c-0.887 0.145-1.58 0.887-1.576 1.796C5.818 14.223 7 15.1 8.642 15.1zm0-1.13c-0.731 0-1.221-0.433-1.221-1.047 0-0.629 0.515-1.084 1.221-1.084 0.703 0 1.222 0.455 1.222 1.084 0 0.617-0.494 1.047-1.222 1.047zm0-3.25c-0.614 0-1.05-0.4-1.05-0.976 0-0.568 0.429-0.958 1.05-0.958 0.618 0 1.051 0.394 1.051 0.958 0 0.576-0.44 0.977-1.05 0.977zm6.712 4.38c1.64 0 2.82-0.878 2.823-2.057-0.004-0.909-0.703-1.651-1.577-1.797v-0.05a1.633 1.633 0 0 0 1.307-1.611c-0.004-1.126-1.083-1.957-2.553-1.957-1.474 0-2.554 0.83-2.55 1.957a1.615 1.615 0 0 0 1.307 1.612v0.05c-0.888 0.145-1.58 0.887-1.577 1.796-0.004 1.18 1.179 2.056 2.82 2.056zm0-1.13c-0.732 0-1.222-0.433-1.222-1.047 0-0.629 0.515-1.084 1.222-1.084 0.703 0 1.221 0.455 1.221 1.084 0 0.617-0.494 1.047-1.221 1.047zm0-3.25c-0.615 0-1.052-0.4-1.052-0.976 0-0.568 0.43-0.958 1.052-0.958 0.617 0 1.05 0.394 1.05 0.958 0 0.576-0.44 0.977-1.05 0.977z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_tray_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_tray_24.xml
new file mode 100644
index 0000000000..43e6db826f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tab_tray_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M2 4.5A2.5 2.5 0 0 1 4.5 2h15A2.5 2.5 0 0 1 22 4.5v10a2.5 2.5 0 0 1-2.5 2.5h-15A2.5 2.5 0 0 1 2 14.5v-10zm2.5-0.75A0.75 0.75 0 0 0 3.75 4.5v10c0 0.414 0.336 0.75 0.75 0.75h15a0.75 0.75 0 0 0 0.75-0.75v-10a0.75 0.75 0 0 0-0.75-0.75h-15zm0 17.75A2.5 2.5 0 0 1 2 19h1.75c0 0.414 0.336 0.75 0.75 0.75h15A0.75 0.75 0 0 0 20.25 19H22a2.5 2.5 0 0 1-2.5 2.5h-15z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_themes_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_themes_24.xml
new file mode 100644
index 0000000000..180523e4c2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_themes_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M18 10V3.5C18 3.22 17.78 3 17.5 3h-11C6.22 3 6 3.22 6 3.5V10H5c-0.28 0-0.5 0.22-0.5 0.5v3A2.5 2.5 0 0 0 7 16h3v4.5c0 0.83 0.67 1.5 1.5 1.5h1c0.83 0 1.5-0.67 1.5-1.5V16h3a2.5 2.5 0 0 0 2.5-2.5v-3c0-0.28-0.22-0.5-0.5-0.5h-1zM7.75 10h8.51V5.37h-0.57l-1.22 1.14c-0.37 0.35-0.94 0.34-1.3-0.02l-1.12-1.12h-0.83l-0.77 0.64c-0.39 0.33-0.96 0.28-1.3-0.09L8.09 4.75H7.75V10z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tool_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tool_24.xml
new file mode 100644
index 0000000000..78cea3d700
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tool_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M13.11,22h-2.22a2.68,2.68 0,0 1,-2.68 -2.68v-6.14C6.08,11.67 5.05,9.11 5.58,6.5c0.37,-1.85 1.55,-3.44 3.23,-4.38l0.43,-0.21a0.879,0.879 0,0 1,1.26 0.77l0.05,4.07c0,0.5 0.42,0.91 0.93,0.91h1.07c0.51,0 0.93,-0.42 0.93,-0.93V2.7c0,-0.3 0.16,-0.58 0.41,-0.74a0.86,0.86 0,0 1,0.85 -0.04l0.41,0.2c2.12,1.18 3.41,3.37 3.41,5.74 0,2.14 -1.03,4.1 -2.77,5.33v6.14c0,1.48 -1.2,2.68 -2.68,2.68V22zM8.77,4.29c-0.74,0.67 -1.28,1.58 -1.48,2.56 -0.41,2.04 0.47,4.04 2.25,5.11 0.26,0.16 0.42,0.44 0.42,0.75v6.61c0,0.51 0.42,0.93 0.93,0.93h2.22c0.51,0 0.93,-0.42 0.93,-0.93v-6.61c0,-0.31 0.16,-0.59 0.42,-0.75 1.47,-0.88 2.35,-2.42 2.35,-4.11 0,-1.36 -0.58,-2.65 -1.58,-3.55v2.44c0,1.48 -1.2,2.68 -2.68,2.68h-1.07c-1.46,0 -2.66,-1.18 -2.68,-2.64l-0.03,-2.49z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_translate_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_translate_24.xml
new file mode 100644
index 0000000000..7fd0e1d3a1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_translate_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M20.144 22H22l-4.716-11.383A1 1 0 0 0 16.36 10h-0.846c-0.404 0-0.769 0.244-0.924 0.617l-2.352 5.677c-0.677-0.35-1.327-0.761-1.909-1.275a16.962 16.962 0 0 1-1.374-1.36 18.85 18.85 0 0 0 3.773-6.66h0.983V5.25H8.71V3H7.002v2.25H2V7h8.931a17.079 17.079 0 0 1-3.07 5.297A17.047 17.047 0 0 1 5.859 8.75H4.033a18.988 18.988 0 0 0 2.621 4.811c-0.16 0.153-0.315 0.311-0.482 0.458a9.258 9.258 0 0 1-3.195 1.83v1.826a10.96 10.96 0 0 0 4.31-2.33c0.163-0.144 0.313-0.298 0.471-0.446 0.459 0.505 0.941 0.992 1.458 1.447a10.995 10.995 0 0 0 2.347 1.583L9.875 22h1.856l1.346-3.25h5.721L20.144 22zm-6.342-5l2.135-5.155L18.073 17h-4.271z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tree.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tree.xml
new file mode 100644
index 0000000000..305131d365
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_tree.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M0.7,18c0,4.9,3.6,8.8,8.1,9.5v4.3c0.2,0,3.2,0,3.2,0v-4.3c1.8-0.4,3.6-1.1,4.9-2.5c0.2-0.2,0.2-0.2,0.2-0.5
+ c-0.2-0.4-0.2-1.1-0.2-1.6c0-2,0.2-4.9,1.6-7.9c0,0,0.9-1.6,0.7-1.8C18,7.2,14.4,0,10.4,0C5,0,0.7,12.6,0.7,18z M18.3,22.8
+ c0,3.1,2.2,5.6,4.9,6.3V32h3.2v-2.9c2.7-0.7,4.9-3.2,4.9-6.3c0-3.6-2.9-12.9-6.5-12.9S18.3,19.2,18.3,22.8z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_update_circle_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_update_circle_24.xml
new file mode 100644
index 0000000000..872902f4c3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_update_circle_24.xml
@@ -0,0 +1,15 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.386 7.25a0.875 0.875 0 0 1 1.228 0L17 11.567l-1.227 1.247-2.898-2.851V17h-1.75V9.963l-2.898 2.851L7 11.567l4.386-4.317z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zM3.75 12a8.25 8.25 0 1 1 16.5 0 8.25 8.25 0 0 1-16.5 0z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_vacation.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_vacation.xml
new file mode 100644
index 0000000000..07a6924ee1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_vacation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M3.6,27l-2.5-1.8L0.8,25c-0.7-0.4-0.7-1.2-0.4-2c0.4-0.5,1.1-0.7,1.6-0.5l3.6,1.2c0-0.4,0.2-0.9,0.4-1.4
+ c0.2-0.7,0.5-1.6,1.1-2.3c0.2-0.4,0.5-0.7,0.7-1.2c0.2-0.4,0.5-0.9,0.9-1.2c0.4-0.9,1.1-1.6,1.8-2.5c0.7-0.9,1.4-1.6,2.3-2.5
+ c0.4-0.4,0.9-0.7,1.2-1.2c0.4-0.2,0.9-0.7,1.2-1.1c0.2-0.2,0.2-0.2,0.4-0.4L3.1,7.3c-0.2,0-0.2,0-0.4,0l-2,0.9
+ C0.2,8.3-0.3,7.6,0.2,7.1l2-2C2.4,5,2.4,5,2.5,5h17.9c0.5-0.5,1.2-1.1,1.8-1.6c0.7-0.7,1.4-1.2,2.1-1.8c0.4-0.4,0.7-0.5,1.1-0.7
+ c0.4-0.2,0.7-0.4,1.1-0.5c0.5,0,0.9-0.2,1.2-0.2s0.7,0,1.1,0s0.7,0,1.1,0c0.4,0,0.5,0,0.7,0.2c0.5,0,0.7,0.2,0.7,0.2
+ c0.2,0,0.2,0.2,0.4,0.4c0,0,0,0.4,0.2,0.7c0,0.2,0,0.5,0.2,0.7c0,0.4,0,0.7,0,1.1s0,0.7,0,1.1c0,0.4,0,0.9-0.2,1.2
+ c-0.2,0.4-0.4,0.7-0.5,1.1c-0.2,0.4-0.5,0.7-0.7,1.1c-0.5,0.7-1.1,1.4-1.8,2.1c-0.4,0.4-0.7,0.7-1.1,1.1v17.8c0,0.2,0,0.4-0.2,0.4
+ l-2,2c-0.5,0.5-1.2,0-1.1-0.5l0.7-2c0-0.2,0-0.2,0-0.4L22.8,16c-0.4,0.4-0.7,0.7-0.9,0.9c-0.4,0.4-0.7,0.9-1.2,1.2
+ c-0.4,0.4-0.7,0.9-1.2,1.2c-0.7,0.9-1.6,1.6-2.5,2.3c-0.9,0.7-1.6,1.4-2.5,2c-0.4,0.4-0.9,0.5-1.2,0.9c-0.4,0.2-0.7,0.5-1.2,0.7
+ c-0.7,0.4-1.6,0.7-2.3,1.1c-0.4,0.2-0.7,0.2-1.2,0.4L9.6,30c0.4,0.7,0,1.4-0.7,1.8c-0.5,0.2-1.2,0-1.6-0.5l-0.2-0.4l-1.8-2.3
+ c-0.2,0-0.2,0-0.4,0.2c-0.4,0-0.5,0.2-0.7,0.2s-0.2,0-0.4,0c-0.2,0-0.2,0-0.4,0c-0.2,0-0.4,0-0.5,0c-0.2,0-0.2,0-0.2,0s0,0,0-0.2
+ c0-0.2,0-0.2,0-0.5c0-0.2,0-0.2,0-0.4c0-0.2,0-0.2,0-0.4C3.4,27.5,3.4,27.3,3.6,27L3.6,27z M5.7,28.4L5.7,28.4L5.7,28.4L5.7,28.4z"
+ tools:ignore="VectorPath" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_24.xml
new file mode 100644
index 0000000000..fcb74e05dc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_24.xml
@@ -0,0 +1,18 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M12.875 15.625h-1.75v1.75h1.75v-1.75z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.125 14V9h1.75v5h-1.75z" />
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.956 4.92c0.165 0 0.47 0.05 0.655 0.385l7.04 12.66a0.729 0.729 0 0 1-0.009 0.745 0.726 0.726 0 0 1-0.646 0.37H5.004a0.727 0.727 0 0 1-0.645-0.368 0.728 0.728 0 0 1-0.012-0.743L11.3 5.309a0.725 0.725 0 0 1 0.657-0.389zm0-1.75c-0.859 0-1.717 0.433-2.19 1.297l-6.953 12.66c-0.915 1.666 0.29 3.703 2.191 3.703h13.993c1.907 0 3.112-2.049 2.185-3.715l-7.04-12.66a2.478 2.478 0 0 0-2.186-1.285z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_fill_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_fill_24.xml
new file mode 100644
index 0000000000..b49799f930
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_warning_fill_24.xml
@@ -0,0 +1,12 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M11.956 3.336c-0.867 0-1.733 0.437-2.212 1.309L2.815 17.262C1.892 18.944 3.108 21 5.027 21h13.946c1.925 0 3.141-2.068 2.205-3.75L14.162 4.633a2.5 2.5 0 0 0-2.206-1.297zM11.125 13.5V9h1.75v4.5h-1.75zm0 1.75h1.75V17h-1.75v-1.75z" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_web_extension_default_icon.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_web_extension_default_icon.xml
new file mode 100644
index 0000000000..8aa89c3b51
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_web_extension_default_icon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z" />
+</vector>
+
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_whats_new_24.xml b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_whats_new_24.xml
new file mode 100644
index 0000000000..e2156ea6d4
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_whats_new_24.xml
@@ -0,0 +1,16 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@color/mozac_ui_icons_fill"
+ android:fillType="evenOdd"
+ android:pathData="M12 3.107A3.375 3.375 0 0 0 6.541 7H5.5A2.5 2.5 0 0 0 3 9.5v1c0 0.818 0.393 1.544 1 2v7A2.5 2.5 0 0 0 6.5 22h11a2.5 2.5 0 0 0 2.5-2.5v-7c0.608-0.457 1-1.183 1-2v-1A2.5 2.5 0 0 0 18.5 7h-1.041A3.375 3.375 0 0 0 12 3.107zM9.5 3.75A1.625 1.625 0 1 0 9.5 7h1.625V5.375c0-0.898-0.727-1.625-1.625-1.625zm3.375 5v2.5H18.5a0.75 0.75 0 0 0 0.75-0.75v-1a0.75 0.75 0 0 0-0.75-0.75h-5.625zM14.5 7a1.625 1.625 0 1 0-1.625-1.625V7H14.5zm-9 1.75h5.625v2.5H5.5a0.75 0.75 0 0 1-0.75-0.75v-1A0.75 0.75 0 0 1 5.5 8.75zM12.875 13h5.376l-0.001 6.5a0.75 0.75 0 0 1-0.75 0.75h-4.625V13zm-1.75 0v7.25H6.5a0.75 0.75 0 0 1-0.75-0.75V13h5.375z"
+ tools:ignore="VectorRaster"
+ tools:targetApi="n" />
+</vector>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/values/attrs.xml b/mobile/android/android-components/components/ui/icons/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..c41244c9c1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/values/attrs.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <!-- Background color for mozac_ic_private_mode_circle_fill_20,
+ mozac_ic_private_mode_circle_fill_24 and mozac_ic_private_mode_circle_fill_48 -->
+ <attr name="mozac_ic_private_mode_circle_fill_background_color" format="reference" />
+ <!-- Icon color for mozac_ic_private_mode_circle_fill_20,
+ mozac_ic_private_mode_circle_fill_24 and mozac_ic_private_mode_circle_fill_48 -->
+ <attr name="mozac_ic_private_mode_circle_fill_icon_color" format="reference" />
+</resources>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/values/colors.xml b/mobile/android/android-components/components/ui/icons/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..b785281bc7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/values/colors.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<resources>
+ <color name="mozac_ui_icons_fill">#FFFFFF</color>
+
+ <!-- Star icon fill colors for mozac_ic_star_one_half_fill_20 -->
+ <color name="mozac_ic_star_filled">#000000</color>
+ <color name="mozac_ic_star_unfilled">#FFFFFF</color>
+
+ <!-- Private Mode mask icon circle fill colors for mozac_ic_private_mode_circle_fill_stroke_20 -->
+ <color name="mozac_ui_private_mode_circle_fill">#000000</color>
+</resources>
diff --git a/mobile/android/android-components/components/ui/icons/src/main/res/values/mozac_ui_icons_strings.xml b/mobile/android/android-components/components/ui/icons/src/main/res/values/mozac_ui_icons_strings.xml
new file mode 100644
index 0000000000..9dbb12a529
--- /dev/null
+++ b/mobile/android/android-components/components/ui/icons/src/main/res/values/mozac_ui_icons_strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <string translatable="false" name="mozac_error_shred_file">mozac_error_shred_file</string>
+ <string translatable="false" name="mozac_error_question_file">mozac_error_question_file</string>
+ <string translatable="false" name="mozac_error_surprised">mozac_error_surprised</string>
+ <string translatable="false" name="mozac_error_hourglass">mozac_error_hourglass</string>
+ <string translatable="false" name="mozac_error_eye_roll">mozac_error_eye_roll</string>
+ <string translatable="false" name="mozac_error_unplugged">mozac_error_unplugged</string>
+ <string translatable="false" name="mozac_error_lock">mozac_error_lock</string>
+ <string translatable="false" name="mozac_error_confused">mozac_error_confused</string>
+ <string translatable="false" name="mozac_error_no_internet">mozac_error_no_internet</string>
+ <string translatable="false" name="mozac_error_asleep">mozac_error_asleep</string>
+ <string translatable="false" name="mozac_error_inspect">mozac_error_inspect</string>
+</resources> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/tabcounter/.gitignore b/mobile/android/android-components/components/ui/tabcounter/.gitignore
new file mode 100644
index 0000000000..796b96d1c4
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/mobile/android/android-components/components/ui/tabcounter/README.md b/mobile/android/android-components/components/ui/tabcounter/README.md
new file mode 100644
index 0000000000..38500615e0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/README.md
@@ -0,0 +1,37 @@
+# [Android Components](../../../README.md) > UI > Tabcounter
+
+A button that shows the current tab count and can animate state changes.
+
+## Usage
+
+Create a tab counter in XML:
+
+```xml
+<mozilla.components.ui.tabcounter.TabCounter
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ mozac:tabCounterTintColor="@color/primary" />
+```
+
+Styleable attributes can be set on your theme as well:
+
+```xml
+<style name="AppTheme">
+ ...
+ <item name="tabCounterTintColor">#FFFFFF</item>
+</style>
+```
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:ui-tabcounter:{latest-version}"
+```
+
+## License
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/
diff --git a/mobile/android/android-components/components/ui/tabcounter/build.gradle b/mobile/android/android-components/components/ui/tabcounter/build.gradle
new file mode 100644
index 0000000000..04e3ccc2e1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/build.gradle
@@ -0,0 +1,50 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'com.google.devtools.ksp'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ buildFeatures {
+ viewBinding true
+ }
+
+ namespace 'mozilla.components.ui.tabcounter'
+}
+
+dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
+ implementation project(':support-ktx')
+ implementation project(':support-utils')
+
+ implementation ComponentsDependencies.androidx_core_ktx
+ implementation project(':concept-menu')
+ implementation project(':browser-menu2')
+ implementation project(':support-base')
+ implementation project(':ui-colors')
+ implementation project(':ui-icons')
+
+ testImplementation project(":support-test")
+
+ testImplementation ComponentsDependencies.androidx_test_junit
+ testImplementation ComponentsDependencies.testing_robolectric
+}
+
+apply from: '../../../android-lint.gradle'
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description)
diff --git a/mobile/android/android-components/components/ui/tabcounter/proguard-rules.pro b/mobile/android/android-components/components/ui/tabcounter/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/AndroidManifest.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..928c7b2243
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/AndroidManifest.xml
@@ -0,0 +1,8 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <application android:supportsRtl="true" />
+
+</manifest>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounter.kt b/mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounter.kt
new file mode 100644
index 0000000000..2ba8aa8540
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounter.kt
@@ -0,0 +1,348 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.tabcounter
+
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.content.Context
+import android.content.res.ColorStateList
+import android.graphics.Typeface
+import android.util.AttributeSet
+import android.util.TypedValue
+import android.view.LayoutInflater
+import android.widget.FrameLayout
+import android.widget.ImageView
+import android.widget.RelativeLayout
+import android.widget.TextView
+import androidx.annotation.VisibleForTesting
+import androidx.core.content.ContextCompat
+import androidx.core.view.isVisible
+import androidx.core.view.updatePadding
+import mozilla.components.support.utils.DrawableUtils
+import mozilla.components.ui.tabcounter.databinding.MozacUiTabcounterLayoutBinding
+import java.text.NumberFormat
+
+class TabCounter @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyle: Int = 0,
+) : RelativeLayout(context, attrs, defStyle) {
+
+ private val animationSet: AnimatorSet
+ private var binding: MozacUiTabcounterLayoutBinding
+ private var counterBox: ImageView
+ private var counterText: TextView
+ private var counterRoot: FrameLayout
+ private var counterMask: ImageView
+
+ init {
+ binding = MozacUiTabcounterLayoutBinding.inflate(LayoutInflater.from(context), this)
+ counterBox = binding.counterBox
+ counterText = binding.counterText
+ counterRoot = binding.counterRoot
+ counterMask = binding.counterMask
+
+ setCount(INTERNAL_COUNT)
+
+ context.obtainStyledAttributes(attrs, R.styleable.TabCounter, defStyle, 0).apply {
+ val counterColor = getColorStateList(
+ R.styleable.TabCounter_tabCounterTintColor,
+ ) ?: ContextCompat.getColorStateList(context, R.color.mozac_ui_tabcounter_default_tint)
+
+ counterColor?.let {
+ setColor(it)
+ }
+
+ clipChildren = false
+
+ recycle()
+ }
+
+ animationSet = createAnimatorSet()
+ }
+
+ /**
+ * Sets the colors of the tab counter box and text.
+ */
+ @VisibleForTesting
+ internal fun setColor(colorStateList: ColorStateList) {
+ val tabCounterBox =
+ DrawableUtils.loadAndTintDrawable(context, R.drawable.mozac_ui_tabcounter_box, colorStateList)
+ counterBox.setImageDrawable(tabCounterBox)
+ counterText.setTextColor(colorStateList)
+ }
+
+ private fun updateContentDescription(count: Int) {
+ counterRoot.contentDescription = if (count == 1) {
+ context?.getString(R.string.mozac_tab_counter_open_tab_tray_single)
+ } else {
+ String.format(
+ context.getString(R.string.mozac_tab_counter_open_tab_tray_plural),
+ count.toString(),
+ )
+ }
+ }
+
+ fun setCountWithAnimation(count: Int) {
+ setCount(count)
+
+ // No need to animate on these cases.
+ when {
+ INTERNAL_COUNT == 0 -> return // Initial state.
+ INTERNAL_COUNT == count -> return // There isn't any tab added or removed.
+ INTERNAL_COUNT > MAX_VISIBLE_TABS -> return // There are still over MAX_VISIBLE_TABS tabs open.
+ }
+
+ // Cancel previous animations if necessary.
+ if (animationSet.isRunning) {
+ animationSet.cancel()
+ }
+ // Trigger animations.
+ animationSet.start()
+ }
+
+ /**
+ * Toggles the visibility of the mask overlay on the counter
+ *
+ * @param showMask [Boolean] used to determine whether to show or hide the mask.
+ */
+ fun toggleCounterMask(showMask: Boolean) {
+ counterMask.isVisible = showMask
+ }
+
+ fun setCount(count: Int) {
+ updateContentDescription(count)
+ adjustTextSize(count)
+ counterText.text = formatCountForDisplay(count)
+ INTERNAL_COUNT = count
+ }
+
+ private fun createAnimatorSet(): AnimatorSet {
+ val animatorSet = AnimatorSet()
+ createBoxAnimatorSet(animatorSet)
+ createTextAnimatorSet(animatorSet)
+ return animatorSet
+ }
+
+ private fun createBoxAnimatorSet(animatorSet: AnimatorSet) {
+ // The first animator, fadeout in 33 ms (49~51, 2 frames).
+ val fadeOut = ObjectAnimator.ofFloat(
+ counterBox,
+ "alpha",
+ ANIM_BOX_FADEOUT_FROM,
+ ANIM_BOX_FADEOUT_TO,
+ ).setDuration(ANIM_BOX_FADEOUT_DURATION)
+
+ // Move up on y-axis, from 0.0 to -5.3 in 50ms, with fadeOut (49~52, 3 frames).
+ val moveUp1 = ObjectAnimator.ofFloat(
+ counterBox,
+ "translationY",
+ ANIM_BOX_MOVEUP1_TO,
+ ANIM_BOX_MOVEUP1_FROM,
+ ).setDuration(ANIM_BOX_MOVEUP1_DURATION)
+
+ // Move down on y-axis, from -5.3 to -1.0 in 116ms, after moveUp1 (52~59, 7 frames).
+ val moveDown2 = ObjectAnimator.ofFloat(
+ counterBox,
+ "translationY",
+ ANIM_BOX_MOVEDOWN2_FROM,
+ ANIM_BOX_MOVEDOWN2_TO,
+ ).setDuration(ANIM_BOX_MOVEDOWN2_DURATION)
+
+ // FadeIn in 66ms, with moveDown2 (52~56, 4 frames).
+ val fadeIn = ObjectAnimator.ofFloat(
+ counterBox,
+ "alpha",
+ ANIM_BOX_FADEIN_FROM,
+ ANIM_BOX_FADEIN_TO,
+ ).setDuration(ANIM_BOX_FADEIN_DURATION)
+
+ // Move down on y-axis, from -1.0 to 2.7 in 116ms, after moveDown2 (59~66, 7 frames).
+ val moveDown3 = ObjectAnimator.ofFloat(
+ counterBox,
+ "translationY",
+ ANIM_BOX_MOVEDOWN3_FROM,
+ ANIM_BOX_MOVEDOWN3_TO,
+ ).setDuration(ANIM_BOX_MOVEDOWN3_DURATION)
+
+ // Move up on y-axis, from 2.7 to 0 in 133ms, after moveDown3 (66~74, 8 frames).
+ val moveUp4 = ObjectAnimator.ofFloat(
+ counterBox,
+ "translationY",
+ ANIM_BOX_MOVEDOWN4_FROM,
+ ANIM_BOX_MOVEDOWN4_TO,
+ ).setDuration(ANIM_BOX_MOVEDOWN4_DURATION)
+
+ // Scale up height from 2% to 105% in 100ms, after moveUp1 and delay 16ms (53~59, 6 frames).
+ val scaleUp1 = ObjectAnimator.ofFloat(
+ counterBox,
+ "scaleY",
+ ANIM_BOX_SCALEUP1_FROM,
+ ANIM_BOX_SCALEUP1_TO,
+ ).setDuration(ANIM_BOX_SCALEUP1_DURATION)
+ scaleUp1.startDelay = ANIM_BOX_SCALEUP1_DELAY // delay 1 frame after moveUp1
+
+ // Scale down height from 105% to 99% in 116ms, after scaleUp1 (59~66, 7 frames).
+ val scaleDown2 = ObjectAnimator.ofFloat(
+ counterBox,
+ "scaleY",
+ ANIM_BOX_SCALEDOWN2_FROM,
+ ANIM_BOX_SCALEDOWN2_TO,
+ ).setDuration(ANIM_BOX_SCALEDOWN2_DURATION)
+
+ // Scale up height from 99% to 100% in 133ms, after scaleDown2 (66~74, 8 frames).
+ val scaleUp3 = ObjectAnimator.ofFloat(
+ counterBox,
+ "scaleY",
+ ANIM_BOX_SCALEUP3_FROM,
+ ANIM_BOX_SCALEUP3_TO,
+ ).setDuration(ANIM_BOX_SCALEUP3_DURATION)
+
+ animatorSet.play(fadeOut).with(moveUp1)
+ animatorSet.play(moveUp1).before(moveDown2)
+ animatorSet.play(moveDown2).with(fadeIn)
+ animatorSet.play(moveDown2).before(moveDown3)
+ animatorSet.play(moveDown3).before(moveUp4)
+
+ animatorSet.play(moveUp1).before(scaleUp1)
+ animatorSet.play(scaleUp1).before(scaleDown2)
+ animatorSet.play(scaleDown2).before(scaleUp3)
+ }
+
+ private fun createTextAnimatorSet(animatorSet: AnimatorSet) {
+ val firstAnimator = animatorSet.childAnimations[0]
+
+ // Fadeout in 100ms, with firstAnimator (49~51, 2 frames).
+ val fadeOut = ObjectAnimator.ofFloat(
+ counterText,
+ "alpha",
+ ANIM_TEXT_FADEOUT_FROM,
+ ANIM_TEXT_FADEOUT_TO,
+ ).setDuration(ANIM_TEXT_FADEOUT_DURATION)
+
+ // FadeIn in 66 ms, after fadeOut with delay 96ms (57~61, 4 frames).
+ val fadeIn = ObjectAnimator.ofFloat(
+ counterText,
+ "alpha",
+ ANIM_TEXT_FADEIN_FROM,
+ ANIM_TEXT_FADEIN_TO,
+ ).setDuration(ANIM_TEXT_FADEIN_DURATION)
+ fadeIn.startDelay = (ANIM_TEXT_FADEIN_DELAY) // delay 6 frames after fadeOut
+
+ // Move down on y-axis, from 0 to 4.4 in 66ms, with fadeIn (57~61, 4 frames).
+ val moveDown = ObjectAnimator.ofFloat(
+ counterText,
+ "translationY",
+ ANIM_TEXT_MOVEDOWN_FROM,
+ ANIM_TEXT_MOVEDOWN_TO,
+ ).setDuration(ANIM_TEXT_MOVEDOWN_DURATION)
+ moveDown.startDelay = (ANIM_TEXT_MOVEDOWN_DELAY) // delay 6 frames after fadeOut
+
+ // Move up on y-axis, from 0 to 4.4 in 66ms, after moveDown (61~69, 8 frames).
+ val moveUp = ObjectAnimator.ofFloat(
+ counterText,
+ "translationY",
+ ANIM_TEXT_MOVEUP_FROM,
+ ANIM_TEXT_MOVEUP_TO,
+ ).setDuration(ANIM_TEXT_MOVEUP_DURATION)
+
+ animatorSet.play(firstAnimator).with(fadeOut)
+ animatorSet.play(fadeOut).before(fadeIn)
+ animatorSet.play(fadeIn).with(moveDown)
+ animatorSet.play(moveDown).before(moveUp)
+ }
+
+ private fun formatCountForDisplay(count: Int): String {
+ return if (count > MAX_VISIBLE_TABS) {
+ counterText.updatePadding(bottom = INFINITE_CHAR_PADDING_BOTTOM)
+ SO_MANY_TABS_OPEN
+ } else {
+ NumberFormat.getInstance().format(count.toLong())
+ }
+ }
+
+ private fun adjustTextSize(newCount: Int) {
+ val newRatio = if (newCount in TWO_DIGITS_TAB_COUNT_THRESHOLD..MAX_VISIBLE_TABS) {
+ TWO_DIGITS_SIZE_RATIO
+ } else {
+ ONE_DIGIT_SIZE_RATIO
+ }
+
+ val counterBoxWidth =
+ context.resources.getDimensionPixelSize(R.dimen.mozac_tab_counter_box_width_height)
+ val textSize = newRatio * counterBoxWidth
+ counterText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
+ counterText.setTypeface(null, Typeface.BOLD)
+ counterText.setPadding(0, 0, 0, 0)
+ }
+
+ companion object {
+ var INTERNAL_COUNT = 0
+
+ const val MAX_VISIBLE_TABS = 99
+ const val SO_MANY_TABS_OPEN = "∞"
+ const val INFINITE_CHAR_PADDING_BOTTOM = 6
+
+ const val ONE_DIGIT_SIZE_RATIO = 0.5f
+ const val TWO_DIGITS_SIZE_RATIO = 0.4f
+ const val TWO_DIGITS_TAB_COUNT_THRESHOLD = 10
+
+ // createBoxAnimatorSet
+ private const val ANIM_BOX_FADEOUT_FROM = 1.0f
+ private const val ANIM_BOX_FADEOUT_TO = 0.0f
+ private const val ANIM_BOX_FADEOUT_DURATION = 33L
+
+ private const val ANIM_BOX_MOVEUP1_FROM = 0.0f
+ private const val ANIM_BOX_MOVEUP1_TO = -5.3f
+ private const val ANIM_BOX_MOVEUP1_DURATION = 50L
+
+ private const val ANIM_BOX_MOVEDOWN2_FROM = -5.3f
+ private const val ANIM_BOX_MOVEDOWN2_TO = -1.0f
+ private const val ANIM_BOX_MOVEDOWN2_DURATION = 167L
+
+ private const val ANIM_BOX_FADEIN_FROM = 0.01f
+ private const val ANIM_BOX_FADEIN_TO = 1.0f
+ private const val ANIM_BOX_FADEIN_DURATION = 66L
+ private const val ANIM_BOX_MOVEDOWN3_FROM = -1.0f
+ private const val ANIM_BOX_MOVEDOWN3_TO = 2.7f
+ private const val ANIM_BOX_MOVEDOWN3_DURATION = 116L
+
+ private const val ANIM_BOX_MOVEDOWN4_FROM = 2.7f
+ private const val ANIM_BOX_MOVEDOWN4_TO = 0.0f
+ private const val ANIM_BOX_MOVEDOWN4_DURATION = 133L
+
+ private const val ANIM_BOX_SCALEUP1_FROM = 0.02f
+ private const val ANIM_BOX_SCALEUP1_TO = 1.05f
+ private const val ANIM_BOX_SCALEUP1_DURATION = 100L
+ private const val ANIM_BOX_SCALEUP1_DELAY = 16L
+
+ private const val ANIM_BOX_SCALEDOWN2_FROM = 1.05f
+ private const val ANIM_BOX_SCALEDOWN2_TO = 0.99f
+ private const val ANIM_BOX_SCALEDOWN2_DURATION = 116L
+
+ private const val ANIM_BOX_SCALEUP3_FROM = 0.99f
+ private const val ANIM_BOX_SCALEUP3_TO = 1.00f
+ private const val ANIM_BOX_SCALEUP3_DURATION = 133L
+
+ // createTextAnimatorSet
+ private const val ANIM_TEXT_FADEOUT_FROM = 1.0f
+ private const val ANIM_TEXT_FADEOUT_TO = 0.0f
+ private const val ANIM_TEXT_FADEOUT_DURATION = 33L
+
+ private const val ANIM_TEXT_FADEIN_FROM = 0.01f
+ private const val ANIM_TEXT_FADEIN_TO = 1.0f
+ private const val ANIM_TEXT_FADEIN_DURATION = 66L
+ private const val ANIM_TEXT_FADEIN_DELAY = 16L * 6
+
+ private const val ANIM_TEXT_MOVEDOWN_FROM = 0.0f
+ private const val ANIM_TEXT_MOVEDOWN_TO = 4.4f
+ private const val ANIM_TEXT_MOVEDOWN_DURATION = 66L
+ private const val ANIM_TEXT_MOVEDOWN_DELAY = 16L * 6
+
+ private const val ANIM_TEXT_MOVEUP_FROM = 4.4f
+ private const val ANIM_TEXT_MOVEUP_TO = 0.0f
+ private const val ANIM_TEXT_MOVEUP_DURATION = 66L
+ }
+}
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounterMenu.kt b/mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounterMenu.kt
new file mode 100644
index 0000000000..4f0329a85b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounterMenu.kt
@@ -0,0 +1,101 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.tabcounter
+
+import android.content.Context
+import androidx.core.content.ContextCompat.getColor
+import mozilla.components.browser.menu2.BrowserMenuController
+import mozilla.components.concept.menu.MenuController
+import mozilla.components.concept.menu.candidate.DrawableMenuIcon
+import mozilla.components.concept.menu.candidate.TextMenuCandidate
+import mozilla.components.concept.menu.candidate.TextStyle
+import mozilla.components.ui.icons.R as iconsR
+
+/**
+ * The menu that is shown when clicking on the [TabCounter]
+ *
+ * @param context the context.
+ * @param onItemTapped behavior for when an item in the menu is tapped.
+ * @param iconColor optional color to specify tint of menu icons
+ */
+open class TabCounterMenu(
+ context: Context,
+ onItemTapped: (Item) -> Unit,
+ iconColor: Int? = null,
+) {
+
+ /**
+ * Represents the menu items.
+ *
+ * [CloseTab] menu item for closing a tab.
+ * [NewTab] menu item for opening a new tab.
+ * [NewPrivateTab] menu item for opening a new private tab.
+ * [DuplicateTab] menu item for duplicating the current tab.
+ */
+ @Suppress("UndocumentedPublicClass")
+ open class Item {
+ object CloseTab : Item()
+ object NewTab : Item()
+ object NewPrivateTab : Item()
+ object DuplicateTab : Item()
+ }
+
+ var newTabItem: TextMenuCandidate
+ var newPrivateTabItem: TextMenuCandidate
+ var closeTabItem: TextMenuCandidate
+ var duplicateTabItem: TextMenuCandidate
+
+ val menuController: MenuController by lazy { BrowserMenuController() }
+
+ init {
+ newTabItem = TextMenuCandidate(
+ text = context.getString(R.string.mozac_browser_menu_new_tab),
+ start = DrawableMenuIcon(
+ context,
+ iconsR.drawable.mozac_ic_plus_24,
+ tint = iconColor ?: getColor(context, R.color.mozac_ui_tabcounter_default_text),
+ ),
+ textStyle = TextStyle(),
+ ) {
+ onItemTapped(Item.NewTab)
+ }
+
+ newPrivateTabItem = TextMenuCandidate(
+ text = context.getString(R.string.mozac_browser_menu_new_private_tab),
+ start = DrawableMenuIcon(
+ context,
+ iconsR.drawable.mozac_ic_private_mode_24,
+ tint = iconColor ?: getColor(context, R.color.mozac_ui_tabcounter_default_text),
+ ),
+ textStyle = TextStyle(),
+ ) {
+ onItemTapped(Item.NewPrivateTab)
+ }
+
+ closeTabItem = TextMenuCandidate(
+ text = context.getString(R.string.mozac_close_tab),
+ start = DrawableMenuIcon(
+ context,
+ iconsR.drawable.mozac_ic_cross_24,
+ tint = iconColor ?: getColor(context, R.color.mozac_ui_tabcounter_default_text),
+ ),
+ textStyle = TextStyle(),
+ ) {
+ onItemTapped(Item.CloseTab)
+ }
+
+ duplicateTabItem = TextMenuCandidate(
+ text = context.getString(R.string.mozac_ui_tabcounter_duplicate_tab),
+ start = DrawableMenuIcon(
+ context,
+ iconsR.drawable.mozac_ic_tab,
+ tint = iconColor ?: getColor(context, R.color.mozac_ui_tabcounter_default_text),
+ ),
+ textStyle = TextStyle(),
+ ) {
+ onItemTapped(Item.DuplicateTab)
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_bar.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_bar.xml
new file mode 100644
index 0000000000..75aef5e019
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_bar.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="line">
+ <stroke
+ android:width="1dp"
+ android:color="@color/mozac_ui_tabcounter_default_tint" />
+ <size android:height="2dp" />
+</shape> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_box.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_box.xml
new file mode 100644
index 0000000000..489efcb568
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_box.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+<path
+ android:pathData="M4.5,4A2.5,2.5 0,0 0,2 6.5v11A2.5,2.5 0,0 0,4.5 20h15a2.5,2.5 0,0 0,2.5 -2.5v-11A2.5,2.5 0,0 0,19.5 4h-15zM20.5,17.7 L19.7,18.5L4.3,18.5l-0.8,-0.8L3.5,6.3l0.8,-0.8h15.4l0.8,0.8v11.4z"
+ android:strokeWidth="1"
+ android:fillColor="@color/mozac_ui_tabcounter_default_tint"/>
+</vector>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_round_rectangle_ripple.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_round_rectangle_ripple.xml
new file mode 100644
index 0000000000..e79ba0457f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/drawable/mozac_ui_tabcounter_round_rectangle_ripple.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="#22000000">
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <solid android:color="#000000" />
+ <corners android:radius="2dp" />
+ </shape>
+ </item>
+</ripple>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/layout/mozac_ui_tabcounter_layout.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/layout/mozac_ui_tabcounter_layout.xml
new file mode 100644
index 0000000000..ce03eed04b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/layout/mozac_ui_tabcounter_layout.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ tools:layout_height="wrap_content"
+ tools:layout_width="wrap_content">
+
+ <FrameLayout
+ android:id="@+id/counter_root"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:clipChildren="false">
+
+ <ImageView
+ android:id="@+id/counter_box"
+ android:layout_width="@dimen/mozac_tab_counter_box_width_height"
+ android:layout_height="@dimen/mozac_tab_counter_box_width_height"
+ android:contentDescription="@string/mozac_tab_counter_content_description"
+ android:importantForAccessibility="no"
+ android:layout_gravity="center"
+ app:srcCompat="@drawable/mozac_ui_tabcounter_box" />
+
+ <TextView
+ android:id="@+id/counter_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:textAlignment="center"
+ android:textColor="@color/mozac_ui_tabcounter_default_tint"
+ android:layout_marginBottom="0.5dp"
+ android:textSize="12sp"
+ android:textStyle="bold"
+ tools:text="16" />
+
+ <androidx.appcompat.widget.AppCompatImageView
+ android:id="@+id/counter_mask"
+ app:srcCompat="@drawable/mozac_ic_private_mode_circle_fill_stroke_20"
+ android:translationX="8dp"
+ android:translationY="-8dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="top|end"
+ android:visibility="gone" />
+ </FrameLayout>
+</merge>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-am/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-am/strings.xml
new file mode 100644
index 0000000000..0aeb48b020
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-am/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ትር ክፈት። ትሮችን ለመቀየር መታ ያድርጉ።</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ትር ክፈት። ትሮችን ለመቀየር መታ ያድርጉ።</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">አዲስ ትር</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">አዲስ የግል ትር</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ትርን ዝጋ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ትርን አባዛ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">የትር ቆጣሪ ሰሪ-አሞሌ አዝራር።</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ar/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ar/strings.xml
new file mode 100644
index 0000000000..4f66de8ec0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ar/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">لسان واحد مفتوح. انقر لتبديل الألسنة.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s من الألسنة مفتوح. انقر لتبديل الألسنة.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">لسان جديد</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">لسان خاص جديد</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">أغلِق اللسان</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">كرّر اللسان</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">زر ”عدد الألسنة“ في شريط الأدوات.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ast/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ast/strings.xml
new file mode 100644
index 0000000000..ed05585c87
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ast/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 llingüeta abierta. Toca pa cambiar a otra.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s llingüetes abiertes. Toca pa cambiar a otra.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Llingüeta nueva</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Llingüeta privada nueva</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zarrar la llingüeta</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar la llingüeta</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">El botón del contador de llingüetes de la barra de ferramientes.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml
new file mode 100644
index 0000000000..9f856c949a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">آچیق تاغ. تاغ‌لاری دگیشدیرمک اوچون توخونون.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s آچیق تاغ. تاغلاری دگیشدیرمک اوچون توخونون.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">یئنی تاغ</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">یئنی گیزلی تاغ</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">تاغی باغلا</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">تاغی ایکی‌له</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">تاغ سایی‌جی‌نین تولبار دویمه‌سی.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-be/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-be/strings.xml
new file mode 100644
index 0000000000..395e798a81
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-be/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 адкрытая картка. Націсніце, каб пераключыць карткі.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Адкрытых картак: %1$s. Націсніце, каб пераключыць карткі.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Новая картка</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Новая прыватная картка</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Закрыць картку</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Дубляваць картку</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Кнопка лічыльніка картак на панэлі інструментаў.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bg/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bg/strings.xml
new file mode 100644
index 0000000000..0714493b0d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bg/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 отворен раздел. Докоснете за превключване на раздели.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s отворени раздела. Докоснете, за превключване на раздели.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Нов раздел</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Нов поверителен раздел</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Затваряне на раздел</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Дублиране на раздел</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Бутон към инструментите от брояча на раздели.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bn/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bn/strings.xml
new file mode 100644
index 0000000000..1136e9a18c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bn/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">খোলা ট্যাব ১টি। ট্যাব পাল্টাও।</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$sটি খোলা ট্যাব। ট্যাব পাল্টাও।</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">নতুন ট্যাব</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">নতুন ব্যক্তিগত ট্যাব</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ট্যাব বন্ধ করুন</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">অনুরূপ ট্যাব</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ট্যাব গণনাকারী টুলবার বোতাম।</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-br/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-br/strings.xml
new file mode 100644
index 0000000000..813c4a9382
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-br/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ivinell digor. Stokit evit mont dʼun ivinell all.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ivinell digor. Stokit evit mont dʼun ivinell all.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Ivinell nevez</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Ivinell prevez nevez</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Serriñ an ivinell</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Eilañ an ivinell</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">An afell kontañ ivinelloù er varrenn-ostilhoù.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bs/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bs/strings.xml
new file mode 100644
index 0000000000..8b89e9972f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-bs/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 otvoren tab. Dodirnite za promjenu tabova.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s otvorenih tabova. Dodirnite za promjenu tabova.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Novi tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Novi privatni tab</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zatvori tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dupliciraj tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Tipka brojača tabova na alatnoj traci.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ca/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ca/strings.xml
new file mode 100644
index 0000000000..141fb164b0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ca/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 pestanya oberta. Toqueu per canviar de pestanya.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s pestanyes obertes. Toqueu per canviar de pestanya.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Pestanya nova</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Pestanya privada nova</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Tanca la pestanya</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplica la pestanya</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">El botó del comptador de pestanyes de la barra d’eines.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cak/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cak/strings.xml
new file mode 100644
index 0000000000..0ac9556c3d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cak/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ruwi\' jaqon. Tachapa\' richin nak\'ëx ruwi\'.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ruwi\' ejaqon. Tachapa\' richin nak\'ëx ruwi\'.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">K\'ak\'a\' ruwi\'</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">K\'ak\'a\' ichinan ruwi\'</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Titz\'apïx ruwi\'</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Tikamulüx ruwi\'</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Ri rupitz\'b\'al ajilanel ruwi\' pa rukajtz\'ik samajib\'äl.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ceb/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ceb/strings.xml
new file mode 100644
index 0000000000..c629119fc1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ceb/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ang abli nga tab. i-Tap para mobalhin ug mga tab.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ang abli nga mga tab. i-Tap para mobalhin ug mga tab.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Bag-o nga tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Bag-o nga pribadong tab</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">i-Close ang tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicate nga tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Ang tab counter toolbar button.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ckb/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ckb/strings.xml
new file mode 100644
index 0000000000..46e0ffeadb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ckb/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">١ بازدەر کراوەیە. پەنجەدابگرە بۆ گۆڕینی بازدەرەکان.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s بازدەر کراوەیە. پەنجەدابگرە بۆ گۆڕینی بازدەرەکان.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">بازدەری نوێ</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">بازدەری تایبەتی نوێ</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">بازدەر دابخە</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">بازدەری دووبارە</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">دوگمەی ژمارەی بازدەرەکان لە توڵامراز.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-co/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-co/strings.xml
new file mode 100644
index 0000000000..d72dfc8f8f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-co/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 unghjetta aperta. Picchichjà per cambià d’unghjetta.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s unghjette aperte. Picchichjà per cambià d’unghjetta.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nova unghjetta</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nova unghjetta privata</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Chjode l’unghjetta</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duppià l’unghjetta</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">U buttone di cuntatore d’unghjetta in a barra d’attrezzi.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cs/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cs/strings.xml
new file mode 100644
index 0000000000..de8db31078
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cs/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Jeden otevřený panel. Klepnutím panely přepnete.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s otevřených panelů. Klepnutím přepnete panely.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nový panel</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nový anonymní panel</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zavřít panel</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplikovat panel</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Tlačítko s počtem panelů na liště.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cy/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cy/strings.xml
new file mode 100644
index 0000000000..78e83d1611
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-cy/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 tab ar agor. Tapio i newid tabiau.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s tab ar agor. Tapio i newid tabiau.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Tab newydd</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Tab preifat newydd</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Cau tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dyblygu tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Botwm y bar offer cyfrif tabiau.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-da/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-da/strings.xml
new file mode 100644
index 0000000000..15549d060c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-da/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 åbent faneblad. Tryk for at skifte faneblade.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s åbne faneblade. Tryk for at skifte faneblade.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nyt faneblad</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nyt privat faneblad</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Luk faneblad</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Kopier faneblad</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Værktøjslinjeknappen til fanebladstæller.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-de/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-de/strings.xml
new file mode 100644
index 0000000000..69ff81ea3b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-de/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 offener Tab. Antippen, um Tabs zu wechseln.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s offene Tabs. Antippen, um Tabs zu wechseln.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Neuer Tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Neuer privater Tab</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Tab schließen</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Tab klonen</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Die Schaltfläche der Tab-Zähler-Symbolleiste.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-dsb/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-dsb/strings.xml
new file mode 100644
index 0000000000..6eb7e31beb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-dsb/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Wócynjone rejtariki: 1. Pótusniśo, aby rejtariki pśešaltował.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Wócynjone rejtariki: %1$s. Pótusniśo, aby rejtariki pśešaltował.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nowy rejtarik</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nowy priwatny rejtarik</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Rejtarik zacyniś</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Rejtarik pódwójś</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Symbol rejtarikowego licaka na symbolowej rědce.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-el/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-el/strings.xml
new file mode 100644
index 0000000000..9a3eb98254
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-el/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ανοικτή καρτέλα. Πατήστε για εναλλαγή καρτελών.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ανοικτές καρτέλες. Πατήστε για εναλλαγή καρτελών.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Νέα καρτέλα</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Νέα ιδιωτική καρτέλα</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Κλείσιμο καρτέλας</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Αντιγραφή καρτέλας</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Το κουμπί μέτρησης καρτελών της γραμμής εργαλείων.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rCA/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000000..04c14f2b61
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rCA/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 open tab. Tap to switch tabs.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s open tabs. Tap to switch tabs.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">New tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">New private tab</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Close tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicate tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">The tab counter toolbar button.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rGB/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000000..04c14f2b61
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-en-rGB/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 open tab. Tap to switch tabs.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s open tabs. Tap to switch tabs.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">New tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">New private tab</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Close tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicate tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">The tab counter toolbar button.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eo/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eo/strings.xml
new file mode 100644
index 0000000000..8936839830
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eo/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 malfermita langeto. Tuŝetu por ŝanĝi langeton.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s malfermitaj langetoj. Tuŝetu por ŝanĝi langetojn.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nova langeto</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nova privata langeto</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Fermi langeton</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duobligi langeton</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">La ilara butono kun nombro de langetoj.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rAR/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rAR/strings.xml
new file mode 100644
index 0000000000..dccbab6fc8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rAR/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 pestaña abierta. Tocá para cambiar de pestaña.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s pestañas abiertas. Tocá para cambiar de pestaña.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nueva pestaña</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nueva pestaña privada</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Cerrar pestaña</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Pestaña duplicada</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">El botón contador de pestañas de la barra de herramientas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rCL/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rCL/strings.xml
new file mode 100644
index 0000000000..fec84a0de1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rCL/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 pestaña abierta. Toca para cambiar de pestaña.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s pestañas abiertas. Toca para cambiar de pestaña.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nueva pestaña</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nueva pestaña privada</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Cerrar pestaña</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar pestaña</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">El botón contador de pestañas de la barra de herramientas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rES/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rES/strings.xml
new file mode 100644
index 0000000000..fec84a0de1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rES/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 pestaña abierta. Toca para cambiar de pestaña.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s pestañas abiertas. Toca para cambiar de pestaña.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nueva pestaña</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nueva pestaña privada</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Cerrar pestaña</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar pestaña</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">El botón contador de pestañas de la barra de herramientas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rMX/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rMX/strings.xml
new file mode 100644
index 0000000000..fec84a0de1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es-rMX/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 pestaña abierta. Toca para cambiar de pestaña.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s pestañas abiertas. Toca para cambiar de pestaña.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nueva pestaña</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nueva pestaña privada</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Cerrar pestaña</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar pestaña</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">El botón contador de pestañas de la barra de herramientas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000000..fec84a0de1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-es/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 pestaña abierta. Toca para cambiar de pestaña.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s pestañas abiertas. Toca para cambiar de pestaña.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nueva pestaña</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nueva pestaña privada</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Cerrar pestaña</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar pestaña</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">El botón contador de pestañas de la barra de herramientas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-et/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-et/strings.xml
new file mode 100644
index 0000000000..a1dca163dd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-et/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 avatud kaart. Kaartide vahetamiseks puuduta.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s avatud kaarti. Kaartide vahetamiseks puuduta.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Uus kaart</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Uus privaatne kaart</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Sulge kaart</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Klooni kaart</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Kaartide loenduri tööriistariba nupp.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eu/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eu/strings.xml
new file mode 100644
index 0000000000..f2d08959b2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-eu/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Irekitako fitxa bat. Sakatu fitxaz aldatzeko.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Irekitako %1$s fitxa. Sakatu fitxaz aldatzeko.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Fitxa berria</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Fitxa pribatu berria</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Itxi fitxa</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Bikoiztu fitxa</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Fitxen kontagailuaren tresna-barrako botoia.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fa/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fa/strings.xml
new file mode 100644
index 0000000000..75cc015960
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fa/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">۱ زبانهٔ باز. برای تعویض زبانه‌ها ضربه بزنید.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s زبانهٔ باز. برای تغییر زبانه‌ها ضربه بزنید.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">زبانهٔ جدید</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">زبانهٔ خصوصی جدید</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">بستن زبانه</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">تکثیر زبانه</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">دکمهٔ نوار ابزار شمارندهٔ زبانه‌ها.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ff/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ff/strings.xml
new file mode 100644
index 0000000000..c9c6f48e08
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ff/strings.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Tabbere hesere</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Tabbere suuriinde hesere</string>
+ </resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fi/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fi/strings.xml
new file mode 100644
index 0000000000..cd5743f8f5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fi/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 avoin välilehti. Napauta vaihtaaksesi.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s avointa välilehteä. Napauta vaihtaaksesi.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Uusi välilehti</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Uusi yksityinen välilehti</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Sulje välilehti</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Monista välilehti</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Välilehtien laskurin työkalupalkin painike.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fr/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000000..de7950588c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fr/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 onglet ouvert. Appuyez pour changer d’onglet.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s onglets ouverts. Appuyez pour changer d’onglet.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nouvel onglet</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nouvel onglet privé</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Fermer l’onglet</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dupliquer l’onglet</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Le bouton compteur d’onglets de la barre d’outils.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fur/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fur/strings.xml
new file mode 100644
index 0000000000..365119d527
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fur/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 schede vierte. Tocje par cambiâ schede.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s schedis viertis. Tocje par cambiâ schede.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Gnove schede</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Gnove schede privade</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Siere schede</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dupliche schede</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Il boton cul contadôr des schedis te sbare dai struments.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fy-rNL/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fy-rNL/strings.xml
new file mode 100644
index 0000000000..7c6443528e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-fy-rNL/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 iepen ljepblêd. Tik om tusken ljepblêden te wikseljen.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s iepen ljepblêden. Tik om tusken ljepblêden te wikseljen.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nij ljepblêd</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nij priveeljepblêd</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Ljepblêd slute</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Ljepblêd duplisearje</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">De ljepblêdteller-arkbalkeknop.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gd/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gd/strings.xml
new file mode 100644
index 0000000000..b9bbced3ea
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gd/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Tha taba fosgailte. Thoir gnogag airson leum a ghearradh gu taba eile.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Tha tabaichean (%1$s) fosgailte. Thoir gnogag airson leum a ghearradh gu taba eile.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Taba ùr</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Taba prìobhaideach ùr</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Dùin an taba</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dùblaich an taba</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Putan bàr-inneal cunntair nan taba.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gl/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gl/strings.xml
new file mode 100644
index 0000000000..c4112f16fd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gl/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 lapela aberta. Toque para cambiar de lapela.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s lapelas abertas. Toque para cambiar de lapela.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nova lapela</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nova lapela privada</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Pechar lapela</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar o separador</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">O botón da barra de ferramentas do contador de lapelas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gn/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gn/strings.xml
new file mode 100644
index 0000000000..b1fa6062c3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-gn/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 tendayke ijurujáva. Eikutu emoambue hag̃ua tendayke.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s tendayke ijurujáva. Eikutu emoambue hag̃ua tendayke.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Tendayke pyahu</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Tendayke pyahu ñemigua</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Tendayke mboty</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Tendayke ikõiva</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Pe votõ tendayke papaha tembiporu renda pegua.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hi-rIN/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hi-rIN/strings.xml
new file mode 100644
index 0000000000..519a98c230
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hi-rIN/strings.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 खुले टैब। टैब स्विच करने के लिए टैप करें।</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s खुले टैब। टैब स्विच करने के लिए टैप करें।</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">नया टैब</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">नई निजी टैब</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">टैब बंद करें</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">डुप्लीकेट टैब</string>
+ </resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hr/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hr/strings.xml
new file mode 100644
index 0000000000..0233a91fa4
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hr/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 otvorena kartica. Dodirni za prebacivanje kartica.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s otvorene kartice. Dodirni za prebacivanje kartica.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nova kartica</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nova privatna kartica</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zatvori karticu</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dupliciraj karticu</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Tipka brojača kartica na alatnoj traci.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hsb/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hsb/strings.xml
new file mode 100644
index 0000000000..1affc525e1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hsb/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Wočinjene rajtarki: 1. Podótkńće so, zo byšće rajtarki přepinał.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Wočinjene rajtarki: %1$s. Podótkńće so, zo byšće rajtarki přepinał.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nowy rajtark</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nowy priwatny rajtark</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Rajtark začinić</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Rajtark podwojić</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Symbol rajtarkoweho ličaka na symbolowej lajsće.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hu/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hu/strings.xml
new file mode 100644
index 0000000000..abc31799fc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hu/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 nyitott lap. Koppintson a lapváltáshoz.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s nyitott lap. Koppintson a lapváltáshoz.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Új lap</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Új privát lap</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Lap bezárása</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Lap duplikálása</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">A lapszámláló eszköztárgomb.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hy-rAM/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000000..201c4bff6f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-hy-rAM/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 բաց ներդիր: Հպեք՝ ներդիրին անցնելու համար:</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s բաց ներդիրներ: Հպեք՝ ներդիրին անցնելու համար:</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Նոր ներդիր</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Նոր մասնավոր ներդիր</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Փակել ներդիրը</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Կրկնօրինակել ներդիրը</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Ներդիրի հաշվիչի գործիքագոտու կոճակը:</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ia/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ia/strings.xml
new file mode 100644
index 0000000000..2e80e79466
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ia/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 scheda aperte. Tocca pro cambiar le scheda.
+</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s schedas aperte. Tocca pro cambiar le scheda.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nove scheda</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nove scheda private</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Clauder le scheda</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar le scheda</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Le button contator de schedas del barra de instrumentos.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-in/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-in/strings.xml
new file mode 100644
index 0000000000..63a84de095
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-in/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 tab terbuka. Ketuk untuk beralih tab.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s tab terbuka. Ketuk untuk beralih tab.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Tab baru</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Tab pribadi baru</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Tutup tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Gandakan tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Tombol bilah alat penghitung tab.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-is/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-is/strings.xml
new file mode 100644
index 0000000000..85bf97412a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-is/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 opinn flipi. Ýttu til að skipta um flipa.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s opnir flipar. Ýttu til að skipta um flipa.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nýr flipi</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nýr huliðsflipi</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Loka flipa</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Tvítaka flipa</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Flipateljara-hnappurinn á verkfæraslánni.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-it/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-it/strings.xml
new file mode 100644
index 0000000000..bb6ba5c1c4
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-it/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Aperta 1 scheda. Tocca per cambiare scheda.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Aperte %1$s schede. Tocca per cambiare scheda.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nuova scheda</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nuova scheda anonima</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Chiudi scheda</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplica scheda</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Il pulsante nella barra degli strumenti con il numero di schede</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-iw/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-iw/strings.xml
new file mode 100644
index 0000000000..57d4a70de1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-iw/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">לשונית אחת פתוחה. יש להקיש כדי להחליף לשוניות.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s לשוניות פתוחות. יש להקיש כדי להחליף לשוניות.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">לשונית חדשה</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">לשונית פרטית חדשה</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">סגירת לשונית</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">שכפול לשונית</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">כפתור סרגל הכלים של מונה הלשוניות.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ja/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ja/strings.xml
new file mode 100644
index 0000000000..9780a8380f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ja/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">開いているタブ 1 個。タップしてタブを切り替えます。</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">開いているタブ %1$s 個。タップしてタブを切り替えます。</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">新しいタブ</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">新しいプライベートタブ</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">タブを閉じる</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">タブを複製</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">タブカウンターのツールバーボタンです。</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ka/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ka/strings.xml
new file mode 100644
index 0000000000..00d535442e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ka/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 გახსნილი ჩანართი. შეეხეთ ჩანართების გადასართველად.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s გახსნილი ჩანართი. შეეხეთ ჩანართების გადასართველად.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">ახალი ჩანართი</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">ახალი პირადი ჩანართი</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ჩანართის დახურვა</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ჩანართის გაორმაგება</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ჩანართის მრიცხველის ღილაკი სამართავ ზოლზე.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kaa/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kaa/strings.xml
new file mode 100644
index 0000000000..5854750cf2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kaa/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 bet ashıq. Basqa betlerge ótiw ushın basıń.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s bet ashıq. Basqa betlerge ótiw ushın basıń.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Jańa bet</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Jańa jeke bet</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Betti jabıw</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Betti nusqalaw</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Ásbaplar panelinde betler sanaw túymesi.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kab/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kab/strings.xml
new file mode 100644
index 0000000000..e3c1f477b6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kab/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 yiccer i yeldin. Sit akken ad tbeddleḍ iccer.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s waccaren yeldin. Sit akken ad tettbeddileḍ gar waccaren.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Iccer amaynut</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Iccer uslig amaynut</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Mdel iccer</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Sleg iccer</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Taqeffalt n ugalis n yifecka n umesmiḍan n waccaren.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kk/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kk/strings.xml
new file mode 100644
index 0000000000..0149ee5e5c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kk/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ашық бет. Беттерді ауыстыру үшін шертіңіз.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ашық бет. Беттерді ауыстыру үшін шертіңіз.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Жаңа бет</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Жаңа жекелік беті</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Бетті жабу</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Бетті қосарлау</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Беттер санағышы болатын панель батырмасы.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kmr/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kmr/strings.xml
new file mode 100644
index 0000000000..d05d912cb7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-kmr/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 hilpekîna vekirî. Ji bo hilpekînê biguherînî, bitikîne.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s hilpekînên vekirî. Ji bo hilpekînê biguherînî, bitikîne.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Hilpekîna nû</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Hilpekîna veşartî ya nû</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Hilpekînê bigire</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Hilpekînê zêde bike</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Bişkoka darikê amûran a jimarkera hilpekînan.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ko/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ko/strings.xml
new file mode 100644
index 0000000000..4811b27a84
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ko/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">열린 탭 1개. 탭을 전환하려면 누르세요.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">열린 탭 %1$s개. 탭을 전환하려면 누르세요.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">새 탭</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">새 사생활 보호 탭</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">탭 닫기</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">탭 복제</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">탭 카운터 도구 모음 버튼입니다.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lo/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lo/strings.xml
new file mode 100644
index 0000000000..a82e9d6e4e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lo/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ເປີດແທັບ. ແຕະເພື່ອປ່ຽນແທັບ.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ເປີດແທັບ. ແຕະເພື່ອປ່ຽນແທັບ.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">ແທັບໃຫມ່</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">ແທັບສ່ວນໂຕໃຫມ່</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ປິດແທັບ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ແທັບທີ່ຊໍ້າກັນ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ປຸ່ມແຖບເຄື່ອງມື ໂຕນັບແຖບ.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lt/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lt/strings.xml
new file mode 100644
index 0000000000..9b592c0023
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-lt/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 atverta kortelė. Bakstelėkite, norėdami pereiti tarp kortelių.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s atvertos kortelės. Bakstelėkite, norėdami pereiti tarp kortelių.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nauja kortelė</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nauja privačioji kortelė</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Užverti kortelę</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dubliuoti kortelę</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Kortelių skaičiaus mygtukas priemonių juostoje.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-my/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-my/strings.xml
new file mode 100644
index 0000000000..13d029ac49
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-my/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">ဖွင့်ထားသော တပ်ဗ် 1 ။ တပ်ဗ်များ ပြောင်းရန် နှိပ်ပါ။ </string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">ဖွင့်ထားသော တပ်ဗ်များ %1$s ။ တက်ဗ်များ ပြောင်းရန် နှိပ်ပါ။ </string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">တပ်ဗ် အသစ်</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">ကိုယ်ပိုင် သီးသန့် တက်ဗ် အသစ်</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">တပ်ဗ်ကို ပိတ်ပါ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">တပ်ဗ်ကို ပွားပါ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">တပ်ဗ် ကောင်တာ တူးဘား ခလုတ်</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nb-rNO/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nb-rNO/strings.xml
new file mode 100644
index 0000000000..941a1a5647
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nb-rNO/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 åpen fane. Trykk for å bytte fane.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s åpne faner. Trykk for å bytte fane.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Ny fane</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Ny privat fane</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Lukk fane</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dupliser fane</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Fane-teller verktøylinjeknapp.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ne-rNP/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000000..b0458adc54
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ne-rNP/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ट्याब खोल्नुहोस् । ट्याबहरु बिचमा स्वीच गर्नको लागि ट्याप गर्नुहोस् ।</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ट्याबहरु खोल्नुहोस् । ट्याबहरु बिचमा स्वीच गर्नको लागि ट्याप गर्नुहोस् ।</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">नयाँ ट्याब</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">नयाँ निजी ट्याब</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ट्याब बन्द गर्नुहोस्</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">नक्कल ट्याब</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ट्याब काउन्टर उपकरणपट्टी बटन् ।</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nl/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nl/strings.xml
new file mode 100644
index 0000000000..e34f69d0bc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nl/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 open tabblad. Tik om tussen tabbladen te wisselen.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s open tabbladen. Tik om tussen tabbladen te wisselen.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nieuw tabblad</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nieuw privétabblad</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Tabblad sluiten</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Tabblad dupliceren</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">De tabbladteller-werkbalkknop.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nn-rNO/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nn-rNO/strings.xml
new file mode 100644
index 0000000000..71cd5c74de
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-nn-rNO/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 open fane. Trykk for å byte fane.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s opne faner. Trykk for å byte fane.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Ny fane</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Ny privat fane</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Lat att fane</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dupliser fane</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Fane-teljar verktøylinjeknapp.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-oc/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-oc/strings.xml
new file mode 100644
index 0000000000..78c7d4501e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-oc/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 onglet dubèrt. Tocatz per bascular.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s onglets dubèrts. Tocatz per bascular.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Onglet novèl</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Onglet de nav. privada</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Tampar l’onglet</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar l’onglet</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Lo boton comptador d’onglets de la barra d’aisinas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-or/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-or/strings.xml
new file mode 100644
index 0000000000..5405b5f6e0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-or/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">ନୂଆ ଟ୍ୟାବ୍</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">ନୂଆ ବ୍ୟକ୍ତିଗତ ଟ୍ୟାବ୍</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ଟ୍ୟାବ୍ ବନ୍ଦ କରନ୍ତୁ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ଟ୍ୟାବ୍ ନକଲ କରନ୍ତୁ</string>
+ </resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rIN/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000000..68a1578f17
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rIN/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ਟੈਬ ਖੁੱਲ੍ਹੀ ਹੈ। ਟੈਬਾਂ ਵਿੱਚ ਬਦਲਣ ਲਈ ਛੂਹੋ।</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ਟੈਬਾਂ ਖੁੱਲ੍ਹੀਆਂ। ਟੈਬਾਂ ਵਿੱਚ ਸਵਿੱਚ ਕਰਨ ਵਾਸਤੇ ਟੈਪ ਕਰੋ।</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">ਨਵੀਂ ਟੈਬ</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">ਨਵੀਂ ਨਿੱਜੀ ਟੈਬ</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ਟੈਬ ਬੰਦ ਕਰੋ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ਡੁਪਲੀਕੇਟ ਟੈਬ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ਟੈਬ ਗਿਣਤੀ ਟੂਲ-ਪੱਟੀ ਬਟਨ ਹੈ।</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rPK/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rPK/strings.xml
new file mode 100644
index 0000000000..a91863a90b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pa-rPK/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">اک ٹیب کھُلھی اے۔ ہورناں ٹیب جاوݨ لئی اِتھے چھوہو۔</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ٹیباں کھُلھیاں ہن۔ ہورناں ٹیب جاوݨ لئی اِتھے چھوہو۔</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">نویں ٹیب کھولھو</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">نجی ٹیب کھولھو</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ٹیب بند کرو</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ٹیب کاپی کرو</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ٹیب دی گݨتی والا بٹن اے۔</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pl/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pl/strings.xml
new file mode 100644
index 0000000000..6179d81a5a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pl/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Otwarte karty: 1. Stuknij, aby przełączyć karty.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Otwarte karty: %1$s. Stuknij, aby przełączyć karty.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nowa karta</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nowa karta prywatna</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zamknij kartę</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplikuj kartę</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Przycisk paska narzędzi z liczbą kart.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rBR/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000000..0f4f87ffab
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 aba aberta. Toque para alternar abas.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s abas abertas. Toque para alternar abas.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nova aba</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nova aba privativa</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Fechar aba</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar aba</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">O botão contador de abas da barra de ferramentas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rPT/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000000..9abddce5aa
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-pt-rPT/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 separador aberto. Toque para mudar de separador.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s separadores abertos. Toque para mudar de separadores.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Novo separador</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Novo separador privado</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Fechar separador</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicar separador</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">O botão da barra de ferramentas com o número de separadores.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-rm/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-rm/strings.xml
new file mode 100644
index 0000000000..4a162573f2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-rm/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 tab avert. Tutgar per midar tab.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s tabs averts. Tutgar per midar tab.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nov tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nov tab privat</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Serrar il tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplitgar il tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Il buttun en la trav d\'utensils cun il dumber da tabs.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml
new file mode 100644
index 0000000000..e2726988b1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 filă deschisă. Atinge pentru a comuta între file.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s file deschise. Atinge pentru a comuta între file.</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Filă privată nouă</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Închide fila</string>
+ </resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ru/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ru/strings.xml
new file mode 100644
index 0000000000..dcde495148
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ru/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 открытая вкладка. Нажмите, чтобы переключить вкладки.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Открытых вкладок: %1$s. Нажмите, чтобы переключить вкладки.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Новая вкладка</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Новая приватная вкладка</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Закрыть вкладку</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Дублировать вкладку</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Кнопка счётчика вкладок на панели инструментов.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sat/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sat/strings.xml
new file mode 100644
index 0000000000..a6878d4562
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sat/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ᱠᱷᱩᱞᱟᱹ ᱴᱮᱵᱽ ᱾ ᱴᱮᱵᱽ ᱠᱚ ᱥᱣᱤᱪ ᱞᱟᱹᱜᱤᱫ ᱚᱛᱟᱭ ᱢᱮ ᱾</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ᱠᱷᱩᱞᱟᱹ ᱴᱮᱵᱽᱠᱚ ᱾ ᱴᱮᱵᱽᱠᱚ ᱥᱣᱤᱪ ᱞᱟᱹᱜᱤᱫ ᱚᱛᱟᱭ ᱢᱮ ᱾</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">ᱱᱟᱶᱟ ᱴᱮᱵᱽ</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">ᱱᱟᱶᱟ ᱱᱤᱡᱮᱨᱟᱠ ᱴᱮᱵᱽ</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ᱴᱮᱵᱽ ᱵᱚᱸᱫᱽᱚᱭ ᱢᱮ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ᱰᱩᱯᱞᱤᱠᱮᱴ ᱴᱮᱵᱽ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ᱴᱮᱵᱽ ᱠᱟᱣᱱᱴᱟᱹᱨ ᱴᱩᱞᱵᱟᱨ ᱵᱩᱛᱟᱹᱢ ᱾</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sc/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sc/strings.xml
new file mode 100644
index 0000000000..d19f2c5d25
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sc/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ischeda aberta. Toca pro cuncambiare ischedas.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ischedas abertas. Toca pro cuncambiare ischedas.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Ischeda noa</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Ischeda privada noa</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Serra s’ischeda</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Dùplica s’ischeda</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Su butone de su contadore de ischedas de sa barra de ainas.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-si/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-si/strings.xml
new file mode 100644
index 0000000000..783718eb2c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-si/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">විවෘත පටිති 1. මාරු වීමට ඔබන්න.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">විවෘත පටිති %1$s. මාරු වීමට ඔබන්න.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">නව පටිත්ත</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">නව පෞද්. පටිත්ත</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">පටිත්ත වසන්න</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">පටිත්තෙහි අනුපිටපතක්</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">පටිති ගණනය මෙවලම් තීරු බොත්තම.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sk/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sk/strings.xml
new file mode 100644
index 0000000000..5f8dc12703
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sk/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 otvorená karta. Ťuknutím prepnete karty.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s otvorených kariet. Ťuknutím prepnete karty.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nová karta</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nová súkromná karta</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zavrieť kartu</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplikovať kartu</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Tlačidlo počítadla kariet na paneli nástrojov.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-skr/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-skr/strings.xml
new file mode 100644
index 0000000000..b4315df355
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-skr/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">١ ٹیب کھولو۔ ٹیبز بدلݨ کیتے دباؤ۔</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ٹیبز کھولو۔ ٹیبز بدلݨ کیتے دباؤ۔</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">نواں ٹیب</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">نویں نجی ٹیب</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ٹیب بند کرو</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">واڳی ٹیب</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ٹیباں ڳݨݨ آلا ٹولبار بٹݨ۔</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sl/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sl/strings.xml
new file mode 100644
index 0000000000..fe24fbb221
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sl/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 odprt zavihek. Tapnite za preklop zavihkov.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Odprtih zavihkov: %1$s. Tapnite za preklop zavihkov.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nov zavihek</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nov zasebni zavihek</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zapri zavihek</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Podvoji zavihek</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Gumb števca zavihkov v orodni vrstici.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sq/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sq/strings.xml
new file mode 100644
index 0000000000..a17e1ece9d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sq/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 skedë e hapur. Prekeni që të ndërroni skeda.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s skeda të hapura. Prekeni që të ndërroni skeda.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Skedë e re</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Skedë e re private</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Mbylle skedën</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Përdytëso skedën</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Butoni i numrit të skedave te paneli.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sr/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sr/strings.xml
new file mode 100644
index 0000000000..7963c5b8f8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sr/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 отворени језичак. Додирни за пребацивање језичака.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s отворених језичака. Додирни за пребацивање језичака.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Нови језичак</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Нови приватни језичак</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Затвори језичак</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Удвостручи језичак</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Дугме за бројач језичака.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-su/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-su/strings.xml
new file mode 100644
index 0000000000..fdc4401b78
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-su/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 tab muka. Toél pikeun pindah tab.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s tab muka. Toél pikeun pindah tab.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Tab anyar</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Tab nyamuni anyar</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Tutup tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplikat tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Tombol tulbar pangitung tab.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sv-rSE/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sv-rSE/strings.xml
new file mode 100644
index 0000000000..bed22b6674
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-sv-rSE/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 öppen flik. Tryck för att växla mellan flikar.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s öppna flikar. Tryck för att växla mellan flikar.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Ny flik</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Ny privat flik</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Stäng flik</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicera flik</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Verktygsfältknapp för flikräknare.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-szl/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-szl/strings.xml
new file mode 100644
index 0000000000..abdc3c96f5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-szl/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">Jedna ôtwarto karta. Tyknij, coby przełōnczyć karty.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">Ôtwarte karty: %1$s. Tyknij, coby je zmiynić.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Nowo karta</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Nowo prywatno karta</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Zawrzij karta</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Tupluj karta</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Knefel z poskym z noczyniami do rachowanio kart. </string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-te/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-te/strings.xml
new file mode 100644
index 0000000000..056d3aebcd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-te/strings.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 తెరిచివున్న ట్యాబు. ట్యాబుల మధ్య మారడానికి తాకండి.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s తెరిచివున్న ట్యాబులు. ట్యాబుల మధ్య మారడానికి తాకండి.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">కొత్త ట్యాబు</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">కొత్త అంతరంగిక ట్యాబు</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ట్యాబును మూసివేయి</string>
+ </resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tg/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tg/strings.xml
new file mode 100644
index 0000000000..950305d610
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tg/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 варақаи кушода. Барои гузариш байни варақаҳо, зарба занед.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s варақаи кушода. Барои гузариш байни варақаҳо, зарба занед.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Варақаи нав</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Варақаи хусусии нав</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Пӯшидани варақа</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Такроран кушодани варақа</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Тугмаи ҳисобкунаки варақаҳо дар навори абзорҳо.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-th/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-th/strings.xml
new file mode 100644
index 0000000000..cee1d74cd6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-th/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 แท็บที่เปิด แตะเพื่อสลับไปยังแท็บ</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s แท็บที่เปิด แตะเพื่อสลับไปยังแท็บ</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">แท็บใหม่</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">แท็บส่วนตัวใหม่</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ปิดแท็บ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">ทำสำเนาแท็บ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ปุ่มแถบเครื่องมือตัวนับแท็บ</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tl/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tl/strings.xml
new file mode 100644
index 0000000000..ca7ef24882
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tl/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 nakabukas na tab. I-tap para lumipat ng tab.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s nakabukas na tab. I-tap para lumipat ng tab.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Bagong tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Bagong pribadong tab</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Isara ang tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Kaparehong tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Ang toolbar button para sa bilang ng tab.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tr/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tr/strings.xml
new file mode 100644
index 0000000000..896b18dbf7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tr/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 açık sekme. Sekme değiştirmek için dokunun.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s açık sekme. Sekme değiştirmek için dokunun.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Yeni sekme</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Yeni gizli sekme</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Sekmeyi kapat</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Sekmeyi çoğalt</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Sekme sayacı araç çubuğu düğmesi.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-trs/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-trs/strings.xml
new file mode 100644
index 0000000000..732c0ebab6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-trs/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 nā\'nïn rakïj ñanj. Gūru\'man ra\'a da\' nādūnāt rakïj ñanj.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s nā\'nïn nej rakïj ñanj. Gūru\'man ra\'a da\' nādūnāt nej rakïj ñanj.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Rakïj ñanj nākàa</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Rakïj ñaj nākà gārasun \'ngō rïn\'</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Narán rakïj ñanj</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Rakïj ñanj nata’a</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Butûn riña ‘na’ nej dukuán ahia nej si rāsun nej rakïj ñanj.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tt/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tt/strings.xml
new file mode 100644
index 0000000000..d89b5bbbaa
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tt/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ачык таб. Табларны күчерү өчен басыгыз.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ачык таб. Табларны күчерү өчен басыгыз.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Яңа таб</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Яңа хосусый таб</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Табны ябу</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Табны кабатлау</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Кораллар панелендәге таблар cанагычы төймәсе.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tzm/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tzm/strings.xml
new file mode 100644
index 0000000000..3ca40446d7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-tzm/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Aseksel amaynu</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Aseksel uslig amaynu</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Mdel aseksel</string>
+ </resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ug/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ug/strings.xml
new file mode 100644
index 0000000000..a2a92a2c73
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ug/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 بەتكۈچ ئوچۇق. بەتكۈچنى ئالماشتۇرۇش ئۈچۈن چېكىڭ.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s بەتكۈچ ئوچۇق. بەتكۈچنى ئالماشتۇرۇش ئۈچۈن چېكىڭ.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">يېڭى بەتكۈچ</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">يېڭى شەخسىي بەتكۈچ</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">بەتكۈچنى تاقاش</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">تەكرار بەتكۈچ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">بەتكۈچ سانىغۇچ قورال بالداق توپچىسى.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uk/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000000..1f46eb3d93
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uk/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 відкрита вкладка. Торкніться, щоб перемкнути вкладки.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s відкритих вкладок. Торкніться, щоб перемкнути вкладки.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Нова вкладка</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Нова приватна вкладка</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Закрити вкладку</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Дублювати вкладку</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Кнопка панелі інструментів лічильника вкладок.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ur/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ur/strings.xml
new file mode 100644
index 0000000000..da3b2630ae
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-ur/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 کھلا ٹیب۔ ٹیبز بدلنے کے لئے دبائیں۔</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s کھلے ٹیب۔ ٹیب بدلنے کے لئے دبائیں۔</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">نیا ٹیب</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">نیا نجی ٹیب</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">ٹیب بند کریں</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">دوهرا ٹیب</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">ٹیب کاؤنٹر ٹول بار کا بٹن۔</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uz/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uz/strings.xml
new file mode 100644
index 0000000000..a9b46408c3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-uz/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 ta ochiq varaq. Boshqa varaqqa oʻtish uchun bosing.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s ta ochiq varaq. Boshqa varaqqa oʻtish uchun bosing.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Yangi varaq</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Yangi maxfiy varaq</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Varaqni yopish</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Varaqni nusxalash</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Asboblar panelidagi varaq taymer tugmasi.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-vi/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-vi/strings.xml
new file mode 100644
index 0000000000..af59036db1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-vi/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 thẻ đang mở. Chạm để chuyển thẻ.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s thẻ đang mở. Chạm để chuyển thẻ.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Thẻ mới</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Thẻ riêng tư mới</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Đóng thẻ</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Nhân đôi thẻ</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Nút thanh công cụ bộ đếm thẻ.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-yo/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-yo/strings.xml
new file mode 100644
index 0000000000..13d72778f6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-yo/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 sí táàbù. Tẹ̀ ẹ́ láti bọ́ sí àwọn táàbù.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s sí táàbù. Tẹ̀ ẹ́ láti bọ́ sí àwọn táàbù.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">Táàbù tuntun</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">Táàbù ìkọ̀kọ̀ tuntun</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Pa táàbù dé</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Ẹ̀dà táàbù</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">Táàbù náà rí bọ́tìnì irinṣé.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rCN/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000000..c2a979f9d5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rCN/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">打开了 1 个标签页,点击即可切换。</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">打开了 %1$s 个标签页,点击即可切换。</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">新建标签页</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">新建隐私标签页</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">关闭标签页</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">克隆标签页</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">标签页计数器工具栏按钮。</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rTW/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000000..ef18d2a974
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">開啟了 1 個分頁,點擊即可切換分頁。</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">開啟了 %1$s 個分頁,點擊即可切換分頁。</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">開新分頁</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">開新隱私分頁</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">關閉分頁</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">複製分頁</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">分頁計數器工具列按鈕。</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/attrs.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..70195f2198
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/attrs.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+
+ <declare-styleable name="TabCounter">
+ <attr name="tabCounterTintColor" format="reference|color" />
+ </declare-styleable>
+
+</resources> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/colors.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..f01e0ca318
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/colors.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <color name="mozac_ui_tabcounter_default_tint">#FF272727</color>
+ <color name="mozac_ui_tabcounter_private_tint">#FFFFFF</color>
+ <color name="mozac_ui_tabcounter_default_text">#20123A</color>
+</resources> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/dimens.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..e247e31552
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/dimens.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<resources>
+ <dimen name="mozac_tab_counter_box_width_height">24dp</dimen>
+</resources> \ No newline at end of file
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/strings.xml b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..b63520c1a0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <!-- Message announced to the user when tab tray is selected with 1 tab -->
+ <string name="mozac_tab_counter_open_tab_tray_single">1 open tab. Tap to switch tabs.</string>
+ <!-- Message announced to the user when tab tray is selected with multiple tabs -->
+ <string name="mozac_tab_counter_open_tab_tray_plural">%1$s open tabs. Tap to switch tabs.</string>
+ <!-- Browser menu button that creates a new tab -->
+ <string name="mozac_browser_menu_new_tab">New tab</string>
+ <!-- Browser menu button that creates a private tab -->
+ <string name="mozac_browser_menu_new_private_tab">New private tab</string>
+ <!-- Browser menu button to close tab. Closes the current session when pressed. -->
+ <string name="mozac_close_tab">Close tab</string>
+ <!-- Menu option to duplicate the current tab -->
+ <string name="mozac_ui_tabcounter_duplicate_tab">Duplicate tab</string>
+ <!-- Content description of the tab counter toolbar button -->
+ <string name="mozac_tab_counter_content_description">The tab counter toolbar button.</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterMenuTest.kt b/mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterMenuTest.kt
new file mode 100644
index 0000000000..40ec54066b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterMenuTest.kt
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.tabcounter
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidJUnit4::class)
+class TabCounterMenuTest {
+
+ @Test
+ fun `return only the new tab item`() {
+ val onItemTapped: (TabCounterMenu.Item) -> Unit = spy { Unit }
+ val menu = TabCounterMenu(testContext, onItemTapped)
+
+ val item = menu.newTabItem
+ assertEquals("New tab", item.text)
+ item.onClick()
+
+ verify(onItemTapped).invoke(TabCounterMenu.Item.NewTab)
+ }
+
+ @Test
+ fun `return only the new private tab item`() {
+ val onItemTapped: (TabCounterMenu.Item) -> Unit = spy { Unit }
+ val menu = TabCounterMenu(testContext, onItemTapped)
+
+ val item = menu.newPrivateTabItem
+ assertEquals("New private tab", item.text)
+ item.onClick()
+
+ verify(onItemTapped).invoke(TabCounterMenu.Item.NewPrivateTab)
+ }
+
+ @Test
+ fun `return a close button`() {
+ val onItemTapped: (TabCounterMenu.Item) -> Unit = spy { Unit }
+ val menu = TabCounterMenu(testContext, onItemTapped)
+
+ val item = menu.closeTabItem
+ assertEquals("Close tab", item.text)
+ item.onClick()
+
+ verify(onItemTapped).invoke(TabCounterMenu.Item.CloseTab)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterTest.kt b/mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterTest.kt
new file mode 100644
index 0000000000..881a19e47a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/test/java/mozilla/components/ui/tabcounter/TabCounterTest.kt
@@ -0,0 +1,70 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.tabcounter
+
+import android.content.res.ColorStateList
+import android.view.LayoutInflater
+import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import mozilla.components.ui.tabcounter.TabCounter.Companion.SO_MANY_TABS_OPEN
+import mozilla.components.ui.tabcounter.databinding.MozacUiTabcounterLayoutBinding
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class TabCounterTest {
+
+ private lateinit var tabCounter: TabCounter
+ private lateinit var binding: MozacUiTabcounterLayoutBinding
+
+ @Before
+ fun setUp() {
+ tabCounter = TabCounter(testContext)
+ binding =
+ MozacUiTabcounterLayoutBinding.inflate(LayoutInflater.from(testContext), tabCounter)
+ }
+
+ @Test
+ fun `Default tab count is set to zero`() {
+ assertEquals("0", binding.counterText.text)
+ }
+
+ @Test
+ fun `Set tab count as single digit value shows count`() {
+ tabCounter.setCount(1)
+ assertEquals("1", binding.counterText.text)
+ }
+
+ @Test
+ fun `Set tab count as two digit number shows count`() {
+ tabCounter.setCount(99)
+ assertEquals("99", binding.counterText.text)
+ }
+
+ @Test
+ fun `Setting tab count as three digit value shows correct icon`() {
+ tabCounter.setCount(100)
+ assertEquals(SO_MANY_TABS_OPEN, binding.counterText.text)
+ }
+
+ @Test
+ fun `Setting tab color shows correct icon`() {
+ val colorStateList: ColorStateList = mock()
+
+ tabCounter.setColor(colorStateList)
+ assertEquals(binding.counterText.textColors, colorStateList)
+ }
+
+ @Test
+ fun `Toggling the counterMask will set the mask to visible`() {
+ assertEquals(binding.counterMask.visibility, View.GONE)
+ tabCounter.toggleCounterMask(true)
+ assertEquals(binding.counterMask.visibility, View.VISIBLE)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/mobile/android/android-components/components/ui/tabcounter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000..cf1c399ea8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1,2 @@
+mock-maker-inline
+// This allows mocking final classes (classes are final by default in Kotlin)
diff --git a/mobile/android/android-components/components/ui/tabcounter/src/test/resources/robolectric.properties b/mobile/android/android-components/components/ui/tabcounter/src/test/resources/robolectric.properties
new file mode 100644
index 0000000000..932b01b9eb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/tabcounter/src/test/resources/robolectric.properties
@@ -0,0 +1 @@
+sdk=28
diff --git a/mobile/android/android-components/components/ui/widgets/README.md b/mobile/android/android-components/components/ui/widgets/README.md
new file mode 100644
index 0000000000..524ef9d794
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/README.md
@@ -0,0 +1,19 @@
+# [Android Components](../../../README.md) > UI > Widgets
+
+The standard set of Mozilla widgets.
+
+## Usage
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:ui-widgets:{latest-version}"
+```
+
+## License
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/
diff --git a/mobile/android/android-components/components/ui/widgets/build.gradle b/mobile/android/android-components/components/ui/widgets/build.gradle
new file mode 100644
index 0000000000..e1ccc51159
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/build.gradle
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ namespace 'mozilla.components.ui.widgets'
+}
+
+dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
+ implementation project(':concept-base')
+ implementation project(':concept-engine')
+ implementation project(':ui-colors')
+ implementation project(':ui-icons')
+ implementation project(':support-ktx')
+ implementation project(':concept-toolbar')
+
+ implementation ComponentsDependencies.androidx_appcompat
+ implementation ComponentsDependencies.androidx_constraintlayout
+ implementation ComponentsDependencies.androidx_core_ktx
+ implementation ComponentsDependencies.google_material
+ implementation ComponentsDependencies.androidx_swiperefreshlayout
+
+ testImplementation project(":support-test")
+ testImplementation project(':support-test-fakes')
+
+ testImplementation ComponentsDependencies.androidx_test_junit
+ testImplementation ComponentsDependencies.testing_robolectric
+}
+
+apply from: '../../../android-lint.gradle'
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description)
diff --git a/mobile/android/android-components/components/ui/widgets/proguard-rules.pro b/mobile/android/android-components/components/ui/widgets/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/AndroidManifest.xml b/mobile/android/android-components/components/ui/widgets/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e16cda1d34
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<manifest />
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/Extentions.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/Extentions.kt
new file mode 100644
index 0000000000..fb17b7eb5a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/Extentions.kt
@@ -0,0 +1,37 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets
+
+import android.widget.TextView
+import android.view.View.TEXT_ALIGNMENT_CENTER as CENTER
+
+/**
+ * A shortcut to align buttons' text to center inside AlertDialog.
+ */
+fun androidx.appcompat.app.AlertDialog.withCenterAlignedButtons(): androidx.appcompat.app.AlertDialog {
+ findViewById<TextView>(android.R.id.button1)?.let { it.textAlignment = CENTER }
+ findViewById<TextView>(android.R.id.button2)?.let { it.textAlignment = CENTER }
+ findViewById<TextView>(android.R.id.button3)?.let { it.textAlignment = CENTER }
+ return this
+}
+
+/**
+ * A shortcut to align buttons' text to center inside AlertDialog.
+ *
+ * Important: On Android API levels lower than 24, this method must be called only AFTER the dialog
+ * has been shown. Calling this method prior to displaying the dialog on those API levels will cause
+ * partial initialization of the view, leading to a crash.
+ *
+ * Usage example:
+ * dialog.setOnShowListener {
+ * dialog.withCenterAlignedButtons()
+ * }
+ */
+fun android.app.AlertDialog.withCenterAlignedButtons(): android.app.AlertDialog {
+ findViewById<TextView>(android.R.id.button1)?.let { it.textAlignment = CENTER }
+ findViewById<TextView>(android.R.id.button2)?.let { it.textAlignment = CENTER }
+ findViewById<TextView>(android.R.id.button3)?.let { it.textAlignment = CENTER }
+ return this
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/SnackbarDelegate.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/SnackbarDelegate.kt
new file mode 100644
index 0000000000..8e2dd2fad7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/SnackbarDelegate.kt
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets
+
+import android.view.View
+import com.google.android.material.snackbar.Snackbar
+
+/**
+ * Delegate to display a snackbar.
+ */
+interface SnackbarDelegate {
+ /**
+ * Displays a snackbar.
+ *
+ * @param snackBarParentView The view to find a parent from for displaying the Snackbar.
+ * @param text The text to show. Can be formatted text.
+ * @param duration How long to display the message.
+ * @param action String resource to display for the action.
+ * @param listener callback to be invoked when the action is clicked.
+ */
+ fun show(
+ snackBarParentView: View,
+ text: Int,
+ duration: Int,
+ action: Int = 0,
+ listener: ((v: View) -> Unit)? = null,
+ )
+}
+
+/**
+ * Default implementation for [SnackbarDelegate]. Will display a standard default Snackbar.
+ */
+class DefaultSnackbarDelegate : SnackbarDelegate {
+ override fun show(
+ snackBarParentView: View,
+ text: Int,
+ duration: Int,
+ action: Int,
+ listener: ((v: View) -> Unit)?,
+ ) {
+ val snackbar = Snackbar.make(
+ snackBarParentView,
+ text,
+ duration,
+ )
+
+ if (action != 0 && listener != null) {
+ snackbar.setAction(action, listener)
+ }
+
+ snackbar.show()
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayout.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayout.kt
new file mode 100644
index 0000000000..aa8bc10b67
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayout.kt
@@ -0,0 +1,216 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewConfiguration
+import androidx.annotation.VisibleForTesting
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import kotlin.math.abs
+
+/**
+ * [SwipeRefreshLayout] that filters only vertical scrolls for triggering pull to refresh.
+ *
+ * Following situations will not trigger pull to refresh:
+ * - a scroll happening more on the horizontal axis
+ * - a scale in/out gesture
+ * - a quick scale gesture
+ *
+ * To control responding to scrolls and showing the pull to refresh throbber or not
+ * use the [View.isEnabled] property.
+ */
+class VerticalSwipeRefreshLayout @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+) : SwipeRefreshLayout(context, attrs) {
+ @VisibleForTesting
+ internal var isQuickScaleInProgress = false
+
+ @VisibleForTesting
+ internal var quickScaleEvents = QuickScaleEvents()
+ private var previousX = 0f
+ private var previousY = 0f
+ private val doubleTapTimeout = ViewConfiguration.getDoubleTapTimeout()
+ private val doubleTapSlop = ViewConfiguration.get(context).scaledDoubleTapSlop
+ private val doubleTapSlopSquare = doubleTapSlop * doubleTapSlop
+
+ @VisibleForTesting
+ internal var hadMultiTouch: Boolean = false
+
+ @VisibleForTesting
+ internal var disallowInterceptTouchEvent = false
+
+ @Suppress("ComplexMethod", "ReturnCount")
+ override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
+ // Setting "isEnabled = false" is recommended for users of this ViewGroup
+ // who who are not interested in the pull to refresh functionality
+ // Setting this easily avoids executing code unneededsly before the check for "canChildScrollUp".
+ if (!isEnabled || disallowInterceptTouchEvent) {
+ return false
+ }
+
+ if (MotionEvent.ACTION_DOWN == event.action) {
+ hadMultiTouch = false
+ }
+
+ // Layman's scale gesture (with two fingers) detector.
+ // Allows for quick, serial inference as opposed to using ScaleGestureDetector
+ // which uses callbacks and would be hard to synchronize in the little time we have.
+ if (event.pointerCount > 1 || hadMultiTouch) {
+ hadMultiTouch = true
+ return false
+ }
+
+ val eventAction = event.action
+
+ // Cleanup if the gesture has been aborted or quick scale just ended/
+ if (MotionEvent.ACTION_CANCEL == eventAction ||
+ (MotionEvent.ACTION_UP == eventAction && isQuickScaleInProgress)
+ ) {
+ forgetQuickScaleEvents()
+ return callSuperOnInterceptTouchEvent(event)
+ }
+
+ // Disable pull to refresh if quick scale is in progress.
+ maybeAddDoubleTapEvent(event)
+ if (isQuickScaleInProgress(quickScaleEvents)) {
+ isQuickScaleInProgress = true
+ return false
+ }
+
+ // Disable pull to refresh if the move was more on the X axis.
+ if (MotionEvent.ACTION_DOWN == eventAction) {
+ previousX = event.x
+ previousY = event.y
+ } else if (MotionEvent.ACTION_MOVE == eventAction) {
+ val xDistance = abs(event.x - previousX)
+ val yDistance = abs(event.y - previousY)
+ previousX = event.x
+ previousY = event.y
+ if (xDistance > yDistance) {
+ return false
+ }
+ }
+
+ return callSuperOnInterceptTouchEvent(event)
+ }
+
+ override fun onStartNestedScroll(child: View, target: View, nestedScrollAxes: Int): Boolean {
+ // Ignoring nested scrolls from descendants.
+ // Allowing descendants to trigger nested scrolls would defeat the purpose of this class
+ // and result in pull to refresh to happen for all movements on the Y axis
+ // (even as part of scale/quick scale gestures) while also doubling the throbber with the overscroll shadow.
+ return if (isEnabled) {
+ return false
+ } else {
+ callSuperOnStartNestedScroll(child, target, nestedScrollAxes)
+ }
+ }
+
+ @SuppressLint("Recycle") // we do recycle the events in forgetQuickScaleEvents()
+ @VisibleForTesting
+ internal fun maybeAddDoubleTapEvent(event: MotionEvent) {
+ val currentEventAction = event.action
+
+ // A double tap event must follow the order:
+ // ACTION_DOWN - ACTION_UP - ACTION_DOWN
+ // all these events happening in an interval defined by a system constant - DOUBLE_TAP_TIMEOUT
+
+ if (MotionEvent.ACTION_DOWN == currentEventAction) {
+ if (quickScaleEvents.upEvent != null) {
+ if (event.eventTime - quickScaleEvents.upEvent!!.eventTime > doubleTapTimeout) {
+ // Too much time passed for the MotionEvents sequence to be considered
+ // a quick scale gesture. Restart counting.
+ forgetQuickScaleEvents()
+ quickScaleEvents.firstDownEvent = MotionEvent.obtain(event)
+ } else {
+ quickScaleEvents.secondDownEvent = MotionEvent.obtain(event)
+ }
+ } else {
+ // This may be the first time the user touches the screen or
+ // the gesture was not finished with ACTION_UP.
+ forgetQuickScaleEvents()
+ quickScaleEvents.firstDownEvent = MotionEvent.obtain(event)
+ }
+ }
+ // For the double tap events series we need ACTION_DOWN first
+ // and then ACTION_UP second.
+ else if (MotionEvent.ACTION_UP == currentEventAction && quickScaleEvents.firstDownEvent != null) {
+ quickScaleEvents.upEvent = MotionEvent.obtain(event)
+ }
+ }
+
+ override fun requestDisallowInterceptTouchEvent(b: Boolean) {
+ // We need to disable Pull to Refresh on this layout be we don't want to propagate the
+ // request to the parent, because they may use the gesture for other purpose, like
+ // propagating it to ToolbarBehavior
+ this.disallowInterceptTouchEvent = b
+ }
+
+ @VisibleForTesting
+ internal fun forgetQuickScaleEvents() {
+ quickScaleEvents.firstDownEvent?.recycle()
+ quickScaleEvents.upEvent?.recycle()
+ quickScaleEvents.secondDownEvent?.recycle()
+ quickScaleEvents.firstDownEvent = null
+ quickScaleEvents.upEvent = null
+ quickScaleEvents.secondDownEvent = null
+
+ isQuickScaleInProgress = false
+ }
+
+ @VisibleForTesting
+ internal fun isQuickScaleInProgress(events: QuickScaleEvents): Boolean {
+ return if (events.isNotNull()) {
+ isQuickScaleInProgress(events.firstDownEvent!!, events.upEvent!!, events.secondDownEvent!!)
+ } else {
+ false
+ }
+ }
+
+ // Method closely following GestureDetectorCompat#isConsideredDoubleTap.
+ // Allows for serial inference of double taps as opposed to using callbacks.
+ @VisibleForTesting
+ internal fun isQuickScaleInProgress(
+ firstDown: MotionEvent,
+ firstUp: MotionEvent,
+ secondDown: MotionEvent,
+ ): Boolean {
+ if (secondDown.eventTime - firstUp.eventTime > doubleTapTimeout) {
+ return false
+ }
+
+ val deltaX = firstDown.x.toInt() - secondDown.x.toInt()
+ val deltaY = firstDown.y.toInt() - secondDown.y.toInt()
+
+ return deltaX * deltaX + deltaY * deltaY < doubleTapSlopSquare
+ }
+
+ @VisibleForTesting
+ internal fun callSuperOnInterceptTouchEvent(event: MotionEvent) =
+ super.onInterceptTouchEvent(event)
+
+ @VisibleForTesting
+ internal fun callSuperOnStartNestedScroll(child: View, target: View, nestedScrollAxes: Int) =
+ super.onStartNestedScroll(child, target, nestedScrollAxes)
+
+ private fun QuickScaleEvents.isNotNull(): Boolean {
+ return firstDownEvent != null && upEvent != null && secondDownEvent != null
+ }
+
+ /**
+ * Wrapper over the MotionEvents that compose a quickScale gesture.
+ */
+ @VisibleForTesting
+ internal data class QuickScaleEvents(
+ var firstDownEvent: MotionEvent? = null,
+ var upEvent: MotionEvent? = null,
+ var secondDownEvent: MotionEvent? = null,
+ )
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/WidgetSiteItemView.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/WidgetSiteItemView.kt
new file mode 100644
index 0000000000..0eca198957
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/WidgetSiteItemView.kt
@@ -0,0 +1,106 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets
+
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.FrameLayout
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.appcompat.content.res.AppCompatResources.getDrawable
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.isVisible
+
+/**
+ * Shared UI widget for showing a website in a list of websites,
+ * such as in bookmarks, history, site exceptions, or collections.
+ */
+class WidgetSiteItemView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+ private val labelView: TextView by lazy { findViewById<TextView>(R.id.label) }
+ private val captionView: TextView by lazy { findViewById<TextView>(R.id.caption) }
+ private val iconWrapper: FrameLayout by lazy { findViewById<FrameLayout>(R.id.favicon_wrapper) }
+ private val secondaryButton: ImageButton by lazy { findViewById<ImageButton>(R.id.secondary_button) }
+
+ /**
+ * ImageView that should display favicons.
+ */
+ val iconView: ImageView by lazy { findViewById<ImageView>(R.id.favicon) }
+
+ init {
+ LayoutInflater.from(context).inflate(R.layout.mozac_widget_site_item, this, true)
+ }
+
+ /**
+ * Sets the text displayed inside of the site item view.
+ *
+ * @param label Main label text, such as a site title.
+ * @param caption Sub caption text, such as a URL. If null, the caption is hidden.
+ */
+ fun setText(label: CharSequence, caption: CharSequence?) {
+ labelView.text = label
+ captionView.text = caption
+ captionView.isVisible = caption != null
+ }
+
+ /**
+ * Add a view that will overlay the favicon, such as a checkmark.
+ */
+ fun addIconOverlay(overlay: View) {
+ iconWrapper.addView(overlay)
+ }
+
+ /**
+ * Add a secondary button, such as an overflow menu.
+ *
+ * @param icon Drawable to display in the button.
+ * @param contentDescription Accessible description of the button's purpose.
+ * @param onClickListener Listener called when the button is clicked.
+ */
+ fun setSecondaryButton(
+ icon: Drawable?,
+ contentDescription: CharSequence,
+ onClickListener: (View) -> Unit,
+ ) {
+ secondaryButton.isVisible = true
+ secondaryButton.setImageDrawable(icon)
+ secondaryButton.contentDescription = contentDescription
+ secondaryButton.setOnClickListener(onClickListener)
+ }
+
+ /**
+ * Add a secondary button, such as an overflow menu.
+ *
+ * @param icon Drawable to display in the button.
+ * @param contentDescription Accessible description of the button's purpose.
+ * @param onClickListener Listener called when the button is clicked.
+ */
+ fun setSecondaryButton(
+ @DrawableRes icon: Int,
+ @StringRes contentDescription: Int,
+ onClickListener: (View) -> Unit,
+ ) = setSecondaryButton(
+ icon = getDrawable(context, icon),
+ contentDescription = context.getString(contentDescription),
+ onClickListener = onClickListener,
+ )
+
+ /**
+ * Removes the secondary button if it was previously set in [setSecondaryButton].
+ */
+ fun removeSecondaryButton() {
+ secondaryButton.isVisible = false
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetector.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetector.kt
new file mode 100644
index 0000000000..b15df65078
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetector.kt
@@ -0,0 +1,192 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.content.Context
+import android.view.GestureDetector
+import android.view.MotionEvent
+import android.view.ScaleGestureDetector
+import androidx.annotation.VisibleForTesting
+import mozilla.components.concept.base.crash.CrashReporting
+import kotlin.math.abs
+
+/**
+ * Wraps exceptions that are caught by [BrowserGestureDetector].
+ * Instances of this class are submitted via [CrashReporting]. This wrapping helps easily identify
+ * exceptions related to [BrowserGestureDetector].
+ */
+internal class BrowserGestureDetectorException(e: Throwable) : Throwable(e)
+
+/**
+ * Custom [MotionEvent] gestures detector with scroll / zoom callbacks.
+ *
+ * Favors zoom gestures in detriment of the scroll gestures with:
+ * - higher sensitivity for multi-finger zoom gestures
+ * - ignoring scrolls if zoom is in progress
+ *
+ * @param applicationContext context used for registering internal gesture listeners.
+ * @param listener client interested in zoom / scroll events.
+ */
+internal class BrowserGestureDetector(
+ applicationContext: Context,
+ listener: GesturesListener,
+ private val crashReporting: CrashReporting? = null,
+) {
+ @VisibleForTesting
+ internal var gestureDetector = GestureDetector(
+ applicationContext,
+ CustomScrollDetectorListener { previousEvent: MotionEvent?, currentEvent: MotionEvent, distanceX, distanceY ->
+ run {
+ listener.onScroll?.invoke(distanceX, distanceY)
+
+ // We got many crashes because of the initial event - ACTION_DOWN being null.
+ // Investigations to be continued in android-components/issues/8552.
+ // In the meantime we'll protect against this with a simple null check.
+ if (previousEvent != null) {
+ if (abs(currentEvent.y - previousEvent.y) >= abs(currentEvent.x - previousEvent.x)) {
+ listener.onVerticalScroll?.invoke(distanceY)
+ } else {
+ listener.onHorizontalScroll?.invoke(distanceX)
+ }
+ }
+ }
+ },
+ )
+
+ @VisibleForTesting
+ internal var scaleGestureDetector = ScaleGestureDetector(
+ applicationContext,
+ CustomScaleDetectorListener(
+ listener.onScaleBegin ?: {},
+ listener.onScale ?: {},
+ listener.onScaleEnd ?: {},
+ ),
+ )
+
+ /**
+ * Accepts MotionEvents and dispatches zoom / scroll events to the registered listener when appropriate.
+ *
+ * Applications should pass a complete and consistent event stream to this method.
+ * A complete and consistent event stream involves all MotionEvents from the initial ACTION_DOWN
+ * to the final ACTION_UP or ACTION_CANCEL.
+ *
+ * @return if the event was handled by any of the registered detectors
+ */
+ @Suppress("ComplexCondition")
+ internal fun handleTouchEvent(event: MotionEvent): Boolean {
+ val eventAction = event.actionMasked
+
+ // A double tap for a quick scale gesture (quick double tap followed by a drag)
+ // would trigger a ACTION_CANCEL event before the MOVE_EVENT.
+ // This would prevent the scale detector from properly inferring the movement.
+ // We'll want to ignore ACTION_CANCEL but process the next stream of events.
+ if (eventAction != MotionEvent.ACTION_CANCEL) {
+ scaleGestureDetector.onTouchEvent(event)
+ }
+
+ // Ignore scrolling if zooming is already in progress.
+ // Always pass motion begin / end events just to have the detector ready
+ // to infer scrolls when the scale gesture ended.
+ return if (!scaleGestureDetector.isInProgress ||
+ eventAction == MotionEvent.ACTION_DOWN ||
+ eventAction == MotionEvent.ACTION_UP ||
+ eventAction == MotionEvent.ACTION_CANCEL
+ ) {
+ @Suppress("TooGenericExceptionCaught")
+ try {
+ gestureDetector.onTouchEvent(event)
+ } catch (e: Exception) {
+ crashReporting?.submitCaughtException(BrowserGestureDetectorException(e))
+ false
+ }
+ } else {
+ false
+ }
+ }
+
+ /**
+ * A convenience containing listeners for zoom / scroll events
+ *
+ * Provide implementation for the events you are interested in.
+ * The others will be no-op.
+ */
+ internal class GesturesListener(
+ /**
+ * Responds to scroll events for a gesture in progress.
+ * The distance in x and y is also supplied for convenience.
+ */
+ val onScroll: ((distanceX: Float, distanceY: Float) -> Unit)? = { _, _ -> run {} },
+
+ /**
+ * Responds to an in progress scroll occuring more on the vertical axis.
+ * The scroll distance is also supplied for convenience.
+ */
+ val onVerticalScroll: ((distance: Float) -> Unit)? = {},
+
+ /**
+ * Responds to an in progress scroll occurring more on the horizontal axis.
+ * The scroll distance is also supplied for convenience.
+ */
+ val onHorizontalScroll: ((distance: Float) -> Unit)? = {},
+
+ /**
+ * Responds to the the beginning of a new scale gesture.
+ * Reported by new pointers going down.
+ */
+ val onScaleBegin: ((scaleFactor: Float) -> Unit)? = {},
+
+ /**
+ * Responds to scaling events for a gesture in progress.
+ * The scaling factor is also supplied for convenience.
+ * This value is represents the difference from the previous scale event to the current event.
+ */
+ val onScale: ((scaleFactor: Float) -> Unit)? = {},
+
+ /**
+ * Responds to the end of a scale gesture.
+ * Reported by existing pointers going up.
+ */
+ val onScaleEnd: ((scaleFactor: Float) -> Unit)? = {},
+ )
+
+ private class CustomScrollDetectorListener(
+ val onScrolling: (
+ previousEvent: MotionEvent?,
+ currentEvent: MotionEvent,
+ distanceX: Float,
+ distanceY: Float,
+ ) -> Unit,
+ ) : GestureDetector.SimpleOnGestureListener() {
+ override fun onScroll(
+ e1: MotionEvent?,
+ e2: MotionEvent,
+ distanceX: Float,
+ distanceY: Float,
+ ): Boolean {
+ onScrolling(e1, e2, distanceX, distanceY)
+ return true
+ }
+ }
+
+ private class CustomScaleDetectorListener(
+ val onScaleBegin: (scaleFactor: Float) -> Unit = {},
+ val onScale: (scaleFactor: Float) -> Unit = {},
+ val onScaleEnd: (scaleFactor: Float) -> Unit = {},
+ ) : ScaleGestureDetector.SimpleOnScaleGestureListener() {
+ override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
+ onScaleBegin(detector.scaleFactor)
+ return true
+ }
+
+ override fun onScale(detector: ScaleGestureDetector): Boolean {
+ onScale(detector.scaleFactor)
+ return true
+ }
+
+ override fun onScaleEnd(detector: ScaleGestureDetector) {
+ onScaleEnd(detector.scaleFactor)
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt
new file mode 100644
index 0000000000..d0f532bfbc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt
@@ -0,0 +1,90 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import androidx.annotation.VisibleForTesting
+import androidx.coordinatorlayout.widget.CoordinatorLayout
+import mozilla.components.concept.engine.EngineView
+import mozilla.components.concept.toolbar.ScrollableToolbar
+import mozilla.components.support.ktx.android.view.findViewInHierarchy
+import kotlin.math.roundToInt
+
+/**
+ * A [CoordinatorLayout.Behavior] implementation that allows the [EngineView] to automatically
+ * size itself in relation to the Y translation of the [ScrollableToolbar].
+ *
+ * This is useful for dynamic [ScrollableToolbar]s ensuring the web content is displayed immediately
+ * below / above the toolbar even when that is animated.
+ *
+ * @param context [Context] used for various Android interactions
+ * @param attrs XML set attributes configuring this
+ * @param engineViewParent NestedScrollingChild parent of the [EngineView]
+ * @param toolbarHeight size of [ScrollableToolbar] when it is placed above the [EngineView]
+ * @param toolbarPosition whether the [ScrollableToolbar] is placed above or below the [EngineView]
+ */
+class EngineViewClippingBehavior(
+ context: Context?,
+ attrs: AttributeSet?,
+ engineViewParent: View,
+ toolbarHeight: Int,
+ toolbarPosition: ToolbarPosition,
+) : CoordinatorLayout.Behavior<View>(context, attrs) {
+
+ @VisibleForTesting
+ internal val engineView = engineViewParent.findViewInHierarchy { it is EngineView } as EngineView?
+
+ @VisibleForTesting
+ internal var toolbarChangedAction: (Float) -> Unit?
+ private val bottomToolbarChangedAction = { newToolbarTranslationY: Float ->
+ if (!newToolbarTranslationY.isNaN()) {
+ engineView?.setVerticalClipping(-newToolbarTranslationY.roundToInt())
+ }
+ }
+ private val topToolbarChangedAction = { newToolbarTranslationY: Float ->
+ // the top toolbar is translated upwards when collapsing-> all values received are 0 or negative
+ engineView?.let {
+ it.setVerticalClipping(newToolbarTranslationY.roundToInt())
+ // Need to add the toolbarHeight to effectively place the engineView below the toolbar.
+ engineViewParent.translationY = newToolbarTranslationY + toolbarHeight
+ }
+ }
+
+ init {
+ toolbarChangedAction = if (toolbarPosition == ToolbarPosition.TOP) {
+ topToolbarChangedAction
+ } else {
+ bottomToolbarChangedAction
+ }
+ }
+
+ override fun layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
+ if (dependency is ScrollableToolbar) {
+ return true
+ }
+
+ return super.layoutDependsOn(parent, child, dependency)
+ }
+
+ /**
+ * Apply vertical clipping to [EngineView]. This requires [EngineViewClippingBehavior] to be set
+ * in/on the [EngineView] or its parent. Must be a direct descending child of [CoordinatorLayout].
+ */
+ override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
+ toolbarChangedAction.invoke(dependency.translationY)
+
+ return true
+ }
+}
+
+/**
+ * Where the toolbar is placed on the screen.
+ */
+enum class ToolbarPosition {
+ TOP,
+ BOTTOM,
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt
new file mode 100644
index 0000000000..08da7e5064
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt
@@ -0,0 +1,237 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import androidx.annotation.VisibleForTesting
+import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.core.view.ViewCompat
+import mozilla.components.concept.base.crash.CrashReporting
+import mozilla.components.concept.engine.EngineView
+import mozilla.components.support.ktx.android.view.findViewInHierarchy
+
+/**
+ * Where the view is placed on the screen.
+ */
+enum class ViewPosition {
+ TOP,
+ BOTTOM,
+}
+
+/**
+ * A [CoordinatorLayout.Behavior] implementation to be used when placing [View] at the bottom of the screen.
+ *
+ * This is safe to use even if the [View] may be added / removed from a parent layout later
+ * or if it could have Visibility.GONE set.
+ *
+ * This implementation will:
+ * - Show/Hide the [View] automatically when scrolling vertically.
+ * - Snap the [View] to be hidden or visible when the user stops scrolling.
+ */
+class EngineViewScrollingBehavior(
+ val context: Context?,
+ attrs: AttributeSet?,
+ private val viewPosition: ViewPosition,
+ private val crashReporting: CrashReporting? = null,
+) : CoordinatorLayout.Behavior<View>(context, attrs) {
+ // This implementation is heavily based on this blog article:
+ // https://android.jlelse.eu/scroll-your-bottom-navigation-view-away-with-10-lines-of-code-346f1ed40e9e
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal var shouldSnapAfterScroll: Boolean = false
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal var startedScroll = false
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal var isScrollEnabled = false
+
+ /**
+ * Reference to [EngineView] used to check user's [android.view.MotionEvent]s.
+ */
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal var engineView: EngineView? = null
+
+ /**
+ * Reference to the actual [View] that we'll animate.
+ */
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal var dynamicScrollView: View? = null
+
+ /**
+ * Depending on how user's touch was consumed by EngineView / current website,
+ *
+ * we will animate the dynamic navigation bar if:
+ * - touches were used for zooming / panning operations in the website.
+ *
+ * We will do nothing if:
+ * - the website is not scrollable
+ * - the website handles the touch events itself through it's own touch event listeners.
+ */
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal val shouldScroll: Boolean
+ get() = engineView?.getInputResultDetail()?.let {
+ (it.canScrollToBottom() || it.canScrollToTop()) && isScrollEnabled
+ } ?: false
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal var gesturesDetector: BrowserGestureDetector = createGestureDetector()
+
+ @VisibleForTesting
+ internal var yTranslator: ViewYTranslator = createYTranslationStrategy()
+
+ private fun createYTranslationStrategy() = ViewYTranslator(viewPosition)
+
+ override fun onStartNestedScroll(
+ coordinatorLayout: CoordinatorLayout,
+ child: View,
+ directTargetChild: View,
+ target: View,
+ axes: Int,
+ type: Int,
+ ): Boolean {
+ return if (dynamicScrollView != null) {
+ startNestedScroll(axes, type, child)
+ } else {
+ return false // not interested in subsequent scroll events
+ }
+ }
+
+ override fun onStopNestedScroll(
+ coordinatorLayout: CoordinatorLayout,
+ child: View,
+ target: View,
+ type: Int,
+ ) {
+ if (dynamicScrollView != null) {
+ stopNestedScroll(type, child)
+ }
+ }
+
+ override fun onInterceptTouchEvent(
+ parent: CoordinatorLayout,
+ child: View,
+ ev: MotionEvent,
+ ): Boolean {
+ if (dynamicScrollView != null) {
+ gesturesDetector.handleTouchEvent(ev)
+ }
+ return false // allow events to be passed to below listeners
+ }
+
+ override fun onLayoutChild(
+ parent: CoordinatorLayout,
+ child: View,
+ layoutDirection: Int,
+ ): Boolean {
+ dynamicScrollView = child
+ engineView = parent.findViewInHierarchy { it is EngineView } as? EngineView
+
+ return super.onLayoutChild(parent, child, layoutDirection)
+ }
+
+ /**
+ * Used to expand the [View]
+ */
+ fun forceExpand(view: View) {
+ yTranslator.expandWithAnimation(view)
+ }
+
+ /**
+ * Used to collapse the [View]
+ */
+ fun forceCollapse(view: View) {
+ yTranslator.collapseWithAnimation(view)
+ }
+
+ /**
+ * Allow this view to be animated.
+ *
+ * @see disableScrolling
+ */
+ fun enableScrolling() {
+ isScrollEnabled = true
+ }
+
+ /**
+ * Disable scrolling of the view irrespective of the intrinsic checks.
+ *
+ * @see enableScrolling
+ */
+ fun disableScrolling() {
+ isScrollEnabled = false
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal fun tryToScrollVertically(distance: Float) {
+ dynamicScrollView?.let { view ->
+ if (shouldScroll && startedScroll) {
+ yTranslator.translate(view, distance)
+ } else if (engineView?.getInputResultDetail()?.isTouchHandlingUnknown() == false) {
+ // Force expand the view if the user scrolled up, it is not already expanded and
+ // an animation to expand it is not already in progress,
+ // otherwise the user could get stuck in a state where they cannot show the view
+ // See https://github.com/mozilla-mobile/android-components/issues/7101
+ yTranslator.forceExpandIfNotAlready(view, distance)
+ }
+ }
+ }
+
+ /**
+ * Helper function to ease testing.
+ * (Re)Initializes the [BrowserGestureDetector] in a new context.
+ *
+ * Useful in spied behaviors, to ensure callbacks are of the spy and not of the initially created object
+ * if the passed in argument is the result of [createGestureDetector].
+ */
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal fun initGesturesDetector(detector: BrowserGestureDetector) {
+ gesturesDetector = detector
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal fun createGestureDetector() =
+ BrowserGestureDetector(
+ context!!,
+ BrowserGestureDetector.GesturesListener(
+ onVerticalScroll = ::tryToScrollVertically,
+ onScaleBegin = {
+ // Scale shouldn't animate the view but a small y translation is still possible
+ // because of a previous scroll. Try to be swift about such an in progress animation.
+ yTranslator.snapImmediately(dynamicScrollView)
+ },
+ ),
+ crashReporting = crashReporting,
+ )
+
+ @VisibleForTesting
+ internal fun startNestedScroll(axes: Int, type: Int, view: View): Boolean {
+ return if (shouldScroll && axes == ViewCompat.SCROLL_AXIS_VERTICAL) {
+ startedScroll = true
+ shouldSnapAfterScroll = type == ViewCompat.TYPE_TOUCH
+ yTranslator.cancelInProgressTranslation()
+ true
+ } else if (engineView?.getInputResultDetail()?.isTouchUnhandled() == true) {
+ // Force expand the view if event is unhandled, otherwise user could get stuck in a
+ // state where they cannot show the view
+ yTranslator.cancelInProgressTranslation()
+ yTranslator.expandWithAnimation(view)
+ false
+ } else {
+ false
+ }
+ }
+
+ @VisibleForTesting
+ internal fun stopNestedScroll(type: Int, view: View) {
+ startedScroll = false
+ if (shouldSnapAfterScroll || type == ViewCompat.TYPE_NON_TOUCH) {
+ yTranslator.snapWithAnimation(view)
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt
new file mode 100644
index 0000000000..8311f2d21a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt
@@ -0,0 +1,189 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.animation.ValueAnimator
+import android.view.View
+import android.view.animation.DecelerateInterpolator
+import androidx.annotation.VisibleForTesting
+import kotlin.math.max
+import kotlin.math.min
+
+@VisibleForTesting
+internal const val SNAP_ANIMATION_DURATION = 150L
+
+/**
+ * Helper class with methods for different behaviors for when translating a [View] on the Y axis.
+ */
+internal abstract class ViewYTranslationStrategy {
+ @VisibleForTesting
+ var animator = ValueAnimator().apply {
+ interpolator = DecelerateInterpolator()
+ duration = SNAP_ANIMATION_DURATION
+ }
+
+ /**
+ * Snap the [View] to be collapsed or expanded, depending on whatever state is closer
+ * over a short amount of time.
+ */
+ abstract fun snapWithAnimation(view: View)
+
+ /**
+ * Snap the [View] to be collapsed or expanded, depending on whatever state is closer immediately.
+ */
+ abstract fun snapImmediately(view: View?)
+
+ /**
+ * Translate the [View] to it's full visible height.
+ */
+ abstract fun expandWithAnimation(view: View)
+
+ /**
+ * Force expanding the [View] depending on the [distance] value that should be translated
+ * cancelling any other translation already in progress.
+ */
+ abstract fun forceExpandWithAnimation(view: View, distance: Float)
+
+ /**
+ * Translate the [View] to it's full 0 visible height.
+ */
+ abstract fun collapseWithAnimation(view: View)
+
+ /**
+ * Translate [view] immediately to the specified [distance] amount (positive or negative).
+ */
+ abstract fun translate(view: View, distance: Float)
+
+ /**
+ * Translate [view] to the indicated [targetTranslationY] vaue over a short amount of time.
+ */
+ open fun animateToTranslationY(view: View, targetTranslationY: Float) = with(animator) {
+ addUpdateListener { view.translationY = it.animatedValue as Float }
+ setFloatValues(view.translationY, targetTranslationY)
+ start()
+ }
+
+ /**
+ * Cancel any translation animations currently in progress.
+ */
+ fun cancelInProgressTranslation() = animator.cancel()
+}
+
+/**
+ * Helper class containing methods for translating a [View] on the Y axis
+ * between 0 and [View.getHeight]
+ */
+internal class BottomViewBehaviorStrategy : ViewYTranslationStrategy() {
+ @VisibleForTesting
+ internal var wasLastExpanding = false
+
+ override fun snapWithAnimation(view: View) {
+ if (view.translationY >= (view.height / 2f)) {
+ collapseWithAnimation(view)
+ } else {
+ expandWithAnimation(view)
+ }
+ }
+
+ override fun snapImmediately(view: View?) {
+ if (animator.isStarted) {
+ animator.end()
+ } else {
+ view?.apply {
+ translationY = if (translationY >= height / 2) {
+ height.toFloat()
+ } else {
+ 0f
+ }
+ }
+ }
+ }
+
+ override fun expandWithAnimation(view: View) {
+ animateToTranslationY(view, 0f)
+ }
+
+ override fun forceExpandWithAnimation(view: View, distance: Float) {
+ val shouldExpandToolbar = distance < 0
+ val isToolbarExpanded = view.translationY == 0f
+ if (shouldExpandToolbar && !isToolbarExpanded && !wasLastExpanding) {
+ animator.cancel()
+ expandWithAnimation(view)
+ }
+ }
+
+ override fun collapseWithAnimation(view: View) {
+ animateToTranslationY(view, view.height.toFloat())
+ }
+
+ override fun translate(view: View, distance: Float) {
+ view.translationY =
+ max(0f, min(view.height.toFloat(), view.translationY + distance))
+ }
+
+ override fun animateToTranslationY(view: View, targetTranslationY: Float) {
+ wasLastExpanding = targetTranslationY <= view.translationY
+ super.animateToTranslationY(view, targetTranslationY)
+ }
+}
+
+/**
+ * Helper class containing methods for translating a [View] on the Y axis
+ * between -[View.getHeight] and 0.
+ */
+internal class TopViewBehaviorStrategy : ViewYTranslationStrategy() {
+ @VisibleForTesting
+ internal var wasLastExpanding = false
+
+ override fun snapWithAnimation(view: View) {
+ if (view.translationY >= -(view.height / 2f)) {
+ expandWithAnimation(view)
+ } else {
+ collapseWithAnimation(view)
+ }
+ }
+
+ override fun snapImmediately(view: View?) {
+ if (animator.isStarted) {
+ animator.end()
+ } else {
+ view?.apply {
+ translationY = if (translationY >= -height / 2) {
+ 0f
+ } else {
+ -height.toFloat()
+ }
+ }
+ }
+ }
+
+ override fun expandWithAnimation(view: View) {
+ animateToTranslationY(view, 0f)
+ }
+
+ override fun forceExpandWithAnimation(view: View, distance: Float) {
+ val isExpandingInProgress = animator.isStarted && wasLastExpanding
+ val shouldExpandToolbar = distance < 0
+ val isToolbarExpanded = view.translationY == 0f
+ if (shouldExpandToolbar && !isToolbarExpanded && !isExpandingInProgress) {
+ animator.cancel()
+ expandWithAnimation(view)
+ }
+ }
+
+ override fun collapseWithAnimation(view: View) {
+ animateToTranslationY(view, -view.height.toFloat())
+ }
+
+ override fun translate(view: View, distance: Float) {
+ view.translationY =
+ min(0f, max(-view.height.toFloat(), view.translationY - distance))
+ }
+
+ override fun animateToTranslationY(view: View, targetTranslationY: Float) {
+ wasLastExpanding = targetTranslationY >= view.translationY
+ super.animateToTranslationY(view, targetTranslationY)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt
new file mode 100644
index 0000000000..042b810b40
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.view.View
+import androidx.annotation.VisibleForTesting
+
+/**
+ * Helper class with methods for translating on the Y axis a top / bottom [View].
+ *
+ * @param viewPosition whether the view is displayed immediately at the top of the screen or
+ * immediately at the bottom. This affects how it will be translated:
+ * - if place at the bottom it will be Y translated between 0 and [View.getHeight]
+ * - if place at the top it will be Y translated between -[View.getHeight] and 0
+ */
+class ViewYTranslator(viewPosition: ViewPosition) {
+ @VisibleForTesting
+ internal var strategy = getTranslationStrategy(viewPosition)
+
+ /**
+ * Snap the [View] to be collapsed or expanded, depending on whatever state is closer
+ * over a short amount of time.
+ */
+ internal fun snapWithAnimation(view: View) {
+ strategy.snapWithAnimation(view)
+ }
+
+ /**
+ * Snap the [View] to be collapsed or expanded, depending on whatever state is closer immediately.
+ */
+ fun snapImmediately(view: View?) {
+ strategy.snapImmediately(view)
+ }
+
+ /**
+ * Translate the [View] to it's full visible height over a short amount of time.
+ */
+ internal fun expandWithAnimation(view: View) {
+ strategy.expandWithAnimation(view)
+ }
+
+ /**
+ * Translate the [View] to be hidden from view over a short amount of time.
+ */
+ internal fun collapseWithAnimation(view: View) {
+ strategy.collapseWithAnimation(view)
+ }
+
+ /**
+ * Force expanding the [View] depending on the [distance] value that should be translated
+ * cancelling any other translation already in progress.
+ */
+ fun forceExpandIfNotAlready(view: View, distance: Float) {
+ strategy.forceExpandWithAnimation(view, distance)
+ }
+
+ /**
+ * Translate [view] immediately to the specified [distance] amount (positive or negative).
+ */
+ fun translate(view: View, distance: Float) {
+ strategy.translate(view, distance)
+ }
+
+ /**
+ * Cancel any translation animations currently in progress.
+ */
+ fun cancelInProgressTranslation() {
+ strategy.cancelInProgressTranslation()
+ }
+
+ @VisibleForTesting
+ internal fun getTranslationStrategy(viewPosition: ViewPosition): ViewYTranslationStrategy {
+ return if (viewPosition == ViewPosition.TOP) {
+ TopViewBehaviorStrategy()
+ } else {
+ BottomViewBehaviorStrategy()
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/drawable/mozac_widget_favicon_background.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/drawable/mozac_widget_favicon_background.xml
new file mode 100644
index 0000000000..93e6f01141
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/drawable/mozac_widget_favicon_background.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:shape="rectangle">
+ <corners android:radius="4dp" />
+ <solid
+ android:color="?mozac_widget_favicon_background_color"
+ tools:color="@color/photonWhite" />
+ <stroke
+ android:width="1dp"
+ android:color="?mozac_widget_favicon_border_color"
+ tools:color="@color/photonLightGrey30" />
+</shape>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/drawable/rounded_button_background.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/drawable/rounded_button_background.xml
new file mode 100644
index 0000000000..260a02530d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/drawable/rounded_button_background.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <shape>
+ <solid android:color="#000000" />
+ <corners android:radius="4dp" />
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="4dp" />
+ </shape>
+ </item>
+</ripple>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/layout/mozac_widget_site_item.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/layout/mozac_widget_site_item.xml
new file mode 100644
index 0000000000..3ddfd7a2c3
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/layout/mozac_widget_site_item.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/mozac_widget_site_item_height"
+ android:background="?android:attr/selectableItemBackground">
+
+ <FrameLayout
+ android:id="@+id/favicon_wrapper"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ app:layout_constraintHorizontal_chainStyle="spread_inside"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/label">
+ <ImageView
+ android:id="@+id/favicon"
+ style="@style/Mozac.Widgets.Favicon"
+ android:importantForAccessibility="no"
+ tools:src="@android:drawable/ic_secure" />
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/label"
+ style="@style/Mozac.Widgets.SiteItem.Label"
+ android:layout_width="0dp"
+ tools:textColor="#20123A"
+ tools:text="Example site"
+ app:layout_goneMarginEnd="16dp"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/caption"
+ app:layout_constraintStart_toEndOf="@id/favicon_wrapper"
+ app:layout_constraintEnd_toStartOf="@id/secondary_button"
+ app:layout_constraintVertical_chainStyle="packed" />
+
+ <TextView
+ android:id="@+id/caption"
+ style="@style/Mozac.Widgets.SiteItem.Caption"
+ android:layout_width="0dp"
+ android:layout_marginTop="2dp"
+ tools:text="https://example.com/"
+ tools:textColor="@color/photonLightGrey90"
+ app:layout_constraintEnd_toEndOf="@id/label"
+ app:layout_constraintStart_toStartOf="@id/label"
+ app:layout_constraintTop_toBottomOf="@id/label"
+ app:layout_constraintBottom_toBottomOf="parent" />
+
+ <ImageButton
+ android:id="@+id/secondary_button"
+ android:layout_width="@dimen/mozac_widget_site_item_secondary_button_size"
+ android:layout_height="@dimen/mozac_widget_site_item_secondary_button_size"
+ android:padding="@dimen/mozac_widget_site_item_secondary_button_padding"
+ android:layout_marginStart="12dp"
+ android:layout_marginEnd="12dp"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:visibility="gone"
+ tools:visibility="visible"
+ tools:src="@drawable/mozac_ic_ellipsis_vertical_24"
+ tools:ignore="ContentDescription"
+ tools:tint="#20123A"
+ app:tint="?attr/mozac_primary_text_color"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/label"
+ app:layout_constraintEnd_toEndOf="parent" />
+
+</merge>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-am/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-am/strings.xml
new file mode 100644
index 0000000000..cdde258cef
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-am/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">ምስል ወደ ቅንጥብ ሰሌዳ ተቀድቷል</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ar/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ar/strings.xml
new file mode 100644
index 0000000000..eb2045ed67
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ar/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">نُسخت الصورة إلى الحافظة</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ast/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ast/strings.xml
new file mode 100644
index 0000000000..013fbec0b8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ast/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">La imaxe copióse al cartafueyu</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-azb/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-azb/strings.xml
new file mode 100644
index 0000000000..706d647459
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-azb/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">عکس کلیپ‌بوردا کوپی اولدو</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-be/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-be/strings.xml
new file mode 100644
index 0000000000..7096e05e05
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-be/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Відарыс скапіяваны ў буфер абмену</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-bg/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-bg/strings.xml
new file mode 100644
index 0000000000..9c2defef43
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-bg/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Изображението е копирано</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-br/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-br/strings.xml
new file mode 100644
index 0000000000..3ae6d8340a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-br/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Skeudenn eilet er golver</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-bs/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-bs/strings.xml
new file mode 100644
index 0000000000..b0e64d0437
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-bs/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Slika je kopirana u privremenu memoriju</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ca/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ca/strings.xml
new file mode 100644
index 0000000000..75a4596b48
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ca/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">S’ha copiat la imatge al porta-retalls</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-cak/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-cak/strings.xml
new file mode 100644
index 0000000000..dee19cb2a1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-cak/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Xwachib\'ëx ri wachib\'äl pa molwuj</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-co/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-co/strings.xml
new file mode 100644
index 0000000000..dc5ae642c1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-co/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Fiura cupiata in u preme’papei</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-cs/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-cs/strings.xml
new file mode 100644
index 0000000000..039f1848dc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-cs/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Obrázek zkopírován do schránky</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-cy/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-cy/strings.xml
new file mode 100644
index 0000000000..274e4c8a92
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-cy/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Copïwyd delwedd i’r clipfwrdd</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-da/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-da/strings.xml
new file mode 100644
index 0000000000..1e8162dcf1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-da/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Billede kopieret til udklipsholder</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-de/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-de/strings.xml
new file mode 100644
index 0000000000..a6f23ccb4a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-de/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Grafik in Zwischenablage kopiert</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-dsb/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-dsb/strings.xml
new file mode 100644
index 0000000000..5119090d13
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-dsb/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Wobraz jo se kopěrował do mjazywótkłada</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-el/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-el/strings.xml
new file mode 100644
index 0000000000..57da3ec96d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-el/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Η εικόνα αντιγράφτηκε στο πρόχειρο</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rCA/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000000..638ee8543e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rCA/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Image copied to clipboard</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rGB/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000000..638ee8543e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-en-rGB/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Image copied to clipboard</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-eo/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-eo/strings.xml
new file mode 100644
index 0000000000..9cc052f510
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-eo/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Bildo kopiita al la tondujo</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rAR/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rAR/strings.xml
new file mode 100644
index 0000000000..06f644e903
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rAR/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagen copiada al portapapeles</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rCL/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rCL/strings.xml
new file mode 100644
index 0000000000..06f644e903
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rCL/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagen copiada al portapapeles</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rES/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rES/strings.xml
new file mode 100644
index 0000000000..06f644e903
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rES/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagen copiada al portapapeles</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rMX/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rMX/strings.xml
new file mode 100644
index 0000000000..06f644e903
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es-rMX/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagen copiada al portapapeles</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-es/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000000..06f644e903
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-es/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagen copiada al portapapeles</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-et/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-et/strings.xml
new file mode 100644
index 0000000000..b77f8fe2fc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-et/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Pilt kopeeriti vahemällu</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-eu/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-eu/strings.xml
new file mode 100644
index 0000000000..18039c3b03
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-eu/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Irudia arbelean kopiatu da</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-fa/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fa/strings.xml
new file mode 100644
index 0000000000..4d9c243f3c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fa/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">تصویر به تخته‌گیره رونوشت شد</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-fi/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fi/strings.xml
new file mode 100644
index 0000000000..426de77fe1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fi/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Kuva kopioitu leikepöydälle</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-fr/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000000..c41cec7a23
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Image copiée dans le presse-papiers</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-fur/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fur/strings.xml
new file mode 100644
index 0000000000..5fb71c5b51
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fur/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagjin copiade intes notis</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-fy-rNL/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fy-rNL/strings.xml
new file mode 100644
index 0000000000..db7c6fa54d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-fy-rNL/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Ofbylding nei klamboerd kopiearre</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-gd/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-gd/strings.xml
new file mode 100644
index 0000000000..a2c04bd312
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-gd/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Chaidh lethbhreac dhen dealbh a chur air an stòr-bhòrd</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-gl/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-gl/strings.xml
new file mode 100644
index 0000000000..3e7252778d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-gl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Copiouse a imaxe ao portapapeis</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-gn/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-gn/strings.xml
new file mode 100644
index 0000000000..af5e3ba7cb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-gn/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Embohasa ta’ãnga kuatiajokohápe</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-hr/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hr/strings.xml
new file mode 100644
index 0000000000..dbfcb2d809
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Slika je kopirana u međuspremnik</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-hsb/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hsb/strings.xml
new file mode 100644
index 0000000000..473527a6cd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hsb/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Wobraz je so do mjezyskłada kopěrował</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-hu/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hu/strings.xml
new file mode 100644
index 0000000000..0ca081817d
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hu/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Kép vágólapra másolva</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-hy-rAM/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000000..4567efaed4
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-hy-rAM/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Պատկերը պատճենվել է սեղմատախտակին</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ia/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ia/strings.xml
new file mode 100644
index 0000000000..6b8f02500b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ia/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagine copiate al area de transferentia</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-in/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-in/strings.xml
new file mode 100644
index 0000000000..4b6807e51e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-in/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Gambar disalin ke papan klip</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-is/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-is/strings.xml
new file mode 100644
index 0000000000..c2e2bb5714
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-is/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Mynd afrituð á klippispjald</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-it/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-it/strings.xml
new file mode 100644
index 0000000000..79c58ec52e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-it/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Immagine copiata negli appunti</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-iw/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-iw/strings.xml
new file mode 100644
index 0000000000..85bf7a942a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-iw/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">התמונה הועתקה ללוח</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ja/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ja/strings.xml
new file mode 100644
index 0000000000..805eacfc87
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ja/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">画像をクリップボードにコピーしました</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ka/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ka/strings.xml
new file mode 100644
index 0000000000..8de04f6263
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ka/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">სურათის ასლი აღებულია</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-kaa/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kaa/strings.xml
new file mode 100644
index 0000000000..cb2c90ba5b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kaa/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Súwret almasıw buferine kóshirip alındı</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-kab/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kab/strings.xml
new file mode 100644
index 0000000000..093f1d2616
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kab/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Tugna tettwanɣel ɣef wafus</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-kk/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kk/strings.xml
new file mode 100644
index 0000000000..80b99ef483
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kk/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Сурет алмасу буферіне көшірілді</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-kmr/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kmr/strings.xml
new file mode 100644
index 0000000000..b299c8f6b7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-kmr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Wêne li panoyê hate kopîkirin</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ko/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ko/strings.xml
new file mode 100644
index 0000000000..5d6ebf83e7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ko/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">클립보드에 이미지 복사됨</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-lo/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-lo/strings.xml
new file mode 100644
index 0000000000..ab066dba6f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-lo/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">ສຳເນົາຮູບໃສ່ຄລິບບອດແລ້ວ</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-nb-rNO/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-nb-rNO/strings.xml
new file mode 100644
index 0000000000..bef36125f1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-nb-rNO/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Bilde kopiert til utklippstavlen</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-nl/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-nl/strings.xml
new file mode 100644
index 0000000000..06070807bb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-nl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Afbeelding naar klembord gekopieerd</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-nn-rNO/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-nn-rNO/strings.xml
new file mode 100644
index 0000000000..16c41f8d38
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-nn-rNO/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Bilde kopiert til utklippstavla</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-oc/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-oc/strings.xml
new file mode 100644
index 0000000000..131c779121
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-oc/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imatge copiat al quichapapièrs</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rIN/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000000..03300db934
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rIN/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">ਚਿੱਤਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ ਲਈ ਕਾਪੀ ਕੀਤਾ</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rPK/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rPK/strings.xml
new file mode 100644
index 0000000000..cb4e8c879c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pa-rPK/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">کاپی کیتی گئی</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-pl/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pl/strings.xml
new file mode 100644
index 0000000000..8a79fb5c5e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Skopiowano obraz do schowka</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rBR/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000000..223e60bc6a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagem copiada para área de transferência</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rPT/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000000..48dc017c65
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-pt-rPT/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imagem copiada para a área de transferência</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-rm/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-rm/strings.xml
new file mode 100644
index 0000000000..8b428f02b1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-rm/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Copià il maletg en l\'archiv provisoric</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ro/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ro/strings.xml
new file mode 100644
index 0000000000..be7fc12e65
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ro/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Imaginea a fost copiată în clipboard</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ru/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ru/strings.xml
new file mode 100644
index 0000000000..35ac3be80a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ru/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Изображение скопировано в буфер обмена</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-sat/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sat/strings.xml
new file mode 100644
index 0000000000..d945ea02c5
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sat/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">ᱨᱮᱴᱚᱯᱵᱚᱰ ᱨᱮ ᱪᱤᱛᱟᱹᱨ ᱱᱚᱠᱚᱞ ᱮᱱᱟ</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-sc/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sc/strings.xml
new file mode 100644
index 0000000000..6d122f7e8b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sc/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Immàgine copiada in punta de billete</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-si/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-si/strings.xml
new file mode 100644
index 0000000000..95d46d5ddd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-si/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">රූපය පසුරුපුවරුවට පිටපත් විය</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-sk/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sk/strings.xml
new file mode 100644
index 0000000000..02dc6628cb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sk/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Obrázok bol skopírovaný do schránky</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-skr/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-skr/strings.xml
new file mode 100644
index 0000000000..da370ffcb7
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-skr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">تصویر کلپ بورڈ تے نقل تھی ڳئی</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-sl/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sl/strings.xml
new file mode 100644
index 0000000000..b3a3418289
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Slika kopirana v odložišče</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-sq/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sq/strings.xml
new file mode 100644
index 0000000000..b76b67a352
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sq/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Figura u kopjua në të papastër</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-sr/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sr/strings.xml
new file mode 100644
index 0000000000..f0fbe5c485
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Слика је копирана у привремену меморију</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-su/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-su/strings.xml
new file mode 100644
index 0000000000..91a37e77b6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-su/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Gambar ditiron kana papan klip</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-sv-rSE/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sv-rSE/strings.xml
new file mode 100644
index 0000000000..51210de628
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-sv-rSE/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Bilden har kopierats till urklipp</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-tg/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-tg/strings.xml
new file mode 100644
index 0000000000..b304da28c1
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-tg/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Тасвир ба ҳофизаи муваққатӣ нусха бардошта шуд</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-th/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-th/strings.xml
new file mode 100644
index 0000000000..52a77b64dc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-th/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">คัดลอกภาพไปยังคลิปบอร์ดแล้ว</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-tr/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-tr/strings.xml
new file mode 100644
index 0000000000..b0ef721f12
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-tr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Resim panoya kopyalandı</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-trs/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-trs/strings.xml
new file mode 100644
index 0000000000..d905bed3df
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-trs/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Ñadū’hua ngà nanun riña portapapel</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-tt/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-tt/strings.xml
new file mode 100644
index 0000000000..ad4402d83c
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-tt/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Рәсем алмашу буферына копияләнде</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-ug/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ug/strings.xml
new file mode 100644
index 0000000000..2719590251
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-ug/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">سۈرەت چاپلاش تاختىسىغا كۆچۈرۈلدى</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-uk/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000000..49cffe6ba2
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-uk/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Зображення скопійовано в буфер обміну</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-vi/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-vi/strings.xml
new file mode 100644
index 0000000000..8127c7855b
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-vi/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Đã sao chép ảnh vào khay nhớ tạm</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rCN/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000000..98d08c5c6a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rCN/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">图像已复制到剪贴板</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rTW/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000000..39326e4ac0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">已將圖片複製至剪貼簿</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values/attrs.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..60a3b3a35f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values/attrs.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <attr name="mozac_font_semibold" format="reference" />
+ <attr name="mozac_accent" format="reference" />
+ <attr name="mozac_contrast_text" format="reference" />
+
+ <!-- Background color for favicon widget box -->
+ <attr name="mozac_widget_favicon_background_color" format="reference" />
+ <!-- Border color for favicon widget box -->
+ <attr name="mozac_widget_favicon_border_color" format="reference" />
+
+ <!-- Label color and icon button tint for site item widget -->
+ <attr name="mozac_primary_text_color" format="reference" />
+ <!-- Caption color for site item widget -->
+ <attr name="mozac_caption_text_color" format="reference" />
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values/colors.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..105264e605
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <!-- Button Colors -->
+ <color name="mozac_grey_button_color">#E0E0E6</color>
+ <color name="mozac_destructive_button_text_color">#C50042</color>
+ <color name="mozac_grey_button_text_color">#312A65</color>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values/dimens.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..9f6d4587fd
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values/dimens.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <dimen name="mozac_widget_favicon_size">40dp</dimen>
+ <dimen name="mozac_widget_favicon_padding">8dp</dimen>
+
+ <dimen name="mozac_widget_site_item_height">56dp</dimen>
+ <dimen name="mozac_widget_site_item_label_text_size">16sp</dimen>
+ <dimen name="mozac_widget_site_item_caption_text_size">12sp</dimen>
+ <dimen name="mozac_widget_site_item_secondary_button_size">32dp</dimen>
+ <dimen name="mozac_widget_site_item_secondary_button_padding">4dp</dimen>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values/strings.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..6a82d7eaef
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <!-- Text for confirmation "snackbar" shown after copying an image to the clipboard. -->
+ <string name="snackbar_copy_image_to_clipboard_confirmation">Image copied to clipboard</string>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/main/res/values/styles.xml b/mobile/android/android-components/components/ui/widgets/src/main/res/values/styles.xml
new file mode 100644
index 0000000000..515b98e12e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/main/res/values/styles.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="Mozac.Widgets.TestTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
+ <item name="mozac_widget_favicon_background_color">@color/photonWhite</item>
+ <item name="mozac_widget_favicon_border_color">@color/photonLightGrey30</item>
+ <item name="mozac_primary_text_color">@color/photonInk90</item>
+ <item name="mozac_caption_text_color">@color/photonInk50</item>
+ </style>
+
+ <!-- Button styling -->
+ <style name="Mozac.Widgets.NeutralButton" parent="Widget.MaterialComponents.Button.TextButton">
+ <item name="iconTint">@color/mozac_grey_button_text_color</item>
+ <item name="iconPadding">8dp</item>
+ <item name="iconGravity">textStart</item>
+ <item name="android:textAlignment">center</item>
+ <item name="android:background">@drawable/rounded_button_background</item>
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">48dp</item>
+ <item name="android:textStyle">bold</item>
+ <item name="android:textAllCaps">false</item>
+ <item name="backgroundTint">@color/mozac_grey_button_color</item>
+ <item name="android:textColor">@color/mozac_grey_button_text_color</item>
+ <item name="android:letterSpacing">0</item>
+ <item name="fontFamily">?mozac_font_semibold</item>
+ </style>
+
+ <style name="Mozac.Widgets.DestructiveButton" parent="Mozac.Widgets.NeutralButton">
+ <item name="iconTint">@color/mozac_destructive_button_text_color</item>
+ <item name="android:textColor">@color/mozac_destructive_button_text_color</item>
+ </style>
+
+ <style name="Mozac.Widgets.PositiveButton" parent="Mozac.Widgets.NeutralButton">
+ <item name="backgroundTint">?mozac_accent</item>
+ <item name="iconTint">?mozac_contrast_text</item>
+ <item name="android:textColor">?mozac_contrast_text</item>
+ </style>
+
+ <!-- Favicon styling -->
+ <style name="Mozac.Widgets.Favicon" parent="">
+ <item name="android:layout_width">@dimen/mozac_widget_favicon_size</item>
+ <item name="android:layout_height">@dimen/mozac_widget_favicon_size</item>
+ <item name="android:scaleType">fitCenter</item>
+ <item name="android:padding">@dimen/mozac_widget_favicon_padding</item>
+ <item name="android:background">@drawable/mozac_widget_favicon_background</item>
+ </style>
+
+ <style name="Mozac.Widgets.SiteItem.Label" parent="">
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:ellipsize">end</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:textAlignment">viewStart</item>
+ <item name="android:textSize">@dimen/mozac_widget_site_item_label_text_size</item>
+ <item name="android:textColor">?attr/mozac_primary_text_color</item>
+ </style>
+ <style name="Mozac.Widgets.SiteItem.Caption" parent="Mozac.Widgets.SiteItem.Label">
+ <item name="android:textSize">@dimen/mozac_widget_site_item_caption_text_size</item>
+ <item name="android:textColor">?attr/mozac_caption_text_color</item>
+ </style>
+</resources>
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/TestUtils.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/TestUtils.kt
new file mode 100644
index 0000000000..cda854782e
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/TestUtils.kt
@@ -0,0 +1,73 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets
+
+import android.view.MotionEvent
+
+object TestUtils {
+ fun getMotionEvent(
+ action: Int,
+ x: Float = 0f,
+ y: Float = 0f,
+ eventTime: Long = System.currentTimeMillis(),
+ previousEvent: MotionEvent? = null,
+ ): MotionEvent {
+ val downTime = previousEvent?.downTime ?: System.currentTimeMillis()
+
+ var pointerCount = previousEvent?.pointerCount ?: 0
+ if (action == MotionEvent.ACTION_POINTER_DOWN) {
+ pointerCount++
+ } else if (action == MotionEvent.ACTION_DOWN) {
+ pointerCount = 1
+ } else if (previousEvent?.action == MotionEvent.ACTION_POINTER_UP) {
+ pointerCount--
+ }
+
+ val properties = Array(
+ pointerCount,
+ TestUtils::getPointerProperties,
+ )
+ val pointerCoords =
+ getPointerCoords(
+ x,
+ y,
+ pointerCount,
+ previousEvent,
+ )
+
+ return MotionEvent.obtain(
+ downTime, eventTime,
+ action, pointerCount, properties,
+ pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0,
+ )
+ }
+
+ private fun getPointerCoords(
+ x: Float,
+ y: Float,
+ pointerCount: Int,
+ previousEvent: MotionEvent? = null,
+ ): Array<MotionEvent.PointerCoords?> {
+ val currentEventCoords = MotionEvent.PointerCoords().apply {
+ this.x = x; this.y = y; pressure = 1f; size = 1f
+ }
+
+ return if (pointerCount > 1 && previousEvent != null) {
+ arrayOf(
+ MotionEvent.PointerCoords().apply {
+ this.x = previousEvent.x; this.y = previousEvent.y; pressure = 1f; size = 1f
+ },
+ currentEventCoords,
+ )
+ } else {
+ arrayOf(currentEventCoords)
+ }
+ }
+
+ private fun getPointerProperties(id: Int): MotionEvent.PointerProperties =
+ MotionEvent.PointerProperties().apply {
+ this.id = id; this.toolType = MotionEvent.TOOL_TYPE_FINGER
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayoutTest.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayoutTest.kt
new file mode 100644
index 0000000000..b06e67be3f
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/VerticalSwipeRefreshLayoutTest.kt
@@ -0,0 +1,430 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets
+
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_CANCEL
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_POINTER_DOWN
+import android.view.MotionEvent.ACTION_POINTER_UP
+import android.view.MotionEvent.ACTION_UP
+import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import mozilla.components.ui.widgets.VerticalSwipeRefreshLayout.QuickScaleEvents
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidJUnit4::class)
+class VerticalSwipeRefreshLayoutTest {
+ private lateinit var swipeLayout: VerticalSwipeRefreshLayout
+
+ @Before
+ fun setup() {
+ swipeLayout = VerticalSwipeRefreshLayout(testContext)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should abort pull to refresh and return false if the View is disabled`() {
+ swipeLayout = spy(swipeLayout)
+ val secondFingerEvent = TestUtils.getMotionEvent(ACTION_POINTER_DOWN)
+
+ swipeLayout.isEnabled = false
+ assertFalse(swipeLayout.onInterceptTouchEvent(secondFingerEvent))
+ verify(swipeLayout, times(0)).callSuperOnInterceptTouchEvent(secondFingerEvent)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should abort pull to refresh and return false if the motion was multitouch`() {
+ swipeLayout.isEnabled = true
+ swipeLayout.setOnChildScrollUpCallback { _, _ -> false }
+
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, x = 0f, y = 5f, previousEvent = downEvent)
+ val secondFingerEvent = TestUtils.getMotionEvent(ACTION_POINTER_DOWN, previousEvent = moveEvent)
+ val secondFingerNextEvent =
+ TestUtils.getMotionEvent(ACTION_MOVE, x = 0f, y = 5f, previousEvent = secondFingerEvent)
+ val secondFingerUp = TestUtils.getMotionEvent(ACTION_POINTER_UP, previousEvent = secondFingerNextEvent)
+ val upEvent = TestUtils.getMotionEvent(ACTION_UP, previousEvent = secondFingerUp)
+ val newDownEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+
+ swipeLayout.onInterceptTouchEvent(downEvent)
+ assertFalse(swipeLayout.onInterceptTouchEvent(moveEvent))
+ assertFalse(swipeLayout.hadMultiTouch)
+ assertFalse(swipeLayout.onInterceptTouchEvent(secondFingerEvent))
+ assertTrue(swipeLayout.hadMultiTouch)
+ assertFalse(swipeLayout.onInterceptTouchEvent(secondFingerNextEvent))
+ assertTrue(swipeLayout.hadMultiTouch)
+ assertFalse(swipeLayout.onInterceptTouchEvent(secondFingerUp))
+ assertTrue(swipeLayout.hadMultiTouch)
+ assertFalse(swipeLayout.onInterceptTouchEvent(upEvent))
+ assertTrue(swipeLayout.hadMultiTouch)
+ assertFalse(swipeLayout.onInterceptTouchEvent(newDownEvent))
+ assertFalse(swipeLayout.hadMultiTouch)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should abort pull to refresh and return false if zoom is in progress`() {
+ swipeLayout = spy(swipeLayout)
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f)
+ val pointerDownEvent =
+ TestUtils.getMotionEvent(ACTION_POINTER_DOWN, 200f, 200f, previousEvent = downEvent)
+ swipeLayout.isEnabled = true
+ swipeLayout.setOnChildScrollUpCallback { _, _ -> true }
+
+ swipeLayout.onInterceptTouchEvent(downEvent)
+ verify(swipeLayout, times(1)).callSuperOnInterceptTouchEvent(downEvent)
+
+ swipeLayout.onInterceptTouchEvent(pointerDownEvent)
+ assertFalse(swipeLayout.onInterceptTouchEvent(pointerDownEvent))
+ verify(swipeLayout, times(0)).callSuperOnInterceptTouchEvent(pointerDownEvent)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should cleanup if ACTION_CANCEL`() {
+ swipeLayout = spy(swipeLayout)
+ val cancelEvent = TestUtils.getMotionEvent(
+ ACTION_CANCEL,
+ previousEvent = TestUtils.getMotionEvent(ACTION_DOWN),
+ )
+ swipeLayout.isEnabled = true
+ swipeLayout.setOnChildScrollUpCallback { _, _ -> true }
+
+ swipeLayout.onInterceptTouchEvent(cancelEvent)
+
+ verify(swipeLayout).forgetQuickScaleEvents()
+ verify(swipeLayout).callSuperOnInterceptTouchEvent(cancelEvent)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should cleanup if quick scale ended`() {
+ swipeLayout = spy(swipeLayout)
+ val upEvent = TestUtils.getMotionEvent(
+ ACTION_CANCEL,
+ previousEvent = TestUtils.getMotionEvent(ACTION_DOWN),
+ )
+ swipeLayout.isEnabled = true
+ swipeLayout.isQuickScaleInProgress = true
+ swipeLayout.setOnChildScrollUpCallback { _, _ -> true }
+
+ swipeLayout.onInterceptTouchEvent(upEvent)
+
+ verify(swipeLayout).forgetQuickScaleEvents()
+ verify(swipeLayout).callSuperOnInterceptTouchEvent(upEvent)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should disable pull to refresh if quick scale is in progress`() {
+ // default DOUBLE_TAP_TIMEOUT is 300ms
+
+ swipeLayout = spy(swipeLayout)
+ val firstDownEvent = TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 100)
+ val upEvent =
+ TestUtils.getMotionEvent(ACTION_UP, eventTime = 200, previousEvent = firstDownEvent)
+ val newDownEvent =
+ TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 500, previousEvent = upEvent)
+ val previousEvents = QuickScaleEvents(firstDownEvent, upEvent, null)
+ swipeLayout.quickScaleEvents = previousEvents
+ swipeLayout.isQuickScaleInProgress = false
+
+ assertFalse(swipeLayout.onInterceptTouchEvent(newDownEvent))
+ assertTrue(swipeLayout.isQuickScaleInProgress)
+ verify(swipeLayout).maybeAddDoubleTapEvent(newDownEvent)
+ verify(swipeLayout, times(0)).callSuperOnInterceptTouchEvent(newDownEvent)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should disable pull to refresh if move was more on the x axys`() {
+ // default DOUBLE_TAP_TIMEOUT is 300ms
+
+ swipeLayout = spy(swipeLayout)
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, x = 0f, y = 0f, eventTime = 0)
+ val moveEvent = TestUtils.getMotionEvent(
+ ACTION_MOVE,
+ x = 1f,
+ y = 0f,
+ eventTime = 100,
+ previousEvent = downEvent,
+ )
+ swipeLayout.isEnabled = true
+ swipeLayout.isQuickScaleInProgress = false
+ swipeLayout.setOnChildScrollUpCallback { _, _ -> false }
+
+ swipeLayout.onInterceptTouchEvent(downEvent)
+ verify(swipeLayout).callSuperOnInterceptTouchEvent(downEvent)
+
+ assertFalse(swipeLayout.onInterceptTouchEvent(moveEvent))
+ verify(swipeLayout, times(0)).callSuperOnInterceptTouchEvent(moveEvent)
+ }
+
+ @Test
+ fun `onInterceptTouchEvent should allow pull to refresh if move was more on the y axys`() {
+ // default DOUBLE_TAP_TIMEOUT is 300ms
+
+ swipeLayout = spy(swipeLayout)
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, x = 0f, y = 0f, eventTime = 0)
+ val moveEvent = TestUtils.getMotionEvent(
+ ACTION_MOVE,
+ x = 0f,
+ y = 1f,
+ eventTime = 100,
+ previousEvent = downEvent,
+ )
+ swipeLayout.isEnabled = true
+ swipeLayout.isQuickScaleInProgress = false
+ swipeLayout.setOnChildScrollUpCallback { _, _ -> false }
+
+ swipeLayout.onInterceptTouchEvent(downEvent)
+ verify(swipeLayout).callSuperOnInterceptTouchEvent(downEvent)
+
+ swipeLayout.onInterceptTouchEvent(moveEvent)
+ verify(swipeLayout).callSuperOnInterceptTouchEvent(moveEvent)
+ }
+
+ @Test
+ fun `Should not respond descendants initiated scrolls if this View is enabled`() {
+ swipeLayout = spy(swipeLayout)
+ val childView: View = mock()
+ val targetView: View = mock()
+ val scrollAxis = 0
+
+ swipeLayout.isEnabled = true
+
+ assertFalse(swipeLayout.onStartNestedScroll(childView, targetView, scrollAxis))
+ verify(swipeLayout, times(0)).callSuperOnStartNestedScroll(
+ childView,
+ targetView,
+ scrollAxis,
+ )
+ }
+
+ @Test
+ fun `Should delegate super#onStartNestedScroll if this View is not enabled`() {
+ swipeLayout = spy(swipeLayout)
+ val childView: View = mock()
+ val targetView: View = mock()
+ val scrollAxis = 0
+
+ swipeLayout.isEnabled = false
+ swipeLayout.onStartNestedScroll(childView, targetView, scrollAxis)
+
+ verify(swipeLayout).callSuperOnStartNestedScroll(childView, targetView, scrollAxis)
+ }
+
+ @Test
+ fun `maybeAddDoubleTapEvent should not modify quickScaleEvents if not for ACTION_DOWN or ACTION_UP`() {
+ val emptyListOfEvents = QuickScaleEvents()
+ swipeLayout.quickScaleEvents = emptyListOfEvents
+
+ swipeLayout.maybeAddDoubleTapEvent(TestUtils.getMotionEvent(ACTION_POINTER_DOWN))
+
+ assertEquals(emptyListOfEvents, swipeLayout.quickScaleEvents)
+ }
+
+ @Test
+ fun `maybeAddDoubleTapEvent will add ACTION_UP as second event if there is already one event in sequence`() {
+ val firstEvent = spy(TestUtils.getMotionEvent(ACTION_DOWN))
+ val secondEvent =
+ spy(TestUtils.getMotionEvent(ACTION_UP, eventTime = 133, previousEvent = firstEvent))
+ val expectedResult = Triple<MotionEvent?, MotionEvent?, MotionEvent?>(
+ firstEvent,
+ secondEvent,
+ null,
+ )
+ swipeLayout.quickScaleEvents = QuickScaleEvents(firstEvent, null, null)
+
+ swipeLayout.maybeAddDoubleTapEvent(secondEvent)
+
+ // A Triple assert or MotionEvent assert fails probably because of the copies made
+ // Verifying the expected actions and eventTime should be good enough.
+ assertEquals(expectedResult.first, swipeLayout.quickScaleEvents.firstDownEvent)
+ assertEquals(
+ expectedResult.second!!.actionMasked,
+ swipeLayout.quickScaleEvents.upEvent!!.actionMasked,
+ )
+ assertEquals(
+ expectedResult.second!!.eventTime,
+ swipeLayout.quickScaleEvents.upEvent!!.eventTime,
+ )
+ assertEquals(null, swipeLayout.quickScaleEvents.secondDownEvent)
+ }
+
+ @Test
+ fun `maybeAddDoubleTapEvent will not add ACTION_UP if there is not a first event already in sequence`() {
+ val firstEvent = spy(TestUtils.getMotionEvent(ACTION_DOWN))
+ val secondEvent =
+ spy(TestUtils.getMotionEvent(ACTION_UP, eventTime = 133, previousEvent = firstEvent))
+ val expectedResult = QuickScaleEvents()
+ swipeLayout.quickScaleEvents = expectedResult
+
+ swipeLayout.maybeAddDoubleTapEvent(secondEvent)
+
+ assertEquals(null, swipeLayout.quickScaleEvents.firstDownEvent)
+ assertEquals(null, swipeLayout.quickScaleEvents.upEvent)
+ assertEquals(null, swipeLayout.quickScaleEvents.secondDownEvent)
+ }
+
+ @Test
+ fun `maybeAddDoubleTapEvent will add the first ACTION_DOWN if the events list is otherwise empty`() {
+ swipeLayout = spy(swipeLayout)
+ val emptyListOfEvents = QuickScaleEvents()
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 133)
+ swipeLayout.quickScaleEvents = emptyListOfEvents
+
+ swipeLayout.maybeAddDoubleTapEvent(downEvent)
+
+ verify(swipeLayout).forgetQuickScaleEvents()
+ assertEquals(downEvent.actionMasked, swipeLayout.quickScaleEvents.firstDownEvent!!.actionMasked)
+ assertEquals(downEvent.eventTime, swipeLayout.quickScaleEvents.firstDownEvent!!.eventTime)
+ assertEquals(null, swipeLayout.quickScaleEvents.upEvent)
+ assertEquals(null, swipeLayout.quickScaleEvents.secondDownEvent)
+ }
+
+ @Test
+ fun `maybeAddDoubleTapEvent will reset the first ACTION_DOWN if the events list does not contain other events`() {
+ swipeLayout = spy(swipeLayout)
+ val previousDownEvent = TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 111)
+ val previousEvents = QuickScaleEvents(previousDownEvent, null, null)
+ val newDownEvent = TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 222)
+ swipeLayout.quickScaleEvents = previousEvents
+
+ swipeLayout.maybeAddDoubleTapEvent(newDownEvent)
+
+ verify(swipeLayout).forgetQuickScaleEvents()
+ assertEquals(newDownEvent.actionMasked, swipeLayout.quickScaleEvents.firstDownEvent!!.actionMasked)
+ assertEquals(newDownEvent.eventTime, swipeLayout.quickScaleEvents.firstDownEvent!!.eventTime)
+ assertEquals(null, swipeLayout.quickScaleEvents.upEvent)
+ assertEquals(null, swipeLayout.quickScaleEvents.secondDownEvent)
+ }
+
+ @Test
+ fun `maybeAddDoubleTapEvent will reset ACTION_DOWN if timeout was reached`() {
+ // default DOUBLE_TAP_TIMEOUT is 300ms
+
+ swipeLayout = spy(swipeLayout)
+ val firstDownEvent = TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 100)
+ val upEvent =
+ TestUtils.getMotionEvent(ACTION_UP, eventTime = 200, previousEvent = firstDownEvent)
+ val newDownEvent =
+ TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 501, previousEvent = upEvent)
+ val previousEvents = QuickScaleEvents(firstDownEvent, upEvent, null)
+ swipeLayout.quickScaleEvents = previousEvents
+
+ swipeLayout.maybeAddDoubleTapEvent(newDownEvent)
+
+ verify(swipeLayout).forgetQuickScaleEvents()
+ assertEquals(newDownEvent.actionMasked, swipeLayout.quickScaleEvents.firstDownEvent!!.actionMasked)
+ assertEquals(newDownEvent.eventTime, swipeLayout.quickScaleEvents.firstDownEvent!!.eventTime)
+ assertEquals(null, swipeLayout.quickScaleEvents.upEvent)
+ assertEquals(null, swipeLayout.quickScaleEvents.secondDownEvent)
+ }
+
+ @Test
+ fun `maybeAddDoubleTapEvent will add a second ACTION_DOWN already have two events and timeout is not reached`() {
+ // default DOUBLE_TAP_TIMEOUT is 300ms
+
+ swipeLayout = spy(swipeLayout)
+ val firstDownEvent = TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 100)
+ val upEvent =
+ TestUtils.getMotionEvent(ACTION_UP, eventTime = 200, previousEvent = firstDownEvent)
+ val newDownEvent =
+ TestUtils.getMotionEvent(ACTION_DOWN, eventTime = 500, previousEvent = upEvent)
+ val previousEvents = QuickScaleEvents(firstDownEvent, upEvent, null)
+ swipeLayout.quickScaleEvents = previousEvents
+
+ swipeLayout.maybeAddDoubleTapEvent(newDownEvent)
+
+ verify(swipeLayout, times(0)).forgetQuickScaleEvents()
+ assertEquals(firstDownEvent.actionMasked, swipeLayout.quickScaleEvents.firstDownEvent!!.actionMasked)
+ assertEquals(firstDownEvent.eventTime, swipeLayout.quickScaleEvents.firstDownEvent!!.eventTime)
+ assertEquals(upEvent.actionMasked, swipeLayout.quickScaleEvents.upEvent!!.actionMasked)
+ assertEquals(upEvent.eventTime, swipeLayout.quickScaleEvents.upEvent!!.eventTime)
+ assertEquals(newDownEvent.actionMasked, swipeLayout.quickScaleEvents.secondDownEvent!!.actionMasked)
+ assertEquals(newDownEvent.eventTime, swipeLayout.quickScaleEvents.secondDownEvent!!.eventTime)
+ }
+
+ @Test
+ fun `forgetQuickScaleEvents should recycle all events and reset the quickScaleStatus`() {
+ val firstEvent = spy(TestUtils.getMotionEvent(ACTION_DOWN))
+ val secondEvent = spy(TestUtils.getMotionEvent(ACTION_UP, previousEvent = firstEvent))
+ val thirdEvent = spy(TestUtils.getMotionEvent(ACTION_DOWN))
+ swipeLayout.quickScaleEvents = QuickScaleEvents(firstEvent, secondEvent, thirdEvent)
+ swipeLayout.isQuickScaleInProgress = true
+
+ swipeLayout.forgetQuickScaleEvents()
+
+ verify(firstEvent).recycle()
+ verify(secondEvent).recycle()
+ verify(thirdEvent).recycle()
+ assertEquals(QuickScaleEvents(), swipeLayout.quickScaleEvents)
+ assertFalse(swipeLayout.isQuickScaleInProgress)
+ }
+
+ @Test
+ fun `isQuickScaleInProgress should return false if timeout was reached`() {
+ // default DOUBLE_TAP_TIMEOUT is 300ms
+
+ val firstEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val secondEvent = TestUtils.getMotionEvent(ACTION_UP, 0f, 0f, 0, firstEvent)
+ val thirdEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f, 301L, secondEvent)
+
+ assertFalse(swipeLayout.isQuickScaleInProgress(firstEvent, secondEvent, thirdEvent))
+ }
+
+ @Test
+ fun `isQuickScaleInProgress should return false if taps were too apart`() {
+ val firstEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val secondEvent = TestUtils.getMotionEvent(ACTION_UP, 0f, 0f, 0, firstEvent)
+ val thirdEvent = TestUtils.getMotionEvent(ACTION_DOWN, 200f, 20f, 200L, secondEvent)
+
+ assertFalse(swipeLayout.isQuickScaleInProgress(firstEvent, secondEvent, thirdEvent))
+ }
+
+ @Test
+ fun `isQuickScaleInProgress should return true if taps were close`() {
+ val firstEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val secondEvent = TestUtils.getMotionEvent(ACTION_UP, 0f, 0f, 0, firstEvent)
+ val thirdEvent = TestUtils.getMotionEvent(ACTION_DOWN, 20f, 20f, 200L, secondEvent)
+
+ assertTrue(swipeLayout.isQuickScaleInProgress(firstEvent, secondEvent, thirdEvent))
+ }
+
+ @Test
+ fun `isQuickScaleInProgress should return false if any event is null`() {
+ // Using the same values as in the above test that asserts true
+ val firstEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val secondEvent = TestUtils.getMotionEvent(ACTION_UP, 0f, 0f, 0, firstEvent)
+ val thirdEvent = TestUtils.getMotionEvent(ACTION_DOWN, 20f, 20f, 200L, secondEvent)
+ val oneNullEvent = QuickScaleEvents(firstEvent, secondEvent, null)
+ val twoNullEvents = QuickScaleEvents(null, null, thirdEvent)
+ val allNullEvents = QuickScaleEvents(null, null, null)
+
+ assertFalse(swipeLayout.isQuickScaleInProgress(oneNullEvent))
+ assertFalse(swipeLayout.isQuickScaleInProgress(twoNullEvents))
+ assertFalse(swipeLayout.isQuickScaleInProgress(allNullEvents))
+ }
+
+ @Test
+ fun `isQuickScaleInProgress should return true for valid sequence of non null events`() {
+ // Using the same values as in the above test that asserts true
+ swipeLayout = spy(swipeLayout)
+ val firstEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val secondEvent = TestUtils.getMotionEvent(ACTION_UP, 0f, 0f, 0, firstEvent)
+ val thirdEvent = TestUtils.getMotionEvent(ACTION_DOWN, 20f, 20f, 200L, secondEvent)
+ val quickScaleEvents = QuickScaleEvents(firstEvent, secondEvent, thirdEvent)
+
+ assertTrue(swipeLayout.isQuickScaleInProgress(quickScaleEvents))
+ verify(swipeLayout).isQuickScaleInProgress(firstEvent, secondEvent, thirdEvent)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/WidgetSiteItemViewTest.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/WidgetSiteItemViewTest.kt
new file mode 100644
index 0000000000..babc038dc0
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/WidgetSiteItemViewTest.kt
@@ -0,0 +1,93 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets
+
+import android.graphics.drawable.Drawable
+import android.widget.ImageButton
+import android.widget.TextView
+import androidx.appcompat.view.ContextThemeWrapper
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import mozilla.components.ui.icons.R as iconsR
+
+@RunWith(AndroidJUnit4::class)
+class WidgetSiteItemViewTest {
+
+ private lateinit var view: WidgetSiteItemView
+
+ @Before
+ fun setup() {
+ val context = ContextThemeWrapper(testContext, R.style.Mozac_Widgets_TestTheme)
+ view = WidgetSiteItemView(context)
+ }
+
+ @Test
+ fun `setText hides the caption`() {
+ val labelView = view.findViewById<TextView>(R.id.label)
+ val captionView = view.findViewById<TextView>(R.id.caption)
+
+ view.setText(label = "label", caption = null)
+ assertEquals("label", labelView.text)
+ assertTrue(captionView.isGone)
+
+ view.setText(label = "Label", caption = "")
+ assertEquals("Label", labelView.text)
+ assertEquals("", captionView.text)
+ assertTrue(captionView.isVisible)
+ }
+
+ @Test
+ fun `setSecondaryButton shows the button`() {
+ val secondaryButton = view.findViewById<ImageButton>(R.id.secondary_button)
+ val drawable = mock<Drawable>()
+ var clicked = false
+ view.setSecondaryButton(
+ icon = drawable,
+ contentDescription = "Menu",
+ onClickListener = { clicked = true },
+ )
+ assertTrue(secondaryButton.isVisible)
+ assertEquals(drawable, secondaryButton.drawable)
+ assertEquals("Menu", secondaryButton.contentDescription)
+
+ secondaryButton.performClick()
+ assertTrue(clicked)
+ }
+
+ @Test
+ fun `setSecondaryButton with resource IDs shows the button`() {
+ val secondaryButton = view.findViewById<ImageButton>(R.id.secondary_button)
+ var clicked = false
+ view.setSecondaryButton(
+ icon = iconsR.drawable.mozac_ic_lock_24,
+ contentDescription = iconsR.string.mozac_error_lock,
+ onClickListener = { clicked = true },
+ )
+ assertTrue(secondaryButton.isVisible)
+ assertNotNull(secondaryButton.drawable)
+ assertEquals("mozac_error_lock", secondaryButton.contentDescription)
+
+ secondaryButton.performClick()
+ assertTrue(clicked)
+ }
+
+ @Test
+ fun `removeSecondaryButton does nothing if set was not called`() {
+ val secondaryButton = view.findViewById<ImageButton>(R.id.secondary_button)
+ assertTrue(secondaryButton.isGone)
+
+ view.removeSecondaryButton()
+ assertTrue(secondaryButton.isGone)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetectorTest.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetectorTest.kt
new file mode 100644
index 0000000000..66c4b826ff
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetectorTest.kt
@@ -0,0 +1,231 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.view.GestureDetector
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_CANCEL
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_POINTER_DOWN
+import android.view.MotionEvent.ACTION_UP
+import android.view.ScaleGestureDetector
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.concept.base.crash.CrashReporting
+import mozilla.components.support.test.any
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+
+@RunWith(AndroidJUnit4::class)
+class BrowserGestureDetectorTest {
+ // Robolectric currently (April 17th 2020) only offer a stub in it's `ShadowScaleGestureDetector`
+ // so unit tests based on the actual implementation of `ScaleGestureListener` are not possible.
+
+ // Used spies and not mocks as it was observed that verifying more of the below as mocks
+ // will fail the tests because of "UnfinishedVerificationException"
+ private val scrollListener = spy { _: Float, _: Float -> run {} }
+ private val verticalScrollListener = spy { _: Float -> run {} }
+ private val horizontalScrollListener = spy { _: Float -> run {} }
+ private val scaleBeginListener = spy { _: Float -> run {} }
+ private val scaleInProgressListener = spy { _: Float -> run {} }
+ private val scaleEndListener = spy { _: Float -> run {} }
+ private val gesturesListener = BrowserGestureDetector.GesturesListener(
+ onScroll = scrollListener,
+ onVerticalScroll = verticalScrollListener,
+ onHorizontalScroll = horizontalScrollListener,
+ onScaleBegin = scaleBeginListener,
+ onScale = scaleInProgressListener,
+ onScaleEnd = scaleEndListener,
+ )
+
+ @Test
+ fun `Detector should not attempt to detect zoom if MotionEvent's action is ACTION_CANCEL`() {
+ val detector = spy(BrowserGestureDetector(testContext, mock()))
+ val scaleDetector: ScaleGestureDetector = mock()
+ detector.scaleGestureDetector = scaleDetector
+
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val cancelEvent = TestUtils.getMotionEvent(ACTION_CANCEL, previousEvent = downEvent)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, previousEvent = downEvent)
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(cancelEvent)
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(moveEvent)
+
+ verify(scaleDetector, times(3)).onTouchEvent(any<MotionEvent>())
+ }
+
+ @Test
+ fun `Detector should not attempt to detect scrolls if a zoom gesture is in progress`() {
+ val detector = spy(BrowserGestureDetector(testContext, mock()))
+ val scrollDetector: GestureDetector = mock()
+ val scaleDetector: ScaleGestureDetector = mock()
+ detector.gestureDetector = scrollDetector
+ detector.scaleGestureDetector = scaleDetector
+ `when`(scaleDetector.isInProgress).thenReturn(true)
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, previousEvent = downEvent)
+
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(moveEvent)
+
+ // In this case we let ACTION_DOWN, ACTION_UP, ACTION_CANCEL be handled but not others.
+ verify(scrollDetector, times(1)).onTouchEvent(downEvent)
+ verify(scrollDetector, never()).onTouchEvent(moveEvent)
+ }
+
+ @Test
+ fun `Detector's handleTouchEvent returns false if the event was not handled`() {
+ val detector = spy(BrowserGestureDetector(testContext, mock()))
+ val unhandledEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+
+ // Neither the scale detector, nor the scroll detector should be interested
+ // in a one of a time ACTION_CANCEL MotionEvent
+ val wasEventHandled = detector.handleTouchEvent(
+ TestUtils.getMotionEvent(ACTION_CANCEL, previousEvent = unhandledEvent),
+ )
+
+ assertFalse(wasEventHandled)
+ }
+
+ @Test
+ fun `Detector's handleTouchEvent returns true if the event was handled`() {
+ val detector = spy(BrowserGestureDetector(testContext, mock()))
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 0f, previousEvent = downEvent)
+ val moveEvent2 = TestUtils.getMotionEvent(ACTION_MOVE, 100f, 100f, previousEvent = moveEvent)
+
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(moveEvent)
+ val wasEventHandled = detector.handleTouchEvent(moveEvent2)
+
+ assertTrue(wasEventHandled)
+ }
+
+ @Test
+ fun `Detector should inform about scroll and vertical scrolls events`() {
+ val detector = spy(BrowserGestureDetector(testContext, gesturesListener))
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 0f, previousEvent = downEvent)
+ val moveEvent2 = TestUtils.getMotionEvent(ACTION_MOVE, 100f, 200f, previousEvent = moveEvent)
+
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(moveEvent)
+ detector.handleTouchEvent(moveEvent2)
+
+ // If the movement was more on the Y axis both "onScroll" and "onVerticalScroll" callbacks
+ // should be called but no others.
+ verify(scrollListener).invoke(-100f, -200f)
+ verify(verticalScrollListener).invoke(-200f)
+ verify(horizontalScrollListener, never()).invoke(anyFloat())
+ verify(scaleBeginListener, never()).invoke(anyFloat())
+ verify(scaleInProgressListener, never()).invoke(anyFloat())
+ verify(scaleEndListener, never()).invoke(anyFloat())
+ }
+
+ @Test
+ fun `Detector should prioritize vertical scrolls over horizontal scrolls`() {
+ val detector = spy(BrowserGestureDetector(testContext, gesturesListener))
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 0f, previousEvent = downEvent)
+ val moveEvent2 = TestUtils.getMotionEvent(ACTION_MOVE, 100f, 100f, previousEvent = moveEvent)
+
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(moveEvent)
+ detector.handleTouchEvent(moveEvent2)
+
+ // If the movement was for the same amount on both the Y axis and the X axis
+ // both "onScroll" and "onVerticalScroll" callbacks should be called but no others.
+ verify(scrollListener).invoke(-100f, -100f)
+ verify(verticalScrollListener).invoke(-100f)
+ verify(horizontalScrollListener, never()).invoke(anyFloat())
+ verify(scaleBeginListener, never()).invoke(anyFloat())
+ verify(scaleInProgressListener, never()).invoke(anyFloat())
+ verify(scaleEndListener, never()).invoke(anyFloat())
+ }
+
+ @Test
+ fun `Detector should inform about scroll and horizontal scrolls events`() {
+ val detector = spy(BrowserGestureDetector(testContext, gesturesListener))
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 0f, previousEvent = downEvent)
+ val moveEvent2 = TestUtils.getMotionEvent(ACTION_MOVE, 101f, 100f, previousEvent = moveEvent)
+
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(moveEvent)
+ detector.handleTouchEvent(moveEvent2)
+
+ // If the movement was for the same amount on both the Y axis and the X axis
+ // both "onScroll" and "onVerticalScroll" callbacks should be called but no others.
+ verify(scrollListener).invoke(-101f, -100f)
+ verify(horizontalScrollListener).invoke(-101f)
+ verify(verticalScrollListener, never()).invoke(anyFloat())
+ verify(scaleBeginListener, never()).invoke(anyFloat())
+ verify(scaleInProgressListener, never()).invoke(anyFloat())
+ verify(scaleEndListener, never()).invoke(anyFloat())
+ }
+
+ @Test
+ fun `Detector should always pass the ACTION_DOWN, ACTION_UP, ACTION_CANCEL events to the scroll detector`() {
+ val detector = spy(BrowserGestureDetector(testContext, mock()))
+ val scrollDetector: GestureDetector = mock()
+ val scaleDetector: ScaleGestureDetector = mock()
+ detector.gestureDetector = scrollDetector
+ detector.scaleGestureDetector = scaleDetector
+ // The aforementioned events should always be passed to the scroll detector,
+ // even if scaling is in progress.
+ `when`(scaleDetector.isInProgress).thenReturn(true)
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, previousEvent = downEvent)
+ val upEvent = TestUtils.getMotionEvent(ACTION_UP, previousEvent = moveEvent)
+ val cancelEvent = TestUtils.getMotionEvent(ACTION_CANCEL, previousEvent = upEvent)
+
+ listOf(downEvent, moveEvent, upEvent, cancelEvent).forEach {
+ detector.handleTouchEvent(it)
+ }
+
+ // With scaling in progress we let ACTION_DOWN, ACTION_UP, ACTION_CANCEL be handled but not others.
+ verify(scrollDetector, times(1)).onTouchEvent(downEvent)
+ verify(scrollDetector, times(1)).onTouchEvent(upEvent)
+ verify(scrollDetector, times(1)).onTouchEvent(cancelEvent)
+ verify(scrollDetector, never()).onTouchEvent(moveEvent)
+ }
+
+ @Test
+ fun `Detector should not crash when the scroll detector receives a null first MotionEvent`() {
+ val crashReporting: CrashReporting = mock()
+ val detector = BrowserGestureDetector(testContext, gesturesListener, crashReporting)
+ // We need a previous event for ACTION_MOVE.
+ // Don't use ACTION_DOWN (first pointer on the screen) but ACTION_POINTER_DOWN (other later pointer)
+ // just to artificially be able to recreate the bug from 8552. This should not happen IRL.
+ val downEvent = TestUtils.getMotionEvent(ACTION_POINTER_DOWN)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 0f, previousEvent = downEvent)
+ val moveEvent2 = TestUtils.getMotionEvent(ACTION_MOVE, 100f, 200f, previousEvent = moveEvent)
+
+ detector.handleTouchEvent(downEvent)
+ detector.handleTouchEvent(moveEvent)
+ detector.handleTouchEvent(moveEvent2)
+
+ verify(scrollListener).invoke(-100f, -200f)
+
+ // We don't crash but neither can identify vertical / horizontal scrolls.
+
+ verify(verticalScrollListener, never()).invoke(anyFloat())
+ verify(horizontalScrollListener, never()).invoke(anyFloat())
+ verify(scaleBeginListener, never()).invoke(anyFloat())
+ verify(scaleInProgressListener, never()).invoke(anyFloat())
+ verify(scaleEndListener, never()).invoke(anyFloat())
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt
new file mode 100644
index 0000000000..13538bc591
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt
@@ -0,0 +1,221 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.content.Context
+import android.view.View
+import android.widget.EditText
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.concept.engine.EngineView
+import mozilla.components.concept.toolbar.ScrollableToolbar
+import mozilla.components.support.test.fakes.engine.FakeEngineView
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidJUnit4::class)
+class EngineViewClippingBehaviorTest {
+
+ @Test
+ fun `EngineView clipping and bottom toolbar offset are kept in sync`() {
+ val engineView: EngineView = spy(FakeEngineView(testContext))
+ val toolbar: View = mock()
+ doReturn(100).`when`(toolbar).height
+ doReturn(42f).`when`(toolbar).translationY
+
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView.asView(),
+ toolbar.height,
+ ToolbarPosition.BOTTOM,
+ )
+
+ behavior.onDependentViewChanged(mock(), mock(), toolbar)
+
+ verify(engineView).setVerticalClipping(-42)
+ assertEquals(0f, engineView.asView().translationY)
+ }
+
+ @Test
+ fun `EngineView clipping and top toolbar offset are kept in sync`() {
+ val engineView: EngineView = spy(FakeEngineView(testContext))
+ val toolbar: View = mock()
+ doReturn(100).`when`(toolbar).height
+ doReturn(42f).`when`(toolbar).translationY
+
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView.asView(),
+ toolbar.height,
+ ToolbarPosition.TOP,
+ )
+
+ behavior.onDependentViewChanged(mock(), mock(), toolbar)
+
+ verify(engineView).setVerticalClipping(42)
+ assertEquals(142f, engineView.asView().translationY)
+ }
+
+ @Test
+ fun `Behavior does not depend on normal views`() {
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ mock(),
+ 0,
+ ToolbarPosition.BOTTOM,
+ )
+
+ assertFalse(behavior.layoutDependsOn(mock(), mock(), TextView(testContext)))
+ assertFalse(behavior.layoutDependsOn(mock(), mock(), EditText(testContext)))
+ assertFalse(behavior.layoutDependsOn(mock(), mock(), ImageView(testContext)))
+ }
+
+ @Test
+ fun `Behavior depends on BrowserToolbar`() {
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ mock(),
+ 0,
+ ToolbarPosition.BOTTOM,
+ )
+
+ assertTrue(behavior.layoutDependsOn(mock(), mock(), BrowserToolbar(testContext)))
+ }
+
+ @Test
+ fun `GIVEN a bottom toolbar WHEN translation has below a half decimal THEN set vertical clipping with the floor value`() {
+ val engineView: FakeEngineView = mock()
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView,
+ 100,
+ ToolbarPosition.BOTTOM,
+ )
+
+ behavior.toolbarChangedAction(40.4f)
+
+ verify(engineView).setVerticalClipping(-40)
+ }
+
+ @Test
+ fun `GIVEN a bottom toolbar WHEN translation has exactly half of a decimal THEN set vertical clipping with the ceiling value`() {
+ val engineView: FakeEngineView = mock()
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView,
+ 100,
+ ToolbarPosition.BOTTOM,
+ )
+
+ behavior.toolbarChangedAction(40.5f)
+
+ verify(engineView).setVerticalClipping(-41)
+ }
+
+ @Test
+ fun `GIVEN a bottom toolbar WHEN translation has more than a half decimal THEN set vertical clipping with the ceiling value`() {
+ val engineView: FakeEngineView = mock()
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView,
+ 100,
+ ToolbarPosition.BOTTOM,
+ )
+
+ behavior.toolbarChangedAction(40.6f)
+
+ verify(engineView).setVerticalClipping(-41)
+ }
+
+ @Test
+ fun `GIVEN a top toolbar WHEN translation has below a half decimal THEN set vertical clipping with the floor value`() {
+ val engineView: FakeEngineView = mock()
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView,
+ 100,
+ ToolbarPosition.TOP,
+ )
+
+ behavior.toolbarChangedAction(40.4f)
+
+ verify(engineView).setVerticalClipping(40)
+ }
+
+ @Test
+ fun `GIVEN a top toolbar WHEN translation has exactly half of a decimal THEN set vertical clipping with the ceiling value`() {
+ val engineView: FakeEngineView = mock()
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView,
+ 100,
+ ToolbarPosition.TOP,
+ )
+
+ behavior.toolbarChangedAction(40.5f)
+
+ verify(engineView).setVerticalClipping(41)
+ }
+
+ @Test
+ fun `GIVEN a top toolbar WHEN translation has more than a half decimal THEN set vertical clipping with the ceiling value`() {
+ val engineView: FakeEngineView = mock()
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView,
+ 100,
+ ToolbarPosition.TOP,
+ )
+
+ behavior.toolbarChangedAction(40.6f)
+
+ verify(engineView).setVerticalClipping(41)
+ }
+
+ @Test
+ fun `GIVEN a bottom toolbar WHEN translation returns NaN THEN no exception thrown`() {
+ val engineView: EngineView = spy(FakeEngineView(testContext))
+ val toolbar: View = mock()
+ doReturn(100).`when`(toolbar).height
+ doReturn(Float.NaN).`when`(toolbar).translationY
+
+ val behavior = EngineViewClippingBehavior(
+ mock(),
+ null,
+ engineView.asView(),
+ toolbar.height,
+ ToolbarPosition.BOTTOM,
+ )
+
+ behavior.onDependentViewChanged(mock(), mock(), toolbar)
+ assertEquals(0f, engineView.asView().translationY)
+ }
+}
+
+private class BrowserToolbar(context: Context) : TextView(context), ScrollableToolbar {
+ override fun enableScrolling() {}
+ override fun disableScrolling() {}
+ override fun expand() {}
+ override fun collapse() {}
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt
new file mode 100644
index 0000000000..0f0c10b71a
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt
@@ -0,0 +1,575 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.View
+import android.widget.FrameLayout
+import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.core.view.ViewCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.concept.engine.EngineSession
+import mozilla.components.concept.engine.EngineView
+import mozilla.components.concept.engine.INPUT_UNHANDLED
+import mozilla.components.concept.engine.InputResultDetail
+import mozilla.components.concept.engine.selection.SelectionActionDelegate
+import mozilla.components.support.test.any
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+
+@RunWith(AndroidJUnit4::class)
+class EngineViewScrollingBehaviorTest {
+ @Test
+ fun `onStartNestedScroll should attempt scrolling only if browserToolbar is valid`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ doReturn(true).`when`(behavior).shouldScroll
+
+ behavior.dynamicScrollView = null
+ var acceptsNestedScroll = behavior.onStartNestedScroll(
+ coordinatorLayout = mock(),
+ child = mock(),
+ directTargetChild = mock(),
+ target = mock(),
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ )
+ assertFalse(acceptsNestedScroll)
+ verify(behavior, never()).startNestedScroll(anyInt(), anyInt(), any())
+
+ behavior.dynamicScrollView = mock()
+ acceptsNestedScroll = behavior.onStartNestedScroll(
+ coordinatorLayout = mock(),
+ child = mock(),
+ directTargetChild = mock(),
+ target = mock(),
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ )
+ assertTrue(acceptsNestedScroll)
+ verify(behavior).startNestedScroll(anyInt(), anyInt(), any())
+ }
+
+ @Test
+ fun `startNestedScroll should cancel an ongoing snap animation`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ doReturn(true).`when`(behavior).shouldScroll
+
+ val acceptsNestedScroll = behavior.startNestedScroll(
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ view = mock(),
+ )
+
+ assertTrue(acceptsNestedScroll)
+ verify(yTranslator).cancelInProgressTranslation()
+ }
+
+ @Test
+ fun `startNestedScroll should not accept nested scrolls on the horizontal axis`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ doReturn(true).`when`(behavior).shouldScroll
+
+ var acceptsNestedScroll = behavior.startNestedScroll(
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ view = mock(),
+ )
+ assertTrue(acceptsNestedScroll)
+
+ acceptsNestedScroll = behavior.startNestedScroll(
+ axes = ViewCompat.SCROLL_AXIS_HORIZONTAL,
+ type = ViewCompat.TYPE_TOUCH,
+ view = mock(),
+ )
+ assertFalse(acceptsNestedScroll)
+ }
+
+ @Test
+ fun `GIVEN a gesture that doesn't scroll the toolbar WHEN startNestedScroll THEN toolbar is expanded and nested scroll not accepted`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val engineView: EngineView = mock()
+ val inputResultDetail: InputResultDetail = mock()
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ doReturn(false).`when`(behavior).shouldScroll
+ doReturn(true).`when`(inputResultDetail).isTouchUnhandled()
+ behavior.engineView = engineView
+ doReturn(inputResultDetail).`when`(engineView).getInputResultDetail()
+
+ val acceptsNestedScroll = behavior.startNestedScroll(
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ view = mock(),
+ )
+
+ verify(yTranslator).cancelInProgressTranslation()
+ verify(yTranslator).expandWithAnimation(any())
+ assertFalse(acceptsNestedScroll)
+ }
+
+ @Test
+ fun `Behavior should not accept nested scrolls on the horizontal axis`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ behavior.dynamicScrollView = mock()
+ doReturn(true).`when`(behavior).shouldScroll
+
+ var acceptsNestedScroll = behavior.onStartNestedScroll(
+ coordinatorLayout = mock(),
+ child = mock(),
+ directTargetChild = mock(),
+ target = mock(),
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ )
+ assertTrue(acceptsNestedScroll)
+
+ acceptsNestedScroll = behavior.onStartNestedScroll(
+ coordinatorLayout = mock(),
+ child = mock(),
+ directTargetChild = mock(),
+ target = mock(),
+ axes = ViewCompat.SCROLL_AXIS_HORIZONTAL,
+ type = ViewCompat.TYPE_TOUCH,
+ )
+ assertFalse(acceptsNestedScroll)
+ }
+
+ @Test
+ fun `Behavior should delegate the onStartNestedScroll logic`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val view: View = mock()
+ behavior.dynamicScrollView = view
+ val inputType = ViewCompat.TYPE_TOUCH
+ val axes = ViewCompat.SCROLL_AXIS_VERTICAL
+
+ behavior.onStartNestedScroll(
+ coordinatorLayout = mock(),
+ child = view,
+ directTargetChild = mock(),
+ target = mock(),
+ axes = axes,
+ type = inputType,
+ )
+
+ verify(behavior).startNestedScroll(axes, inputType, view)
+ }
+
+ @Test
+ fun `onStopNestedScroll should attempt stopping nested scrolling only if browserToolbar is valid`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+
+ behavior.dynamicScrollView = null
+ behavior.onStopNestedScroll(
+ coordinatorLayout = mock(),
+ child = mock(),
+ target = mock(),
+ type = 0,
+ )
+ verify(behavior, never()).stopNestedScroll(anyInt(), any())
+
+ behavior.dynamicScrollView = mock()
+ behavior.onStopNestedScroll(
+ coordinatorLayout = mock(),
+ child = mock(),
+ target = mock(),
+ type = 0,
+ )
+ verify(behavior).stopNestedScroll(anyInt(), any())
+ }
+
+ @Test
+ fun `Behavior should delegate the onStopNestedScroll logic`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val inputType = ViewCompat.TYPE_TOUCH
+ val view: View = mock()
+
+ behavior.dynamicScrollView = null
+ behavior.onStopNestedScroll(
+ coordinatorLayout = mock(),
+ child = view,
+ target = mock(),
+ type = inputType,
+ )
+ verify(behavior, never()).stopNestedScroll(inputType, view)
+ }
+
+ @Test
+ fun `stopNestedScroll will snap toolbar up if toolbar is more than 50 percent visible`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ behavior.dynamicScrollView = mock()
+ doReturn(true).`when`(behavior).shouldScroll
+
+ val child = mock<View>()
+ doReturn(100).`when`(child).height
+ doReturn(10f).`when`(child).translationY
+
+ behavior.onStartNestedScroll(
+ coordinatorLayout = mock(),
+ child = child,
+ directTargetChild = mock(),
+ target = mock(),
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ )
+
+ assertTrue(behavior.shouldSnapAfterScroll)
+ verify(yTranslator).cancelInProgressTranslation()
+ verify(yTranslator, never()).expandWithAnimation(any())
+ verify(yTranslator, never()).collapseWithAnimation(any())
+
+ behavior.stopNestedScroll(0, child)
+
+ verify(yTranslator).snapWithAnimation(child)
+ }
+
+ @Test
+ fun `stopNestedScroll will snap toolbar down if toolbar is less than 50 percent visible`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ doReturn(true).`when`(behavior).shouldScroll
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+
+ val child = mock<View>()
+ behavior.dynamicScrollView = child
+ doReturn(100).`when`(child).height
+ doReturn(90f).`when`(child).translationY
+
+ behavior.onStartNestedScroll(
+ coordinatorLayout = mock(),
+ child = child,
+ directTargetChild = mock(),
+ target = mock(),
+ axes = ViewCompat.SCROLL_AXIS_VERTICAL,
+ type = ViewCompat.TYPE_TOUCH,
+ )
+
+ assertTrue(behavior.shouldSnapAfterScroll)
+ verify(yTranslator).cancelInProgressTranslation()
+ verify(yTranslator, never()).expandWithAnimation(any())
+ verify(yTranslator, never()).collapseWithAnimation(any())
+
+ behavior.stopNestedScroll(0, child)
+
+ verify(yTranslator).snapWithAnimation(child)
+ }
+
+ @Test
+ fun `onStopNestedScroll should snap the toolbar only if browserToolbar is valid`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ behavior.dynamicScrollView = null
+
+ behavior.onStopNestedScroll(
+ coordinatorLayout = mock(),
+ child = mock(),
+ target = mock(),
+ type = ViewCompat.TYPE_TOUCH,
+ )
+
+ verify(behavior, never()).stopNestedScroll(anyInt(), any())
+ }
+
+ @Test
+ fun `Behavior will intercept MotionEvents and pass them to the custom gesture detector`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val gestureDetector: BrowserGestureDetector = mock()
+ behavior.initGesturesDetector(gestureDetector)
+ behavior.dynamicScrollView = mock()
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+
+ behavior.onInterceptTouchEvent(mock(), mock(), downEvent)
+
+ verify(gestureDetector).handleTouchEvent(downEvent)
+ }
+
+ @Test
+ fun `Behavior should only dispatch MotionEvents to the gesture detector only if browserToolbar is valid`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val gestureDetector: BrowserGestureDetector = mock()
+ behavior.initGesturesDetector(gestureDetector)
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN)
+
+ behavior.onInterceptTouchEvent(mock(), mock(), downEvent)
+
+ verify(gestureDetector, never()).handleTouchEvent(downEvent)
+ }
+
+ @Test
+ fun `Behavior will apply translation to toolbar only for vertical scrolls`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ behavior.initGesturesDetector(behavior.createGestureDetector())
+ val child = spy(View(testContext, null, 0))
+ behavior.dynamicScrollView = child
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 100f, downEvent)
+
+ behavior.onInterceptTouchEvent(mock(), mock(), downEvent)
+ behavior.onInterceptTouchEvent(mock(), mock(), moveEvent)
+
+ verify(behavior).tryToScrollVertically(-100f)
+ }
+
+ @Test
+ fun `GIVEN a null InputResultDetail from the EngineView WHEN shouldScroll is called THEN it returns false`() {
+ val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)
+ behavior.engineView = null
+ assertFalse(behavior.shouldScroll)
+ behavior.engineView = mock()
+ `when`(behavior.engineView!!.getInputResultDetail()).thenReturn(null)
+
+ assertFalse(behavior.shouldScroll)
+ }
+
+ @Test
+ fun `GIVEN an InputResultDetail with the right values and scroll enabled WHEN shouldScroll is called THEN it returns true`() {
+ val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)
+ val engineView: EngineView = mock()
+ behavior.engineView = engineView
+ behavior.isScrollEnabled = true
+ val validInputResultDetail: InputResultDetail = mock()
+ doReturn(validInputResultDetail).`when`(engineView).getInputResultDetail()
+
+ doReturn(true).`when`(validInputResultDetail).canScrollToBottom()
+ doReturn(false).`when`(validInputResultDetail).canScrollToTop()
+ assertTrue(behavior.shouldScroll)
+
+ doReturn(false).`when`(validInputResultDetail).canScrollToBottom()
+ doReturn(true).`when`(validInputResultDetail).canScrollToTop()
+ assertTrue(behavior.shouldScroll)
+
+ doReturn(true).`when`(validInputResultDetail).canScrollToBottom()
+ doReturn(true).`when`(validInputResultDetail).canScrollToTop()
+ assertTrue(behavior.shouldScroll)
+ }
+
+ @Test
+ fun `GIVEN an InputResultDetail with the right values but with scroll disabled WHEN shouldScroll is called THEN it returns false`() {
+ val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)
+ behavior.engineView = mock()
+ behavior.isScrollEnabled = false
+ val validInputResultDetail: InputResultDetail = mock()
+ doReturn(true).`when`(validInputResultDetail).canScrollToBottom()
+ doReturn(true).`when`(validInputResultDetail).canScrollToTop()
+
+ assertFalse(behavior.shouldScroll)
+ }
+
+ @Test
+ fun `GIVEN scroll enabled but EngineView cannot scroll to bottom WHEN shouldScroll is called THEN it returns false`() {
+ val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)
+ behavior.engineView = mock()
+ behavior.isScrollEnabled = true
+ val validInputResultDetail: InputResultDetail = mock()
+ doReturn(false).`when`(validInputResultDetail).canScrollToBottom()
+ doReturn(true).`when`(validInputResultDetail).canScrollToTop()
+
+ assertFalse(behavior.shouldScroll)
+ }
+
+ @Test
+ fun `GIVEN scroll enabled but EngineView cannot scroll to top WHEN shouldScroll is called THEN it returns false`() {
+ val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)
+ behavior.engineView = mock()
+ behavior.isScrollEnabled = true
+ val validInputResultDetail: InputResultDetail = mock()
+ doReturn(true).`when`(validInputResultDetail).canScrollToBottom()
+ doReturn(false).`when`(validInputResultDetail).canScrollToTop()
+
+ assertFalse(behavior.shouldScroll)
+ }
+
+ @Test
+ fun `Behavior will vertically scroll nested scroll started and EngineView handled the event`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ doReturn(true).`when`(behavior).shouldScroll
+ val child = spy(View(testContext, null, 0))
+ behavior.dynamicScrollView = child
+ doReturn(100).`when`(child).height
+ doReturn(0f).`when`(child).translationY
+ behavior.startedScroll = true
+
+ behavior.tryToScrollVertically(25f)
+
+ verify(yTranslator).translate(child, 25f)
+ }
+
+ @Test
+ fun `Behavior will not scroll vertically if startedScroll is false`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ doReturn(true).`when`(behavior).shouldScroll
+ val child = spy(View(testContext, null, 0))
+ behavior.dynamicScrollView = child
+ doReturn(100).`when`(child).height
+ doReturn(0f).`when`(child).translationY
+ behavior.startedScroll = false
+
+ behavior.tryToScrollVertically(25f)
+
+ verify(yTranslator, never()).translate(any(), anyFloat())
+ }
+
+ @Test
+ fun `Behavior will not scroll vertically if EngineView did not handled the event`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ doReturn(false).`when`(behavior).shouldScroll
+ val child = spy(View(testContext, null, 0))
+ behavior.dynamicScrollView = child
+ doReturn(100).`when`(child).height
+ doReturn(0f).`when`(child).translationY
+
+ behavior.tryToScrollVertically(25f)
+
+ verify(yTranslator, never()).translate(any(), anyFloat())
+ }
+
+ @Test
+ fun `forceExpand should delegate the translator`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ val view: View = mock()
+
+ behavior.forceExpand(view)
+
+ verify(yTranslator).expandWithAnimation(view)
+ }
+
+ @Test
+ fun `forceCollapse should delegate the translator`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ val view: View = mock()
+
+ behavior.forceCollapse(view)
+
+ verify(yTranslator).collapseWithAnimation(view)
+ }
+
+ @Test
+ fun `Behavior will forceExpand when scrolling up and !shouldScroll if the touch was handled in the browser`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ behavior.initGesturesDetector(behavior.createGestureDetector())
+ val view: View = spy(View(testContext, null, 0))
+ behavior.dynamicScrollView = view
+ val engineView: EngineView = mock()
+ behavior.engineView = engineView
+ val handledTouchInput = InputResultDetail.newInstance().copy(INPUT_UNHANDLED)
+ doReturn(handledTouchInput).`when`(engineView).getInputResultDetail()
+
+ doReturn(100).`when`(view).height
+ doReturn(100f).`when`(view).translationY
+
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 30f, downEvent)
+
+ behavior.onInterceptTouchEvent(mock(), mock(), downEvent)
+ behavior.onInterceptTouchEvent(mock(), mock(), moveEvent)
+
+ verify(behavior).tryToScrollVertically(-30f)
+ verify(yTranslator).forceExpandIfNotAlready(view, -30f)
+ }
+
+ @Test
+ fun `Behavior will not forceExpand when scrolling up and !shouldScroll if the touch was not yet handled in the browser`() {
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+ val yTranslator: ViewYTranslator = mock()
+ behavior.yTranslator = yTranslator
+ behavior.initGesturesDetector(behavior.createGestureDetector())
+ val view: View = spy(View(testContext, null, 0))
+ behavior.dynamicScrollView = view
+ val engineView: EngineView = mock()
+ behavior.engineView = engineView
+ val handledTouchInput = InputResultDetail.newInstance()
+ doReturn(handledTouchInput).`when`(engineView).getInputResultDetail()
+
+ doReturn(100).`when`(view).height
+ doReturn(100f).`when`(view).translationY
+
+ val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f)
+ val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 30f, downEvent)
+
+ behavior.onInterceptTouchEvent(mock(), mock(), downEvent)
+ behavior.onInterceptTouchEvent(mock(), mock(), moveEvent)
+
+ verify(behavior).tryToScrollVertically(-30f)
+ verify(yTranslator, never()).forceExpandIfNotAlready(view, -30f)
+ }
+
+ @Test
+ fun `onLayoutChild initializes browserToolbar and engineView`() {
+ val view = View(testContext)
+ val engineView = createDummyEngineView(testContext).asView()
+ val container = CoordinatorLayout(testContext).apply {
+ addView(View(testContext))
+ addView(engineView)
+ }
+ val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM))
+
+ behavior.onLayoutChild(container, view, ViewCompat.LAYOUT_DIRECTION_LTR)
+
+ assertEquals(view, behavior.dynamicScrollView)
+ assertEquals(engineView, behavior.engineView)
+ }
+
+ @Test
+ fun `enableScrolling sets isScrollEnabled to true`() {
+ val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)
+
+ assertFalse(behavior.isScrollEnabled)
+ behavior.enableScrolling()
+
+ assertTrue(behavior.isScrollEnabled)
+ }
+
+ @Test
+ fun `disableScrolling sets isScrollEnabled to false`() {
+ val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)
+ behavior.isScrollEnabled = true
+
+ assertTrue(behavior.isScrollEnabled)
+ behavior.disableScrolling()
+
+ assertFalse(behavior.isScrollEnabled)
+ }
+
+ private fun createDummyEngineView(context: Context): EngineView = DummyEngineView(context)
+
+ open class DummyEngineView(context: Context) : FrameLayout(context), EngineView {
+ override fun setVerticalClipping(clippingHeight: Int) {}
+ override fun setDynamicToolbarMaxHeight(height: Int) {}
+ override fun setActivityContext(context: Context?) {}
+ override fun captureThumbnail(onFinish: (Bitmap?) -> Unit) = Unit
+ override fun render(session: EngineSession) {}
+ override fun release() {}
+ override var selectionActionDelegate: SelectionActionDelegate? = null
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/TestUtils.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/TestUtils.kt
new file mode 100644
index 0000000000..2e5bbaa9df
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/TestUtils.kt
@@ -0,0 +1,62 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.view.MotionEvent
+
+object TestUtils {
+ fun getMotionEvent(
+ action: Int,
+ x: Float = 0f,
+ y: Float = 0f,
+ previousEvent: MotionEvent? = null,
+ ): MotionEvent {
+ val currentTime = System.currentTimeMillis()
+ val downTime = previousEvent?.downTime ?: System.currentTimeMillis()
+
+ var pointerCount = previousEvent?.pointerCount ?: 0
+ if (action == MotionEvent.ACTION_POINTER_DOWN) {
+ pointerCount++
+ } else if (action == MotionEvent.ACTION_DOWN) {
+ pointerCount = 1
+ }
+
+ val properties = Array(pointerCount, TestUtils::getPointerProperties)
+ val pointerCoords = getPointerCoords(x, y, pointerCount)
+
+ return MotionEvent.obtain(
+ downTime, currentTime,
+ action, pointerCount, properties,
+ pointerCoords, 0, 0, 1f, 1f, 0, 0, 0, 0,
+ )
+ }
+
+ private fun getPointerCoords(
+ x: Float,
+ y: Float,
+ pointerCount: Int,
+ previousEvent: MotionEvent? = null,
+ ): Array<MotionEvent.PointerCoords?> {
+ val currentEventCoords = MotionEvent.PointerCoords().apply {
+ this.x = x; this.y = y; pressure = 1f; size = 1f
+ }
+
+ return if (pointerCount > 1 && previousEvent != null) {
+ arrayOf(
+ MotionEvent.PointerCoords().apply {
+ this.x = previousEvent.x; this.y = previousEvent.y; pressure = 1f; size = 1f
+ },
+ currentEventCoords,
+ )
+ } else {
+ arrayOf(currentEventCoords)
+ }
+ }
+
+ private fun getPointerProperties(id: Int): MotionEvent.PointerProperties =
+ MotionEvent.PointerProperties().apply {
+ this.id = id; this.toolType = MotionEvent.TOOL_TYPE_FINGER
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt
new file mode 100644
index 0000000000..62d152f7f6
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt
@@ -0,0 +1,712 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.animation.ValueAnimator
+import android.view.View
+import android.view.animation.DecelerateInterpolator
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.support.test.any
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidJUnit4::class)
+class ViewYTranslationStrategyTest {
+ @Test
+ fun `snapAnimator should use a DecelerateInterpolator with SNAP_ANIMATION_DURATION for bottom toolbar translations`() {
+ val strategy = BottomViewBehaviorStrategy()
+
+ assertTrue(strategy.animator.interpolator is DecelerateInterpolator)
+ assertEquals(SNAP_ANIMATION_DURATION, strategy.animator.duration)
+ }
+
+ @Test
+ fun `snapAnimator should use a DecelerateInterpolator with SNAP_ANIMATION_DURATION for top toolbar translations`() {
+ val strategy = TopViewBehaviorStrategy()
+
+ assertTrue(strategy.animator.interpolator is DecelerateInterpolator)
+ assertEquals(SNAP_ANIMATION_DURATION, strategy.animator.duration)
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy should start with isToolbarExpanding = false`() {
+ val strategy = BottomViewBehaviorStrategy()
+
+ assertFalse(strategy.wasLastExpanding)
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy should start with isToolbarExpanding = false`() {
+ val strategy = TopViewBehaviorStrategy()
+
+ assertFalse(strategy.wasLastExpanding)
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapWithAnimation should collapse toolbar if more than half hidden`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(50f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(51f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(100f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(333f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ verify(strategy, times(4)).collapseWithAnimation(view)
+ verify(strategy, never()).expandWithAnimation(view)
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapWithAnimation should expand toolbar if more than half visible`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(49f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(0f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(-50f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ verify(strategy, times(3)).expandWithAnimation(view)
+ verify(strategy, never()).collapseWithAnimation(view)
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapWithAnimation should collapse toolbar if more than half hidden`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(-51f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(-100f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(-333f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ verify(strategy, times(3)).collapseWithAnimation(view)
+ verify(strategy, never()).expandWithAnimation(view)
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapWithAnimation should expand toolbar if more than half visible`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(-50f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(-49f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(0f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ doReturn(50f).`when`(view).translationY
+ strategy.snapWithAnimation(view)
+
+ verify(strategy, times(4)).expandWithAnimation(view)
+ verify(strategy, never()).collapseWithAnimation(view)
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapImmediately should end translations animations if in progress`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(true).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+
+ strategy.snapImmediately(view)
+
+ verify(animator).end()
+ verify(view, never()).translationY
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if half translated`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(50f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 100f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if more than half`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(55f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 100f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if translated off screen`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(555f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 100f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated less than half`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(49f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated 0`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(0f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated inside the screen`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(-1f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapImmediately should end translations animations if in progress`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(true).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+
+ strategy.snapImmediately(view)
+
+ verify(animator).end()
+ verify(view, never()).translationY
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapImmediately should translate translate to 0 the toolbar if translated less than half`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(-49f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated 0`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(0f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated inside the screen`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(1f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if half translated`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(-50f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if more than half translated`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(-55f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = -100f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated offscreen`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ doReturn(-111f).`when`(view).translationY
+ strategy.snapImmediately(view)
+ verify(view).translationY = -100f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - expandWithAnimation should translate the toolbar to to y 0`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val view: View = mock()
+
+ strategy.expandWithAnimation(view)
+
+ verify(strategy).animateToTranslationY(view, 0f)
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - expandWithAnimation should translate the toolbar to to y 0`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val view: View = mock()
+
+ strategy.expandWithAnimation(view)
+
+ verify(strategy).animateToTranslationY(view, 0f)
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should expand toolbar`() {
+ // Setting the scenario in which forceExpandWithAnimation will actually do what the name says.
+ // Below this test we can change each variable one at a time to test them in isolation.
+
+ val strategy = spy(BottomViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, -100f)
+
+ verify(strategy.animator).cancel()
+ verify(strategy).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not force expand the toolbar if not currently collapsing`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ strategy.wasLastExpanding = true
+ val animator: ValueAnimator = mock()
+ doReturn(true).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, -100f)
+
+ verify(strategy.animator, never()).cancel()
+ verify(strategy, never()).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not expand if user swipes down`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(100f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, 100f)
+
+ verify(strategy.animator, never()).cancel()
+ verify(strategy, never()).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not expand the toolbar if it is already expanded`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(0f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, -100f)
+
+ verify(strategy.animator, never()).cancel()
+ verify(strategy, never()).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should expand toolbar`() {
+ // Setting the scenario in which forceExpandWithAnimation will actually do what the name says.
+ // Below this test we can change each variable one at a time to test them in isolation.
+
+ val strategy = spy(TopViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(-100f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, -100f)
+
+ verify(strategy.animator).cancel()
+ verify(strategy).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not force expand the toolbar if not currently collapsing`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ strategy.wasLastExpanding = true
+ val animator: ValueAnimator = mock()
+ doReturn(true).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(-100f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, -100f)
+
+ verify(strategy.animator, never()).cancel()
+ verify(strategy, never()).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not expand if user swipes up`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(-100f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, 10f)
+
+ verify(strategy.animator, never()).cancel()
+ verify(strategy, never()).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not expand the toolbar if it is already expanded`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val animator: ValueAnimator = mock()
+ doReturn(false).`when`(animator).isStarted
+ strategy.animator = animator
+ val view: View = mock()
+ doReturn(0f).`when`(view).translationY
+
+ strategy.forceExpandWithAnimation(view, -100f)
+
+ verify(strategy.animator, never()).cancel()
+ verify(strategy, never()).expandWithAnimation(any())
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - collapseWithAnimation should animate translating the toolbar down, off-screen`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ strategy.collapseWithAnimation(view)
+
+ verify(strategy).animateToTranslationY(view, 100f)
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - collapseWithAnimation should animate translating the toolbar up, off-screen`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+
+ strategy.collapseWithAnimation(view)
+
+ verify(strategy).animateToTranslationY(view, -100f)
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - translate should translate up the toolbar with the distance parameter`() {
+ val strategy = BottomViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(50f).`when`(view).translationY
+
+ strategy.translate(view, -25f)
+
+ verify(view).translationY = 25f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - translate should translate down the toolbar with the distance parameter`() {
+ val strategy = BottomViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(50f).`when`(view).translationY
+
+ strategy.translate(view, 25f)
+
+ verify(view).translationY = 75f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - translate should not translate up the toolbar if already expanded`() {
+ val strategy = BottomViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(0f).`when`(view).translationY
+
+ strategy.translate(view, -1f)
+
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - translate should not translate up the toolbar more than to 0`() {
+ val strategy = BottomViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(50f).`when`(view).translationY
+
+ strategy.translate(view, -51f)
+
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - translate should not translate down the toolbar if already collapsed`() {
+ val strategy = BottomViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(100f).`when`(view).translationY
+
+ strategy.translate(view, 1f)
+
+ verify(view).translationY = 100f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - translate should not translate down the toolbar more than it's height`() {
+ val strategy = BottomViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(50f).`when`(view).translationY
+
+ strategy.translate(view, 51f)
+
+ verify(view).translationY = 100f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - translate should translate down the toolbar with the distance parameter`() {
+ val strategy = TopViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(-50f).`when`(view).translationY
+
+ strategy.translate(view, 25f)
+
+ verify(view).translationY = -75f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - translate should translate up the toolbar with the distance parameter`() {
+ val strategy = TopViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(-50f).`when`(view).translationY
+
+ strategy.translate(view, 25f)
+
+ verify(view).translationY = -75f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - translate should not translate down the toolbar if already expanded`() {
+ val strategy = TopViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(0f).`when`(view).translationY
+
+ strategy.translate(view, -1f)
+
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - translate should not translate down the toolbar more than to 0`() {
+ val strategy = TopViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(-50f).`when`(view).translationY
+
+ strategy.translate(view, -51f)
+
+ verify(view).translationY = 0f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - translate should not translate up the toolbar if already collapsed`() {
+ val strategy = TopViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(-100f).`when`(view).translationY
+
+ strategy.translate(view, 1f)
+
+ verify(view).translationY = -100f
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - translate should not translate up the toolbar more than it's height`() {
+ val strategy = TopViewBehaviorStrategy()
+ val view: View = mock()
+ doReturn(100).`when`(view).height
+ doReturn(-50f).`when`(view).translationY
+
+ strategy.translate(view, 51f)
+
+ verify(view).translationY = -100f
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - animateToTranslationY should set wasLastExpanding if expanding`() {
+ val strategy = BottomViewBehaviorStrategy()
+ strategy.wasLastExpanding = false
+ val view: View = mock()
+ doReturn(50f).`when`(view).translationY
+
+ strategy.animateToTranslationY(view, 10f)
+ assertTrue(strategy.wasLastExpanding)
+
+ strategy.animateToTranslationY(view, 60f)
+ assertFalse(strategy.wasLastExpanding)
+ }
+
+ @Test
+ fun `BottomToolbarBehaviorStrategy - animateToTranslationY should animate to the indicated y translation`() {
+ val strategy = spy(BottomViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val view = View(testContext)
+ val animator: ValueAnimator = spy(strategy.animator)
+ strategy.animator = animator
+
+ strategy.animateToTranslationY(view, 10f)
+
+ verify(animator).start()
+ animator.end()
+ assertEquals(10f, view.translationY)
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - animateToTranslationY should set wasLastExpanding if expanding`() {
+ val strategy = TopViewBehaviorStrategy()
+ strategy.wasLastExpanding = false
+ val view: View = mock()
+ doReturn(-50f).`when`(view).translationY
+
+ strategy.animateToTranslationY(view, -10f)
+ assertTrue(strategy.wasLastExpanding)
+
+ strategy.animateToTranslationY(view, -60f)
+ assertFalse(strategy.wasLastExpanding)
+ }
+
+ @Test
+ fun `TopToolbarBehaviorStrategy - animateToTranslationY should animate to the indicated y translation`() {
+ val strategy = spy(TopViewBehaviorStrategy())
+ strategy.wasLastExpanding = false
+ val view = View(testContext)
+ val animator: ValueAnimator = spy(strategy.animator)
+ strategy.animator = animator
+
+ strategy.animateToTranslationY(view, -10f)
+
+ verify(animator).start()
+ animator.end()
+ assertEquals(-10f, view.translationY)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt
new file mode 100644
index 0000000000..6a3a908adc
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt
@@ -0,0 +1,113 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.ui.widgets.behavior
+
+import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.support.test.mock
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidJUnit4::class)
+class ViewYTranslatorTest {
+ @Test
+ fun `yTranslator should use BottomToolbarBehaviorStrategy for bottom placed toolbars`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+
+ assertTrue(yTranslator.strategy is BottomViewBehaviorStrategy)
+ }
+
+ @Test
+ fun `yTranslator should use TopToolbarBehaviorStrategy for top placed toolbars`() {
+ val yTranslator = ViewYTranslator(ViewPosition.TOP)
+
+ assertTrue(yTranslator.strategy is TopViewBehaviorStrategy)
+ }
+
+ @Test
+ fun `yTranslator should delegate it's strategy for snapWithAnimation`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+ val strategy: ViewYTranslationStrategy = mock()
+ yTranslator.strategy = strategy
+ val view: View = mock()
+
+ yTranslator.snapWithAnimation(view)
+
+ verify(strategy).snapWithAnimation(view)
+ }
+
+ @Test
+ fun `yTranslator should delegate it's strategy for expandWithAnimation`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+ val strategy: ViewYTranslationStrategy = mock()
+ yTranslator.strategy = strategy
+ val view: View = mock()
+
+ yTranslator.expandWithAnimation(view)
+
+ verify(strategy).expandWithAnimation(view)
+ }
+
+ @Test
+ fun `yTranslator should delegate it's strategy for collapseWithAnimation`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+ val strategy: ViewYTranslationStrategy = mock()
+ yTranslator.strategy = strategy
+ val view: View = mock()
+
+ yTranslator.collapseWithAnimation(view)
+
+ verify(strategy).collapseWithAnimation(view)
+ }
+
+ @Test
+ fun `yTranslator should delegate it's strategy for forceExpandIfNotAlready`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+ val strategy: ViewYTranslationStrategy = mock()
+ yTranslator.strategy = strategy
+ val view: View = mock()
+
+ yTranslator.forceExpandIfNotAlready(view, 14f)
+
+ verify(strategy).forceExpandWithAnimation(view, 14f)
+ }
+
+ @Test
+ fun `yTranslator should delegate it's strategy for translate`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+ val strategy: ViewYTranslationStrategy = mock()
+ yTranslator.strategy = strategy
+ val view: View = mock()
+
+ yTranslator.translate(view, 23f)
+
+ verify(strategy).translate(view, 23f)
+ }
+
+ @Test
+ fun `yTranslator should delegate it's strategy for cancelInProgressTranslation`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+ val strategy: ViewYTranslationStrategy = mock()
+ yTranslator.strategy = strategy
+
+ yTranslator.cancelInProgressTranslation()
+
+ verify(strategy).cancelInProgressTranslation()
+ }
+
+ @Test
+ fun `yTranslator should delegate it's strategy for snapImmediately`() {
+ val yTranslator = ViewYTranslator(ViewPosition.BOTTOM)
+ val strategy: ViewYTranslationStrategy = mock()
+ yTranslator.strategy = strategy
+ val view: View = mock()
+
+ yTranslator.snapImmediately(view)
+
+ verify(strategy).snapImmediately(view)
+ }
+}
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/mobile/android/android-components/components/ui/widgets/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000..cf1c399ea8
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1,2 @@
+mock-maker-inline
+// This allows mocking final classes (classes are final by default in Kotlin)
diff --git a/mobile/android/android-components/components/ui/widgets/src/test/resources/robolectric.properties b/mobile/android/android-components/components/ui/widgets/src/test/resources/robolectric.properties
new file mode 100644
index 0000000000..932b01b9eb
--- /dev/null
+++ b/mobile/android/android-components/components/ui/widgets/src/test/resources/robolectric.properties
@@ -0,0 +1 @@
+sdk=28