From 0ebc76d8609152153d7e43f1c59af3525cb370ba Mon Sep 17 00:00:00 2001 From: Alex Lementuev Date: Mon, 6 Nov 2017 16:52:43 -0800 Subject: [PATCH] Apptentive Android SDK 4.1.0 --- .gitignore | 3 +- .idea/.name | 1 - .travis.yml | 20 +- CHANGELOG.md | 13 + README.md | 2 +- apptentive/build.gradle | 16 +- .../conversation/FileMessageStoreTest.java | 5 +- apptentive/src/main/AndroidManifest.xml | 9 + .../android/sdk/ApptentiveInternal.java | 54 +- .../apptentive/android/sdk/ApptentiveLog.java | 8 + .../android/sdk/ApptentiveLogTag.java | 1 + .../android/sdk/ApptentiveNotifications.java | 16 + .../android/sdk/ApptentiveViewActivity.java | 9 + .../sdk/comm/ApptentiveHttpClient.java | 23 +- .../sdk/conversation/Conversation.java | 7 + .../sdk/conversation/ConversationManager.java | 78 +- .../sdk/debug/AttachmentFileProvider.java | 110 +++ .../sdk/debug/LogBroadcastReceiver.java | 90 ++ .../android/sdk/debug/LogMonitor.java | 533 ++++++++++++ .../android/sdk/debug/LogWriter.java | 138 +++ .../debug/TroubleshootingNotification.java | 110 +++ .../migration/v4_0_0/VersionHistoryStore.java | 18 +- .../v4_0_0/VersionHistoryStoreMigrator.java | 22 +- .../sdk/model/CommerceExtendedData.java | 3 +- .../android/sdk/model/TimeExtendedData.java | 2 + .../fragment/ApptentiveBaseFragment.java | 4 + .../fragment/EnjoymentDialogFragment.java | 15 +- .../fragment/MessageCenterErrorFragment.java | 9 +- .../fragment/MessageCenterFragment.java | 5 + .../interaction/fragment/NoteFragment.java | 4 +- .../interaction/fragment/SurveyFragment.java | 44 +- .../model/InteractionCriteria.java | 5 +- .../interaction/model/Invocation.java | 6 +- .../model/MessageCenterInteraction.java | 4 +- .../engagement/interaction/model/Targets.java | 8 +- .../model/survey/BaseQuestion.java | 6 + .../interaction/model/survey/Question.java | 1 + .../view/survey/BaseSurveyQuestionView.java | 5 + .../view/survey/SurveyQuestionView.java | 5 + .../view/survey/TextSurveyQuestionView.java | 2 + .../sdk/module/engagement/logic/Clause.java | 2 +- .../engagement/logic/ConditionalClause.java | 4 +- .../module/engagement/logic/FieldManager.java | 105 ++- .../engagement/logic/LogicalClause.java | 8 +- .../module/messagecenter/MessageManager.java | 11 +- .../view/AttachmentPreviewDialog.java | 6 +- .../view/holder/GreetingHolder.java | 2 + .../view/holder/MessageComposerHolder.java | 3 +- .../holder/OutgoingCompoundMessageHolder.java | 2 + .../view/holder/WhoCardHolder.java | 22 +- .../android/sdk/network/HttpRequest.java | 4 + .../sdk/storage/AppReleaseManager.java | 4 +- .../android/sdk/storage/DeviceManager.java | 2 +- .../android/sdk/storage/EventData.java | 6 + .../android/sdk/storage/SdkManager.java | 21 +- .../android/sdk/storage/VersionHistory.java | 14 +- .../android/sdk/util/Constants.java | 11 +- .../com/apptentive/android/sdk/util/Util.java | 58 ++ .../sdk/util/image/ImageGridViewAdapter.java | 68 +- .../sdk/util/image/PreviewImageView.java | 10 +- .../sdk/view/ApptentiveNestedScrollView.java | 2 +- ...droid_textfield_activated_holo_light.9.png | Bin 1129 -> 0 bytes .../apptentive_checkmark_alt_40dp.png | Bin 1419 -> 0 bytes .../apptentive_generic_file_thumbnail.png | Bin 978 -> 0 bytes ...entive_generic_file_thumbnail_download.png | Bin 1078 -> 0 bytes .../apptentive_ic_action_attach.png | Bin 330 -> 0 bytes .../apptentive_ic_action_send.png | Bin 364 -> 0 bytes .../res/drawable-hdpi/apptentive_ic_add.png | Bin 744 -> 0 bytes .../apptentive_ic_back_preview.png | Bin 279 -> 0 bytes .../drawable-hdpi/apptentive_ic_branding.png | Bin 3307 -> 0 bytes .../drawable-hdpi/apptentive_ic_compose.png | Bin 420 -> 0 bytes .../apptentive_ic_composing_close.png | Bin 410 -> 0 bytes .../res/drawable-hdpi/apptentive_ic_info.png | Bin 379 -> 0 bytes .../apptentive_ic_profile_edit.png | Bin 343 -> 0 bytes .../apptentive_ic_remove_attachment.png | Bin 1252 -> 0 bytes .../apptentive_ic_toolbar_close.png | Bin 324 -> 0 bytes .../apptentive_icon_no_connection.png | Bin 862 -> 0 bytes .../apptentive_icon_server_error.png | Bin 936 -> 0 bytes .../drawable-hdpi/apptentive_status_gear.png | Bin 0 -> 969 bytes ...droid_textfield_activated_holo_light.9.png | Bin 1099 -> 0 bytes .../apptentive_checkmark_alt_40dp.png | Bin 940 -> 0 bytes .../apptentive_generic_file_thumbnail.png | Bin 699 -> 0 bytes ...entive_generic_file_thumbnail_download.png | Bin 777 -> 0 bytes .../apptentive_ic_action_attach.png | Bin 194 -> 0 bytes .../apptentive_ic_action_send.png | Bin 268 -> 0 bytes .../res/drawable-mdpi/apptentive_ic_add.png | Bin 501 -> 0 bytes .../apptentive_ic_back_preview.png | Bin 223 -> 0 bytes .../drawable-mdpi/apptentive_ic_branding.png | Bin 2057 -> 0 bytes .../drawable-mdpi/apptentive_ic_compose.png | Bin 320 -> 0 bytes .../apptentive_ic_composing_close.png | Bin 321 -> 0 bytes .../res/drawable-mdpi/apptentive_ic_info.png | Bin 247 -> 0 bytes .../apptentive_ic_profile_edit.png | Bin 256 -> 0 bytes .../apptentive_ic_remove_attachment.png | Bin 805 -> 0 bytes .../apptentive_ic_toolbar_close.png | Bin 279 -> 0 bytes .../apptentive_icon_no_connection.png | Bin 595 -> 0 bytes .../apptentive_icon_server_error.png | Bin 621 -> 0 bytes .../drawable-mdpi/apptentive_status_gear.png | Bin 0 -> 712 bytes ...droid_textfield_activated_holo_light.9.png | Bin 1144 -> 0 bytes .../apptentive_checkmark_alt_40dp.png | Bin 2014 -> 0 bytes .../apptentive_generic_file_thumbnail.png | Bin 1331 -> 0 bytes ...entive_generic_file_thumbnail_download.png | Bin 1486 -> 0 bytes .../apptentive_ic_action_attach.png | Bin 324 -> 0 bytes .../apptentive_ic_action_send.png | Bin 458 -> 0 bytes .../res/drawable-xhdpi/apptentive_ic_add.png | Bin 1017 -> 0 bytes .../apptentive_ic_back_preview.png | Bin 326 -> 0 bytes .../drawable-xhdpi/apptentive_ic_branding.png | Bin 4624 -> 0 bytes .../apptentive_ic_btn_check_on.png | Bin 578 -> 0 bytes .../drawable-xhdpi/apptentive_ic_compose.png | Bin 484 -> 0 bytes .../apptentive_ic_composing_close.png | Bin 503 -> 0 bytes .../res/drawable-xhdpi/apptentive_ic_info.png | Bin 442 -> 0 bytes .../apptentive_ic_profile_edit.png | Bin 446 -> 0 bytes .../apptentive_ic_remove_attachment.png | Bin 1743 -> 0 bytes .../apptentive_ic_toolbar_close.png | Bin 402 -> 0 bytes .../apptentive_icon_no_connection.png | Bin 1129 -> 0 bytes .../apptentive_icon_server_error.png | Bin 1181 -> 0 bytes .../drawable-xhdpi/apptentive_status_gear.png | Bin 0 -> 1585 bytes .../apptentive_checkmark_alt_40dp.png | Bin 3474 -> 0 bytes .../apptentive_generic_file_thumbnail.png | Bin 2036 -> 0 bytes ...entive_generic_file_thumbnail_download.png | Bin 2209 -> 0 bytes .../apptentive_ic_action_attach.png | Bin 452 -> 0 bytes .../apptentive_ic_action_send.png | Bin 639 -> 0 bytes .../res/drawable-xxhdpi/apptentive_ic_add.png | Bin 1529 -> 0 bytes .../apptentive_ic_back_preview.png | Bin 413 -> 0 bytes .../apptentive_ic_branding.png | Bin 7138 -> 0 bytes .../apptentive_ic_btn_check_on.png | Bin 643 -> 0 bytes .../drawable-xxhdpi/apptentive_ic_compose.png | Bin 640 -> 0 bytes .../apptentive_ic_composing_close.png | Bin 703 -> 0 bytes .../apptentive_ic_image_default_item.png | Bin 1041 -> 0 bytes .../apptentive_ic_image_picker_selected.png | Bin 1708 -> 0 bytes .../apptentive_ic_image_picker_unselected.png | Bin 362 -> 0 bytes .../drawable-xxhdpi/apptentive_ic_info.png | Bin 651 -> 0 bytes .../apptentive_ic_profile_edit.png | Bin 673 -> 0 bytes .../apptentive_ic_remove_attachment.png | Bin 2824 -> 0 bytes .../apptentive_ic_toolbar_close.png | Bin 499 -> 0 bytes .../apptentive_icon_no_connection.png | Bin 1645 -> 0 bytes .../apptentive_icon_server_error.png | Bin 1702 -> 0 bytes .../apptentive_status_gear.png | Bin 0 -> 2034 bytes .../apptentive_checkmark_alt_40dp.png | Bin 5063 -> 0 bytes .../apptentive_generic_file_thumbnail.png | Bin 2868 -> 0 bytes ...entive_generic_file_thumbnail_download.png | Bin 3111 -> 0 bytes .../apptentive_ic_action_attach.png | Bin 568 -> 0 bytes .../apptentive_ic_action_send.png | Bin 822 -> 0 bytes .../drawable-xxxhdpi/apptentive_ic_add.png | Bin 2048 -> 0 bytes .../apptentive_ic_back_preview.png | Bin 238 -> 0 bytes .../apptentive_ic_branding.png | Bin 9625 -> 0 bytes .../apptentive_ic_composing_close.png | Bin 923 -> 0 bytes .../drawable-xxxhdpi/apptentive_ic_info.png | Bin 854 -> 0 bytes .../apptentive_ic_profile_edit.png | Bin 884 -> 0 bytes .../apptentive_ic_remove_attachment.png | Bin 3853 -> 0 bytes .../apptentive_ic_toolbar_close.png | Bin 662 -> 0 bytes .../apptentive_icon_no_connection.png | Bin 2118 -> 0 bytes .../apptentive_icon_server_error.png | Bin 2203 -> 0 bytes .../apptentive_status_gear.png | Bin 0 -> 3184 bytes .../apptentive_add_circle_outline.xml | 15 + .../res/drawable/apptentive_arrow_back.xml | 15 + .../res/drawable/apptentive_attach_icon.xml | 15 + .../res/drawable/apptentive_check_icon.xml | 15 + .../res/drawable/apptentive_close_x_dark.xml | 14 + .../res/drawable/apptentive_close_x_light.xml | 14 + .../res/drawable/apptentive_file_download.xml | 15 + .../res/drawable/apptentive_file_icon.xml | 15 + ...pptentive_ic_action_attach_auto_mirror.xml | 10 - .../apptentive_ic_action_send_auto_mirror.xml | 10 - .../apptentive_ic_compose_auto_mirror.xml | 10 - .../main/res/drawable/apptentive_ic_error.xml | 14 + .../main/res/drawable/apptentive_ic_info.xml | 14 + .../drawable/apptentive_ic_no_connection.xml | 15 + .../drawable/apptentive_image_placeholder.xml | 15 + .../apptentive_listview_item_shadow.xml | 10 - .../res/drawable/apptentive_pencil_icon.xml | 15 + .../drawable/apptentive_person_icon_dark.xml | 14 + .../drawable/apptentive_person_icon_light.xml | 14 + .../res/drawable/apptentive_remove_button.xml | 33 + .../res/drawable/apptentive_remove_icon.xml | 15 + .../res/drawable/apptentive_send_icon.xml | 11 + .../src/main/res/layout/apptentive_about.xml | 9 +- .../main/res/layout/apptentive_branding.xml | 2 +- .../apptentive_dialog_image_preview.xml | 31 +- ...pptentive_enjoyment_dialog_interaction.xml | 3 +- .../apptentive_image_grid_view_item.xml | 41 +- .../res/layout/apptentive_message_center.xml | 4 +- .../apptentive_message_center_composer.xml | 13 +- ...tentive_message_center_context_message.xml | 3 +- .../apptentive_message_center_error.xml | 14 +- .../apptentive_message_center_greeting.xml | 10 +- .../apptentive_message_center_status.xml | 22 +- .../layout/apptentive_message_incoming.xml | 9 +- .../layout/apptentive_message_outgoing.xml | 9 +- .../apptentive_survey_question_base.xml | 10 +- ...ive_survey_question_multichoice_choice.xml | 3 +- ...ive_survey_question_multiselect_choice.xml | 3 +- ...pptentive_survey_question_range_answer.xml | 6 +- .../layout/apptentive_survey_sent_toast.xml | 11 +- .../src/main/res/values/apptentive-attrs.xml | 2 + apptentive/src/main/res/values/strings.xml | 6 + apptentive/src/main/res/values/styles.xml | 5 +- apptentive/src/main/res/values/themes.xml | 14 +- .../android/sdk/ApptentiveInternalMock.java | 12 - build.gradle | 6 +- samples/apptentive-example/build.gradle | 10 +- .../android/example/ExampleApplication.java | 2 +- .../src/main/res/values/strings.xml | 2 - settings.gradle | 7 +- tests/test-app/build.gradle | 8 +- .../payloads/testCorruptedJson.json | 13 - .../payloads/testCriteriaTimeAtInstall.json | 107 +-- .../testListOfVariousInteractions.json | 124 +-- .../testMissingNullEmptyCriteria.json | 50 -- .../payloads/testQueriesAgainstDevice.json | 73 +- .../payloads/testQueriesAgainstPerson.json | 89 +- .../payloads/testQueriesAgainstSdk.json | 67 +- .../payloads/upgradeMessageOnVersionCode.json | 34 +- .../payloads/upgradeMessageOnVersionName.json | 40 +- .../assets/model/testExtendedDataEvents.json | 2 +- .../model/testParsingTextMessageResponse.json | 2 +- .../sdk/tests/ApptentiveTestCaseBase.java | 38 +- .../android/sdk/tests/model/EventTests.java | 14 +- .../sdk/tests/model/ExtendedDataTests.java | 70 +- .../tests/model/VersionHistoryStoreTest.java | 77 +- .../engagement/CriteriaParsingTest.java | 2 - .../engagement/DataObjectQueryTest.java | 131 ++- .../module/engagement/InteractionTest.java | 453 ++++------ .../CodePointAndInteractionStoreTest.java | 802 +++++++++--------- .../engagement/criteria/CornerCases.java | 57 +- .../engagement/criteria/DefaultValues.java | 27 +- .../engagement/criteria/OperatorTests.java | 68 +- .../criteria/WhitespaceTrimmingTest.java | 39 +- .../messagecenter/JsonObjectBindingTest.java | 35 +- .../messagecenter/MockMessageManager.java | 16 + .../sdk/tests/push/ApptentivePayload.java | 11 +- .../android/sdk/tests/push/AwsSns.java | 5 +- .../android/sdk/tests/push/Fcm.java | 5 +- .../android/sdk/tests/push/Gcm.java | 5 +- .../android/sdk/tests/push/OldStylePush.java | 55 +- .../android/sdk/tests/push/Parse.java | 113 --- .../android/sdk/tests/push/UrbanAirship.java | 40 +- .../res/raw/test_extended_data_events.json | 40 - 237 files changed, 3136 insertions(+), 1942 deletions(-) delete mode 100644 .idea/.name create mode 100644 apptentive/src/main/java/com/apptentive/android/sdk/debug/AttachmentFileProvider.java create mode 100644 apptentive/src/main/java/com/apptentive/android/sdk/debug/LogBroadcastReceiver.java create mode 100644 apptentive/src/main/java/com/apptentive/android/sdk/debug/LogMonitor.java create mode 100644 apptentive/src/main/java/com/apptentive/android/sdk/debug/LogWriter.java create mode 100644 apptentive/src/main/java/com/apptentive/android/sdk/debug/TroubleshootingNotification.java delete mode 100644 apptentive/src/main/res/drawable-hdpi/android_textfield_activated_holo_light.9.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_checkmark_alt_40dp.png delete mode 100755 apptentive/src/main/res/drawable-hdpi/apptentive_generic_file_thumbnail.png delete mode 100755 apptentive/src/main/res/drawable-hdpi/apptentive_generic_file_thumbnail_download.png delete mode 100755 apptentive/src/main/res/drawable-hdpi/apptentive_ic_action_attach.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_ic_action_send.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_ic_add.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_ic_back_preview.png delete mode 100755 apptentive/src/main/res/drawable-hdpi/apptentive_ic_branding.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_ic_compose.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_ic_composing_close.png delete mode 100755 apptentive/src/main/res/drawable-hdpi/apptentive_ic_info.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_ic_profile_edit.png delete mode 100755 apptentive/src/main/res/drawable-hdpi/apptentive_ic_remove_attachment.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_ic_toolbar_close.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_icon_no_connection.png delete mode 100644 apptentive/src/main/res/drawable-hdpi/apptentive_icon_server_error.png create mode 100755 apptentive/src/main/res/drawable-hdpi/apptentive_status_gear.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/android_textfield_activated_holo_light.9.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_checkmark_alt_40dp.png delete mode 100755 apptentive/src/main/res/drawable-mdpi/apptentive_generic_file_thumbnail.png delete mode 100755 apptentive/src/main/res/drawable-mdpi/apptentive_generic_file_thumbnail_download.png delete mode 100755 apptentive/src/main/res/drawable-mdpi/apptentive_ic_action_attach.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_ic_action_send.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_ic_add.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_ic_back_preview.png delete mode 100755 apptentive/src/main/res/drawable-mdpi/apptentive_ic_branding.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_ic_compose.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_ic_composing_close.png delete mode 100755 apptentive/src/main/res/drawable-mdpi/apptentive_ic_info.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_ic_profile_edit.png delete mode 100755 apptentive/src/main/res/drawable-mdpi/apptentive_ic_remove_attachment.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_ic_toolbar_close.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_icon_no_connection.png delete mode 100644 apptentive/src/main/res/drawable-mdpi/apptentive_icon_server_error.png create mode 100755 apptentive/src/main/res/drawable-mdpi/apptentive_status_gear.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/android_textfield_activated_holo_light.9.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_checkmark_alt_40dp.png delete mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_generic_file_thumbnail.png delete mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_generic_file_thumbnail_download.png delete mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_action_attach.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_action_send.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_add.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_back_preview.png delete mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_branding.png delete mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_btn_check_on.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_compose.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_composing_close.png delete mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_info.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_profile_edit.png delete mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_remove_attachment.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_ic_toolbar_close.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_icon_no_connection.png delete mode 100644 apptentive/src/main/res/drawable-xhdpi/apptentive_icon_server_error.png create mode 100755 apptentive/src/main/res/drawable-xhdpi/apptentive_status_gear.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_checkmark_alt_40dp.png delete mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_generic_file_thumbnail.png delete mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_generic_file_thumbnail_download.png delete mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_action_attach.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_action_send.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_add.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_back_preview.png delete mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_branding.png delete mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_btn_check_on.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_compose.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_composing_close.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_image_default_item.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_image_picker_selected.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_image_picker_unselected.png delete mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_info.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_profile_edit.png delete mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_remove_attachment.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_toolbar_close.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_icon_no_connection.png delete mode 100644 apptentive/src/main/res/drawable-xxhdpi/apptentive_icon_server_error.png create mode 100755 apptentive/src/main/res/drawable-xxhdpi/apptentive_status_gear.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_checkmark_alt_40dp.png delete mode 100755 apptentive/src/main/res/drawable-xxxhdpi/apptentive_generic_file_thumbnail.png delete mode 100755 apptentive/src/main/res/drawable-xxxhdpi/apptentive_generic_file_thumbnail_download.png delete mode 100755 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_action_attach.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_action_send.png delete mode 100755 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_add.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_back_preview.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_branding.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_composing_close.png delete mode 100755 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_info.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_profile_edit.png delete mode 100755 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_remove_attachment.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_toolbar_close.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_icon_no_connection.png delete mode 100644 apptentive/src/main/res/drawable-xxxhdpi/apptentive_icon_server_error.png create mode 100755 apptentive/src/main/res/drawable-xxxhdpi/apptentive_status_gear.png create mode 100644 apptentive/src/main/res/drawable/apptentive_add_circle_outline.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_arrow_back.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_attach_icon.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_check_icon.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_close_x_dark.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_close_x_light.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_file_download.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_file_icon.xml delete mode 100644 apptentive/src/main/res/drawable/apptentive_ic_action_attach_auto_mirror.xml delete mode 100644 apptentive/src/main/res/drawable/apptentive_ic_action_send_auto_mirror.xml delete mode 100644 apptentive/src/main/res/drawable/apptentive_ic_compose_auto_mirror.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_ic_error.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_ic_info.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_ic_no_connection.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_image_placeholder.xml delete mode 100644 apptentive/src/main/res/drawable/apptentive_listview_item_shadow.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_pencil_icon.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_person_icon_dark.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_person_icon_light.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_remove_button.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_remove_icon.xml create mode 100644 apptentive/src/main/res/drawable/apptentive_send_icon.xml delete mode 100644 apptentive/src/testCommon/java/com/apptentive/android/sdk/ApptentiveInternalMock.java delete mode 100644 tests/test-app/src/androidTest/assets/engagement/payloads/testCorruptedJson.json delete mode 100644 tests/test-app/src/androidTest/assets/engagement/payloads/testMissingNullEmptyCriteria.json create mode 100644 tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/module/messagecenter/MockMessageManager.java delete mode 100644 tests/test-app/src/androidTest/java/com/apptentive/android/sdk/tests/push/Parse.java delete mode 100644 tests/test-app/src/main/res/raw/test_extended_data_events.json diff --git a/.gitignore b/.gitignore index 65a64d0fe..7c5e5efa7 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ gen/ out/ bin/ build/ +captures/ # IntelliJ *.iws @@ -29,4 +30,4 @@ projectFilesBackup/ # Eclipse .settings -.metadata \ No newline at end of file +.metadata diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index b47a17094..000000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -apptentive-android \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index e1f41ecd3..191cfb0ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: android +dist: precise env: global: - SNAPSHOT_REPOSITORY_USERNAME=travis @@ -16,16 +17,16 @@ cache: - $HOME/.android/build-cache android: components: - - tools - tools - platform-tools - - build-tools-25.0.3 + - tools # not a mistakenly duplicated line: used above api 25.x + - build-tools-26.0.2 - android-19 - - android-24 - - android-25 + - android-26 - extra-google-google_play_services - extra-google-m2repository - - addon-google_apis-google-25 + - extra-android-m2repository + - addon-google_apis-google-26 - sys-img-armeabi-v7a-android-19 install: true before_script: @@ -33,12 +34,21 @@ before_script: - emulator -avd test -no-audio -no-window & - android-wait-for-emulator - adb shell input keyevent 82 & + #- adb -e logcat *:W | tee logcat.log > /dev/null 2>&1 & script: - ./gradlew :apptentive:test -i + - ./gradlew :test-app:connectedAndroidTest +# - if [ -d "apptentive-internal-app" ]; then ./gradlew :apptentive-internal-app:installAutomatedDebug; fi +# - if [ -d "apptentive-internal-app" ]; then ./gradlew :apptentive-internal-app:installAutomatedDebugAndroidTest; fi +# - if [ -d "apptentive-internal-app" ]; then ./gradlew :apptentive-internal-app:connectedAutomatedDebugAndroidTest -i; fi + - if [ -d "apptentive-internal-app" ]; then ./gradlew :apptentive-internal-app:assembleQaDebug; fi after_script: - if [ "$TRAVIS_BRANCH" = "develop" ]; then ./gradlew :apptentive:uploadArchives; + if [ -d "apptentive-internal-app" ]; then ./gradlew :apptentive-internal-app:uploadQaDebugToHockeyApp; fi; fi +after_failure: + #- echo " LOGCAT "; echo "========"; cat logcat.log; pkill -KILL -f adb notifications: slack: secure: HejMl0EUociwGu+5djx95snbS+m/Yw8DseQKCSqeyWvMQLrAy8bi9oa89mZvXnvjqSVY3kKRZgJncEkQdIe9c7xwgNA9QYLkc7UVbXqga291HMoNnWaIMewD2ervbzM4aBQAHnkDr+GsXgb7+1YdOktIn8dA7jdIuB90ar4So9U= diff --git a/CHANGELOG.md b/CHANGELOG.md index e660b4265..120049de1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# 2017-11-06 - v4.1.0 + +#### Improvements + +* Improved accessibility of Surveys and Message center for the visually impaired +* Made use of vector drawables to cut down on AAR and APK size +* Added the ability to enable troubleshooting mode in the SDK, and easily email logs to Apptentive support + +#### Bugs Fixed + +* Fix global configuration fetching +* Fix Love Dialog to stack buttons if their labels are too long + # 2017-08-15 - v4.0.2 #### Bugs Fixed diff --git a/README.md b/README.md index 2eddd5c86..07139ec06 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ use your app, to talk to them at the right time, and in the right way. ##### [Release Notes](https://learn.apptentive.com/knowledge-base/android-sdk-release-notes/) -##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|4.0.2|aar) +##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|4.1.0|aar) #### Reporting Bugs diff --git a/apptentive/build.gradle b/apptentive/build.gradle index 80d4293c7..2d07fd1a6 100644 --- a/apptentive/build.gradle +++ b/apptentive/build.gradle @@ -3,10 +3,10 @@ init() apply plugin: 'com.android.library' dependencies { - compile 'com.android.support:support-v4:24.2.1' - compile 'com.android.support:appcompat-v7:24.2.1' - compile 'com.android.support:cardview-v7:24.2.1' - compile 'com.android.support:design:24.2.1' + compile 'com.android.support:support-v4:26.1.0' + compile 'com.android.support:appcompat-v7:26.1.0' + compile 'com.android.support:cardview-v7:26.1.0' + compile 'com.android.support:design:26.1.0' testCompile 'junit:junit:4.12' testCompile "org.powermock:powermock-module-junit4:1.6.2" testCompile "org.powermock:powermock-module-junit4-rule:1.6.2" @@ -14,14 +14,14 @@ dependencies { testCompile "org.powermock:powermock-classloading-xstream:1.6.2" // Required for instrumented tests - androidTestCompile 'com.android.support:support-annotations:24.2.1' + androidTestCompile 'com.android.support:support-annotations:26.1.0' androidTestCompile 'com.android.support.test:runner:0.5' androidTestCompile 'com.android.support.test:rules:0.5' } android { - compileSdkVersion 25 - buildToolsVersion '25.0.3' + compileSdkVersion 26 + buildToolsVersion '26.0.2' defaultConfig { minSdkVersion 14 @@ -31,6 +31,8 @@ android { versionName project.version consumerProguardFiles 'consumer-proguard-rules.pro' testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + resValue "string", "apptentive_distribution_version", versionName + vectorDrawables.useSupportLibrary = true } lintOptions { diff --git a/apptentive/src/androidTest/java/com/apptentive/android/sdk/conversation/FileMessageStoreTest.java b/apptentive/src/androidTest/java/com/apptentive/android/sdk/conversation/FileMessageStoreTest.java index f833e83ee..b405f5e15 100644 --- a/apptentive/src/androidTest/java/com/apptentive/android/sdk/conversation/FileMessageStoreTest.java +++ b/apptentive/src/androidTest/java/com/apptentive/android/sdk/conversation/FileMessageStoreTest.java @@ -6,8 +6,9 @@ package com.apptentive.android.sdk.conversation; +import android.support.test.InstrumentationRegistry; + import com.apptentive.android.sdk.ApptentiveInternal; -import com.apptentive.android.sdk.ApptentiveInternalMock; import com.apptentive.android.sdk.TestCaseBase; import com.apptentive.android.sdk.model.ApptentiveMessage; import com.apptentive.android.sdk.model.CompoundMessage; @@ -40,7 +41,7 @@ public class FileMessageStoreTest extends TestCaseBase { @Before public void setUp() { super.setUp(); - ApptentiveInternal.setInstance(new ApptentiveInternalMock()); + ApptentiveInternal.setInstance(new ApptentiveInternal(InstrumentationRegistry.getTargetContext())); } @After diff --git a/apptentive/src/main/AndroidManifest.xml b/apptentive/src/main/AndroidManifest.xml index b086b9137..9293b757a 100644 --- a/apptentive/src/main/AndroidManifest.xml +++ b/apptentive/src/main/AndroidManifest.xml @@ -14,7 +14,16 @@ + + + diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java index 1c46b6b61..eaacfb024 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java @@ -28,6 +28,7 @@ import com.apptentive.android.sdk.comm.ApptentiveHttpClient; import com.apptentive.android.sdk.conversation.Conversation; import com.apptentive.android.sdk.conversation.ConversationManager; +import com.apptentive.android.sdk.debug.LogMonitor; import com.apptentive.android.sdk.lifecycle.ApptentiveActivityLifecycleCallbacks; import com.apptentive.android.sdk.model.Configuration; import com.apptentive.android.sdk.model.EventPayload; @@ -56,13 +57,12 @@ import org.json.JSONException; import org.json.JSONObject; +import java.io.File; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import static com.apptentive.android.sdk.ApptentiveLogTag.CONVERSATION; @@ -74,10 +74,12 @@ import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_CONVERSATION_WILL_LOGOUT; import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_INTERACTIONS_FETCHED; import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_INTERACTIONS_SHOULD_DISMISS; +import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_INTERACTION_MANIFEST_FETCHED; import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_KEY_ACTIVITY; import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_KEY_AUTHENTICATION_FAILED_REASON; import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_KEY_CONVERSATION; import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_KEY_CONVERSATION_ID; +import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_KEY_MANIFEST; import static com.apptentive.android.sdk.debug.Assert.assertNotNull; import static com.apptentive.android.sdk.debug.Assert.assertTrue; import static com.apptentive.android.sdk.util.Constants.CONVERSATIONS_DIR; @@ -99,7 +101,6 @@ public class ApptentiveInternal implements ApptentiveNotificationObserver { // We keep a readonly reference to AppRelease object since it won't change at runtime private final AppRelease appRelease; - private boolean appIsInForeground; private final SharedPreferences globalSharedPrefs; private final String apptentiveKey; private final String apptentiveSignature; @@ -151,14 +152,14 @@ public static PushAction parse(String name) { private static volatile ApptentiveInternal sApptentiveInternal; // for unit testing - protected ApptentiveInternal() { + public ApptentiveInternal(Context appContext) { taskManager = null; globalSharedPrefs = null; apptentiveKey = null; apptentiveSignature = null; apptentiveHttpClient = null; conversationManager = null; - appContext = null; + this.appContext = appContext; appRelease = null; lifecycleCallbacks = null; } @@ -188,7 +189,8 @@ private ApptentiveInternal(Application application, String apptentiveKey, String lifecycleCallbacks = new ApptentiveActivityLifecycleCallbacks(); ApptentiveNotificationCenter.defaultCenter() .addObserver(NOTIFICATION_CONVERSATION_WILL_LOGOUT, this) - .addObserver(NOTIFICATION_AUTHENTICATION_FAILED, this); + .addObserver(NOTIFICATION_AUTHENTICATION_FAILED, this) + .addObserver(NOTIFICATION_INTERACTION_MANIFEST_FETCHED, this); } public static boolean isApptentiveRegistered() { @@ -216,6 +218,9 @@ static void createInstance(Application application, String apptentiveKey, String throw new IllegalArgumentException("Application is null"); } + // try initializing log monitor + LogMonitor.tryInitialize(application.getApplicationContext(), apptentiveKey, apptentiveSignature); + synchronized (ApptentiveInternal.class) { if (sApptentiveInternal == null) { @@ -440,14 +445,15 @@ public void onActivityResumed(Activity activity) { } public void onAppEnterForeground() { - appIsInForeground = true; + + // Try to initialize log monitor + LogMonitor.tryInitialize(appContext, apptentiveKey, apptentiveSignature); // Post a notification ApptentiveNotificationCenter.defaultCenter().postNotification(NOTIFICATION_APP_ENTERED_FOREGROUND); } public void onAppEnterBackground() { - appIsInForeground = false; currentTaskStackTopActivity = null; // Post a notification @@ -666,7 +672,7 @@ private void checkSendVersionChanges(Conversation conversation) { conversation.getVersionHistory().updateVersionHistory(Util.currentTimeSeconds(), currentVersionCode, currentVersionName); } - Sdk sdk = SdkManager.generateCurrentSdk(); + Sdk sdk = SdkManager.generateCurrentSdk(appContext); if (sdkChanged) { ApptentiveLog.i("SDK version changed: %s => %s", lastSeenSdkVersion, currentSdkVersion); conversation.setLastSeenSdkVersion(currentSdkVersion); @@ -757,17 +763,6 @@ private void setMinimumLogLevel(ApptentiveLog.Level level) { ApptentiveLog.overrideLogLevel(level); } - private String pushCallbackActivityName; - - public void setPushCallbackActivity(Class activity) { - pushCallbackActivityName = activity.getName(); - ApptentiveLog.d("Setting push callback activity name to %s", pushCallbackActivityName); - } - - public String getPushCallbackActivityName() { - return pushCallbackActivityName; - } - /** * The key that is used to store extra data on an Apptentive push notification. */ @@ -851,6 +846,9 @@ public void showAboutInternal(Context context, boolean showBrandingBand) { context.startActivity(intent); } + /** + * TODO: Decouple this from Conversation and Message Manager so it can be unit tested. + */ static PendingIntent generatePendingIntentFromApptentivePushData(String apptentivePushData) { ApptentiveLog.d("Generating Apptentive push PendingIntent."); if (!TextUtils.isEmpty(apptentivePushData)) { @@ -1092,6 +1090,9 @@ public void onReceiveNotification(ApptentiveNotification notification) { String conversationIdOfFailedRequest = notification.getUserInfo(NOTIFICATION_KEY_CONVERSATION_ID, String.class); Apptentive.AuthenticationFailedReason authenticationFailedReason = notification.getUserInfo(NOTIFICATION_KEY_AUTHENTICATION_FAILED_REASON, Apptentive.AuthenticationFailedReason.class); notifyAuthenticationFailedListener(authenticationFailedReason, conversationIdOfFailedRequest); + } else if (notification.hasName(NOTIFICATION_INTERACTION_MANIFEST_FETCHED)) { + String manifest = notification.getRequiredUserInfo(NOTIFICATION_KEY_MANIFEST, String.class); + storeManifestResponse(appContext, manifest); } } @@ -1104,4 +1105,17 @@ private boolean engageInternal(Context context, String eventName) { } //endregion + + //region Engagement Manifest Data + + private void storeManifestResponse(Context context, String manifest) { + try { + File file = new File(context.getCacheDir(), Constants.FILE_APPTENTIVE_ENGAGEMENT_MANIFEST); + Util.writeText(file, manifest); + } catch (Exception e) { + ApptentiveLog.e(e, "Exception while trying to save engagement manifest data"); + } + } + + //endregion } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLog.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLog.java index 76ad854e0..a877e0628 100755 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLog.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLog.java @@ -16,6 +16,10 @@ public class ApptentiveLog { private static Level logLevel = Level.DEFAULT; + public static Level getLogLevel() { + return logLevel; + } + public static void overrideLogLevel(Level level) { ApptentiveLog.logLevel = level; } @@ -51,12 +55,16 @@ private static void doLog(Level level, ApptentiveLogTag tag, Throwable throwable message = extra + " " + message; } + + //noinspection WrongConstant android.util.Log.println(level.getAndroidLevel(), TAG, message); if(throwable != null){ if(throwable.getMessage() != null){ + //noinspection WrongConstant android.util.Log.println(level.getAndroidLevel(), TAG, throwable.getMessage()); } while(throwable != null) { + //noinspection WrongConstant android.util.Log.println(level.getAndroidLevel(), TAG, android.util.Log.getStackTraceString(throwable)); throwable = throwable.getCause(); } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLogTag.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLogTag.java index 69a54a7fa..29f6d06a8 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLogTag.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveLogTag.java @@ -2,6 +2,7 @@ public enum ApptentiveLogTag { NETWORK(true), + APP_CONFIGURATION(true), CONVERSATION(true), NOTIFICATIONS(true), MESSAGES(true), diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNotifications.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNotifications.java index 8a5e315df..805ba94b7 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNotifications.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveNotifications.java @@ -63,6 +63,21 @@ public class ApptentiveNotifications { */ public static final String NOTIFICATION_INTERACTIONS_FETCHED = "NOTIFICATION_INTERACTIONS_FETCHED"; + /** + * Sent when interaction manifest data is fetched for any conversation. Used by the log monitor. + */ + public static final String NOTIFICATION_INTERACTION_MANIFEST_FETCHED = "INTERACTION_MANIFEST_FETCHED"; // { manifest: String } + + /** + * Sent when log monitor starts capturing and storing logs. + */ + public static final String NOTIFICATION_LOG_MONITOR_STARTED = "NOTIFICATION_LOG_MONITOR_STARTED"; + + /** + * Sent when log monitor stops capturing and storing logs. + */ + public static final String NOTIFICATION_LOG_MONITOR_STOPPED = "NOTIFICATION_LOG_MONITOR_STOPPED"; + // keys public static final String NOTIFICATION_KEY_SUCCESSFUL = "successful"; public static final String NOTIFICATION_KEY_ACTIVITY = "activity"; @@ -72,4 +87,5 @@ public class ApptentiveNotifications { public static final String NOTIFICATION_KEY_PAYLOAD = "payload"; public static final String NOTIFICATION_KEY_RESPONSE_CODE = "responseCode"; public static final String NOTIFICATION_KEY_RESPONSE_DATA = "responseData"; + public static final String NOTIFICATION_KEY_MANIFEST = "manifest"; } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java index 57404af4d..18f1c8d59 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java @@ -23,6 +23,7 @@ import android.support.v4.content.res.ResourcesCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatDelegate; import android.support.v7.widget.Toolbar; import android.view.MenuItem; import android.view.View; @@ -38,6 +39,7 @@ import com.apptentive.android.sdk.module.metric.MetricModule; import com.apptentive.android.sdk.notifications.ApptentiveNotification; import com.apptentive.android.sdk.util.Constants; +import com.apptentive.android.sdk.util.StringUtils; import com.apptentive.android.sdk.util.Util; import static com.apptentive.android.sdk.ApptentiveNotifications.*; @@ -146,6 +148,8 @@ protected void onCreate(Bundle savedInstanceState) { * need to apply the same color in toolbar theme * By default colorControlNormal has same value as textColorPrimary defined in toolbar theme overlay */ + // Allows loading of vector drawable resources from XML + AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); final Drawable alternateUpArrow = ResourcesCompat.getDrawable(getResources(), navIconResId, getTheme()); @@ -154,6 +158,11 @@ protected void onCreate(Bundle savedInstanceState) { alternateUpArrow.setColorFilter(colorControlNormal, PorterDuff.Mode.SRC_ATOP); actionBar.setHomeAsUpIndicator(alternateUpArrow); } + + String contentDescription = newFragment.getToolbarNavigationContentDescription(); + if (!StringUtils.isNullOrEmpty(contentDescription)) { + actionBar.setHomeActionContentDescription(contentDescription); + } } //current_tab = extra.getInt(SELECTED_TAB_EXTRA_KEY, 0); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/comm/ApptentiveHttpClient.java b/apptentive/src/main/java/com/apptentive/android/sdk/comm/ApptentiveHttpClient.java index fe30a945c..b9b38718d 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/comm/ApptentiveHttpClient.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/comm/ApptentiveHttpClient.java @@ -33,13 +33,14 @@ */ public class ApptentiveHttpClient implements PayloadRequestSender { - private static final String USER_AGENT_STRING = "Apptentive/%s (Android)"; // Format with SDK version string. + public static final String USER_AGENT_STRING = "Apptentive/%s (Android)"; // Format with SDK version string. - private static final int DEFAULT_HTTP_CONNECT_TIMEOUT = 45000; - private static final int DEFAULT_HTTP_SOCKET_TIMEOUT = 45000; + public static final int DEFAULT_HTTP_CONNECT_TIMEOUT = 45000; + public static final int DEFAULT_HTTP_SOCKET_TIMEOUT = 45000; // Active API private static final String ENDPOINT_CONVERSATION = "/conversation"; + private static final String ENDPOINT_CONFIGURATION = "/conversations/%s/configuration"; private static final String ENDPOINT_LEGACY_CONVERSATION = "/conversation/token"; private static final String ENDPOINT_LOG_IN_TO_EXISTING_CONVERSATION = "/conversations/%s/session"; private static final String ENDPOINT_LOG_IN_TO_NEW_CONVERSATION = "/conversations"; @@ -112,6 +113,22 @@ public HttpJsonRequest createLoginRequest(String conversationId, String token, H return request; } + public HttpJsonRequest createAppConfigurationRequest(String conversationId, String token, HttpRequest.Listener listener) { + if (StringUtils.isNullOrEmpty(conversationId)) { + throw new IllegalArgumentException("Conversation id is null or empty"); + } + + if (StringUtils.isNullOrEmpty(token)) { + throw new IllegalArgumentException("Conversation token is null or empty"); + } + + String endPoint = StringUtils.format(ENDPOINT_CONFIGURATION, conversationId); + HttpJsonRequest request = createJsonRequest(endPoint, new JSONObject(), HttpRequestMethod.GET); + request.setRequestProperty("Authorization", "Bearer " + token); + request.addListener(listener); + return request; + } + public HttpJsonRequest createFirstLoginRequest(String token, AppRelease appRelease, Sdk sdk, Device device, HttpRequest.Listener listener) { if (token == null) { throw new IllegalArgumentException("Token is null"); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java b/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java index 3cfa7deee..718870ab0 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/conversation/Conversation.java @@ -12,6 +12,7 @@ import com.apptentive.android.sdk.Apptentive; import com.apptentive.android.sdk.ApptentiveInternal; import com.apptentive.android.sdk.ApptentiveLog; +import com.apptentive.android.sdk.ApptentiveNotifications; import com.apptentive.android.sdk.comm.ApptentiveClient; import com.apptentive.android.sdk.comm.ApptentiveHttpResponse; import com.apptentive.android.sdk.debug.Assert; @@ -23,6 +24,7 @@ import com.apptentive.android.sdk.module.engagement.interaction.model.Interactions; import com.apptentive.android.sdk.module.engagement.interaction.model.Targets; import com.apptentive.android.sdk.module.messagecenter.MessageManager; +import com.apptentive.android.sdk.notifications.ApptentiveNotificationCenter; import com.apptentive.android.sdk.storage.AppRelease; import com.apptentive.android.sdk.storage.DataChangedListener; import com.apptentive.android.sdk.storage.Device; @@ -49,6 +51,7 @@ import java.io.File; +import static com.apptentive.android.sdk.ApptentiveNotifications.*; import static com.apptentive.android.sdk.debug.Assert.assertFail; import static com.apptentive.android.sdk.debug.Assert.assertNotNull; import static com.apptentive.android.sdk.debug.Assert.notNull; @@ -223,6 +226,10 @@ else if (!response.isSuccessful()) { if (updateSuccessful) { String interactionsPayloadString = response.getContent(); + // Send a notification so other parts of the SDK can use this data for troubleshooting + ApptentiveNotificationCenter.defaultCenter() + .postNotification(NOTIFICATION_INTERACTION_MANIFEST_FETCHED, NOTIFICATION_KEY_MANIFEST, interactionsPayloadString); + // Store new integration cache expiration. String cacheControl = response.getHeaders().get("Cache-Control"); Integer cacheSeconds = Util.parseCacheControlHeader(cacheControl); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/conversation/ConversationManager.java b/apptentive/src/main/java/com/apptentive/android/sdk/conversation/ConversationManager.java index 1e68d09e3..8da9dcf29 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/conversation/ConversationManager.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/conversation/ConversationManager.java @@ -16,6 +16,7 @@ import com.apptentive.android.sdk.comm.ApptentiveHttpClient; import com.apptentive.android.sdk.conversation.ConversationMetadata.Filter; import com.apptentive.android.sdk.migration.Migrator; +import com.apptentive.android.sdk.model.Configuration; import com.apptentive.android.sdk.model.ConversationItem; import com.apptentive.android.sdk.model.ConversationTokenRequest; import com.apptentive.android.sdk.module.engagement.EngagementModule; @@ -35,6 +36,7 @@ import com.apptentive.android.sdk.util.Constants; import com.apptentive.android.sdk.util.Jwt; import com.apptentive.android.sdk.util.ObjectUtils; +import com.apptentive.android.sdk.util.RuntimeUtils; import com.apptentive.android.sdk.util.StringUtils; import com.apptentive.android.sdk.util.Util; import com.apptentive.android.sdk.util.threading.DispatchQueue; @@ -46,6 +48,7 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.util.List; +import java.util.Map; import static com.apptentive.android.sdk.ApptentiveLog.Level.VERY_VERBOSE; import static com.apptentive.android.sdk.ApptentiveLogTag.*; @@ -67,7 +70,9 @@ public class ConversationManager { protected static final String CONVERSATION_METADATA_PATH = "conversation-v1.meta"; + private static final String TAG_FETCH_CONVERSATION_TOKEN_REQUEST = "fetch_conversation_token"; + private static final String TAG_FETCH_APP_CONFIGURATION_REQUEST = "fetch_app_configuration"; private final WeakReference contextRef; @@ -97,12 +102,13 @@ public ConversationManager(Context context, File apptentiveConversationsStorageD public void onReceiveNotification(ApptentiveNotification notification) { assertMainThread(); if (activeConversation != null && activeConversation.hasActiveState()) { - ApptentiveLog.v(CONVERSATION, "App entered foreground notification received. Trying to fetch interactions..."); + ApptentiveLog.v(CONVERSATION, "App entered foreground notification received. Trying to fetch app configuration and interactions..."); final Context context = getContext(); if (context != null) { + fetchAppConfiguration(activeConversation); activeConversation.fetchInteractions(context); } else { - ApptentiveLog.w(CONVERSATION, "Can't fetch conversation interactions: context is lost"); + ApptentiveLog.w(CONVERSATION, "Can't fetch app configuration and conversation interactions: context is lost"); } } } @@ -360,7 +366,7 @@ private HttpRequest fetchConversationToken(final Conversation conversation) { // Send the Device and Sdk now, so they are available on the server from the start. final Device device = DeviceManager.generateNewDevice(context); - final Sdk sdk = SdkManager.generateCurrentSdk(); + final Sdk sdk = SdkManager.generateCurrentSdk(context); final AppRelease appRelease = ApptentiveInternal.getInstance().getAppRelease(); conversationTokenRequest.setDevice(DeviceManager.getDiffPayload(null, device)); @@ -453,6 +459,9 @@ private void handleConversationStateChange(Conversation conversation) { conversation.fetchInteractions(getContext()); conversation.getMessageManager().startPollingMessages(); + // Fetch app configuration + fetchAppConfiguration(conversation); + // Update conversation with push configuration changes that happened while it wasn't active. SharedPreferences prefs = ApptentiveInternal.getInstance().getGlobalSharedPrefs(); int pushProvider = prefs.getInt(Constants.PREF_KEY_PUSH_PROVIDER, -1); @@ -469,6 +478,65 @@ private void handleConversationStateChange(Conversation conversation) { } } + private void fetchAppConfiguration(Conversation conversation) { + try { + fetchAppConfigurationGuarded(conversation); + } catch (Exception e) { + ApptentiveLog.e(e, "Exception while fetching app configuration"); + } + } + + private void fetchAppConfigurationGuarded(Conversation conversation) { + ApptentiveLog.d(APP_CONFIGURATION, "Fetching app configuration..."); + + HttpRequest existingRequest = getHttpClient().findRequest(TAG_FETCH_APP_CONFIGURATION_REQUEST); + if (existingRequest != null) { + ApptentiveLog.d(APP_CONFIGURATION, "Can't fetch app configuration: another request already pending"); + return; + } + + if (!Configuration.load().hasConfigurationCacheExpired()) { + // if configuration hasn't expired we would fetch it anyway for debug apps + boolean debuggable = RuntimeUtils.isAppDebuggable(getContext()); + if (!debuggable) { + ApptentiveLog.d(APP_CONFIGURATION, "Can't fetch app configuration: the old configuration is still valid"); + return; + } + } + + HttpJsonRequest request = getHttpClient() + .createAppConfigurationRequest(conversation.getConversationId(), conversation.getConversationToken(), + new HttpRequest.Listener() { + @Override + public void onFinish(HttpJsonRequest request) { + try { + String cacheControl = request.getResponseHeader("Cache-Control"); + Integer cacheSeconds = Util.parseCacheControlHeader(cacheControl); + if (cacheSeconds == null) { + cacheSeconds = Constants.CONFIG_DEFAULT_APP_CONFIG_EXPIRATION_DURATION_SECONDS; + } + ApptentiveLog.d(APP_CONFIGURATION, "Caching configuration for %d seconds.", cacheSeconds); + Configuration config = new Configuration(request.getResponseObject().toString()); + config.setConfigurationCacheExpirationMillis(System.currentTimeMillis() + cacheSeconds * 1000); + config.save(); + } catch (Exception e) { + ApptentiveLog.e(e, "Exception while parsing app configuration response"); + } + } + + @Override + public void onCancel(HttpJsonRequest request) { + } + + @Override + public void onFail(HttpJsonRequest request, String reason) { + ApptentiveLog.e(APP_CONFIGURATION, "App configuration request failed: %s", reason); + } + }); + request.setTag(TAG_FETCH_APP_CONFIGURATION_REQUEST); + request.start(); + } + private void updateMetadataItems(Conversation conversation) { ApptentiveLog.vv("Updating metadata: state=%s localId=%s conversationId=%s token=%s", conversation.getState(), @@ -743,7 +811,7 @@ public boolean accept(ConversationMetadataItem item) { // TODO: if we don't set these here - device payload would return 4xx error code activeConversation.setDevice(DeviceManager.generateNewDevice(getContext())); activeConversation.setAppRelease(ApptentiveInternal.getInstance().getAppRelease()); - activeConversation.setSdk(SdkManager.generateCurrentSdk()); + activeConversation.setSdk(SdkManager.generateCurrentSdk(getContext())); } } @@ -776,7 +844,7 @@ private void handleLoginFailed(String reason) { private void sendFirstLoginRequest(final String userId, final String token, final LoginCallback callback) { final AppRelease appRelease = ApptentiveInternal.getInstance().getAppRelease(); - final Sdk sdk = SdkManager.generateCurrentSdk(); + final Sdk sdk = SdkManager.generateCurrentSdk(getContext()); final Device device = DeviceManager.generateNewDevice(getContext()); HttpJsonRequest request = getHttpClient().createFirstLoginRequest(token, appRelease, sdk, device, new HttpRequest.Listener() { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/debug/AttachmentFileProvider.java b/apptentive/src/main/java/com/apptentive/android/sdk/debug/AttachmentFileProvider.java new file mode 100644 index 000000000..80d1287ce --- /dev/null +++ b/apptentive/src/main/java/com/apptentive/android/sdk/debug/AttachmentFileProvider.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. + * Please refer to the LICENSE file for the terms and conditions + * under which redistribution and use of this file is permitted. + */ + +package com.apptentive.android.sdk.debug; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.UriMatcher; +import android.database.Cursor; +import android.net.Uri; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import java.io.File; +import java.io.FileNotFoundException; + +public class AttachmentFileProvider extends ContentProvider { + + private static final String CLASS_NAME = AttachmentFileProvider.class.getSimpleName(); + + // The authority is the symbolic name for the provider class + public static final String AUTHORITY = AttachmentFileProvider.class.getName(); + + // UriMatcher used to match against incoming requests + private UriMatcher uriMatcher; + + @Override + public boolean onCreate() { + uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + + // Add a URI to the matcher which will match against the form + // 'content://it.my.app.AttachmentFileProvider/*' + // and return 1 in the case that the incoming Uri matches this pattern + uriMatcher.addURI(AUTHORITY, "*", 1); + + return true; + } + + @Override + public ParcelFileDescriptor openFile(Uri uri, String mode) + throws FileNotFoundException { + + String LOG_TAG = CLASS_NAME + " - openFile"; + + Log.v(LOG_TAG, + "Called with uri: '" + uri + "'." + uri.getLastPathSegment()); + + // Check incoming Uri against the matcher + switch (uriMatcher.match(uri)) { + + // If it returns 1 - then it matches the Uri defined in onCreate + case 1: + + // The desired file name is specified by the last segment of the + // path + // E.g. + // 'content://com.apptentive.android.sdk.debug.AttachmentFileProvider/log.txt' + // Take this and build the path to the file + String fileLocation = getContext().getCacheDir() + File.separator + + uri.getLastPathSegment(); + + // Create & return a ParcelFileDescriptor pointing to the file + // Note: I don't care what mode they ask for - they're only getting + // read only + ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File( + fileLocation), ParcelFileDescriptor.MODE_READ_ONLY); + return pfd; + + // Otherwise unrecognised Uri + default: + Log.v(LOG_TAG, "Unsupported uri: '" + uri + "'."); + throw new FileNotFoundException("Unsupported uri: " + + uri.toString()); + } + } + + // ////////////////////////////////////////////////////////////// + // Not supported / used / required for this example + // ////////////////////////////////////////////////////////////// + + @Override + public int update(Uri uri, ContentValues contentvalues, String s, + String[] as) { + return 0; + } + + @Override + public int delete(Uri uri, String s, String[] as) { + return 0; + } + + @Override + public Uri insert(Uri uri, ContentValues contentvalues) { + return null; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Cursor query(Uri uri, String[] projection, String s, String[] as1, + String s1) { + return null; + } +} \ No newline at end of file diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogBroadcastReceiver.java b/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogBroadcastReceiver.java new file mode 100644 index 000000000..02c2ac228 --- /dev/null +++ b/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogBroadcastReceiver.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. + * Please refer to the LICENSE file for the terms and conditions + * under which redistribution and use of this file is permitted. + */ + +package com.apptentive.android.sdk.debug; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.v4.app.NotificationManagerCompat; + +import com.apptentive.android.sdk.ApptentiveLog; + +import java.io.File; +import java.util.ArrayList; + +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.ACTION_ABORT; +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.ACTION_SEND_LOGS; +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.EXTRA_EMAIL_RECIPIENTS; +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.EXTRA_INFO; +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.EXTRA_LOG_FILE; +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.EXTRA_MANIFEST_FILE; +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.EXTRA_SUBJECT; +import static com.apptentive.android.sdk.debug.TroubleshootingNotification.NOTIFICATION_ID_KEY; + +public class LogBroadcastReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + + // Get the notification + final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + final int notificationId = intent.getIntExtra(NOTIFICATION_ID_KEY, 0); + + // Dismiss the notification + notificationManager.cancel(notificationId); + + // Close the notification drawer + Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + context.sendBroadcast(it); + + // TODO: The app can be killed and this should still work. But it will be null if the app is killed when a user interacts with the notification. + LogMonitor instance = LogMonitor.sharedInstance(); + if (instance == null) { + ApptentiveLog.e("LogMonitor was null"); + return; + } + + // stop collection logs and close the file + instance.stopWritingLogs(); + + + // handle action + String action = intent.getAction(); + if (ACTION_SEND_LOGS.equals(action)) { + ApptentiveLog.i("Send Report: User is sending Log Monitor email."); + Intent email = new Intent(Intent.ACTION_SEND_MULTIPLE); + email.setType("text/plain"); + email.putExtra(Intent.EXTRA_EMAIL, intent.getStringArrayExtra(EXTRA_EMAIL_RECIPIENTS)); + email.putExtra(Intent.EXTRA_SUBJECT, intent.getStringExtra(EXTRA_SUBJECT)); + email.putExtra(Intent.EXTRA_TEXT, intent.getStringExtra(EXTRA_INFO)); + + File logFile = (File) intent.getExtras().get(EXTRA_LOG_FILE); + File manifestFile = (File) intent.getExtras().get(EXTRA_MANIFEST_FILE); + + ArrayList attachments = new ArrayList<>(); + if (logFile != null && logFile.exists()) { + attachments.add(Uri.parse("content://" + AttachmentFileProvider.AUTHORITY + "/" + logFile.getName())); + } + if (manifestFile != null && manifestFile.exists()) { + attachments.add(Uri.parse("content://" + AttachmentFileProvider.AUTHORITY + "/" + manifestFile.getName())); + } + email.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments); + + Intent chooser = Intent.createChooser(email, "Choose an Email client:"); + chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + + context.startActivity(chooser); + } else if (ACTION_ABORT.equals(action)) { + ApptentiveLog.i("Discard: User exited log monitoring."); + } else { + ApptentiveLog.e("Unexpected action: %s", action); + } + + instance.destroy(); + } +} diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogMonitor.java b/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogMonitor.java new file mode 100644 index 000000000..c2a6d554a --- /dev/null +++ b/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogMonitor.java @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. + * Please refer to the LICENSE file for the terms and conditions + * under which redistribution and use of this file is permitted. + */ + +package com.apptentive.android.sdk.debug; + +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.util.Log; + +import com.apptentive.android.sdk.ApptentiveLog; +import com.apptentive.android.sdk.comm.ApptentiveHttpClient; +import com.apptentive.android.sdk.notifications.ApptentiveNotificationCenter; +import com.apptentive.android.sdk.util.Constants; +import com.apptentive.android.sdk.util.Destroyable; +import com.apptentive.android.sdk.util.Jwt; +import com.apptentive.android.sdk.util.StringUtils; +import com.apptentive.android.sdk.util.Util; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.lang.ref.WeakReference; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_LOG_MONITOR_STARTED; +import static com.apptentive.android.sdk.ApptentiveNotifications.NOTIFICATION_LOG_MONITOR_STOPPED; +import static com.apptentive.android.sdk.comm.ApptentiveHttpClient.USER_AGENT_STRING; + +public class LogMonitor implements Destroyable { + + // TODO: Replace with a better unique number + public static final int NOTIFICATION_ID = 1; + + private static final String TAG = "LogMonitor"; + + private static final String PREFS_NAME = "com.apptentive.debug"; + private static final String PREFS_KEY_EMAIL_RECIPIENTS = "com.apptentive.debug.EmailRecipients"; + private static final String PREFS_KEY_LOG_LEVEL = "com.apptentive.debug.LogLevel"; + private static final String PREFS_KEY_FILTER_PID = "com.apptentive.debug.FilterPID"; + + private static final String DEBUG_TEXT_HEADER = "com.apptentive.debug:"; + + private static LogMonitor instance; + + private final WeakReference contextRef; + private final ApptentiveLog.Level logLevel; + private final String[] emailRecipients; + + private final LogWriter logWriter; + + private ApptentiveLog.Level oldLogLevel; + + private LogMonitor(Context context, Configuration configuration) { + if (context == null) { + throw new IllegalArgumentException("Context is null"); + } + if (configuration == null) { + throw new IllegalArgumentException("Configuration is null"); + } + + this.contextRef = new WeakReference<>(context); + this.logLevel = configuration.logLevel; + this.emailRecipients = configuration.emailRecipients; + this.logWriter = new LogWriter(getLogFile(context), configuration.restored, configuration.filterByPID); + } + + //region Initialization + + /** + * Attempts to initialize an instance. Returns true if succeed. + */ + public static boolean tryInitialize(Context context, String apptentiveApiKey, String apptentiveApiSignature) { + if (instance != null) { + ApptentiveLog.i("Log Monitor already initialized"); + return false; + } + + try { + Configuration configuration = readConfigurationFromPersistentStorage(context); + if (configuration != null) { + ApptentiveLog.i("Read log monitor configuration from persistent storage: " + configuration); + } else { + String accessToken = readAccessTokenFromClipboard(context); + + // No access token was supplied + if (accessToken == null) { + return false; + } + + // The access token was invalid, or expired, or the server could be reached to verify it + if (!syncVerifyAccessToken(apptentiveApiKey, apptentiveApiSignature, accessToken)) { + ApptentiveLog.i("Can't start log monitor: access token verification failed"); + return false; + } + + configuration = readConfigurationFromToken(accessToken); + if (configuration != null) { + ApptentiveLog.i("Read log monitor configuration from clipboard: " + configuration); + Util.setClipboardText(context, ""); // clear the clipboard contents after the data is parsed + + // store the configuration to make sure we can resume the current session + saveConfigurationFromPersistentStorage(context, configuration); + } + } + + if (configuration != null) { + ApptentiveLog.i("Entering Apptentive Troubleshooting mode."); + instance = new LogMonitor(context, configuration); + instance.start(context); + return true; + } + + } catch (Exception e) { + ApptentiveLog.i("Exception while initializing Apptentive Log Monitor", e); + } + + return false; + } + + private static Configuration readConfigurationFromToken(String accessToken) { + try { + final Jwt jwt = Jwt.decode(accessToken); + JSONObject payload = jwt.getPayload(); + + Configuration config = new Configuration(); + + // log level + String logLevelStr = payload.optString("level"); + if (!StringUtils.isNullOrEmpty(logLevelStr)) { + config.logLevel = ApptentiveLog.Level.parse(logLevelStr); + } + + // recipients + JSONArray recipientsJson = payload.optJSONArray("recipients"); + if (recipientsJson != null) { + String[] recipients = new String[recipientsJson.length()]; + for (int i = 0; i < recipientsJson.length(); ++i) { + recipients[i] = recipientsJson.optString(i); + } + + config.emailRecipients = recipients; + } + + // should we filter by PID + config.filterByPID = payload.optBoolean("filter_app_process", config.filterByPID); + + return config; + } catch (Exception e) { + ApptentiveLog.e(e, "Exception while parsing access token: '%s'", accessToken); + return null; + } + } + + /** + * Attempts to read a log monitor configuration stored in the last session. Returns null if failed + */ + private static Configuration readConfigurationFromPersistentStorage(Context context) { + if (context == null) { + throw new IllegalArgumentException("Context is null"); + } + SharedPreferences prefs = getPrefs(context); + if (!prefs.contains(PREFS_KEY_EMAIL_RECIPIENTS)) { + return null; + } + + Configuration configuration = new Configuration(); + configuration.restored = true; + + String emailRecipients = prefs.getString(PREFS_KEY_EMAIL_RECIPIENTS, null); + if (!StringUtils.isNullOrEmpty(emailRecipients)) { + configuration.emailRecipients = emailRecipients.split(","); + } + + String logLevel = prefs.getString(PREFS_KEY_LOG_LEVEL, null); + if (!StringUtils.isNullOrEmpty(logLevel)) { + configuration.logLevel = ApptentiveLog.Level.parse(logLevel); + } + + configuration.filterByPID = prefs.getBoolean(PREFS_KEY_FILTER_PID, configuration.filterByPID); + + return configuration; + } + + /** Saves the configuration into SharedPreferences */ + private static void saveConfigurationFromPersistentStorage(Context context, Configuration configuration) { + SharedPreferences prefs = getPrefs(context); + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(PREFS_KEY_EMAIL_RECIPIENTS, StringUtils.join(configuration.emailRecipients)); + editor.putString(PREFS_KEY_LOG_LEVEL, configuration.logLevel.toString()); + editor.putBoolean(PREFS_KEY_FILTER_PID, configuration.filterByPID); + editor.apply(); + } + + private static void deleteConfigurationFromPersistentStorage(Context context) { + SharedPreferences.Editor editor = getPrefs(context).edit(); + editor.remove(PREFS_KEY_EMAIL_RECIPIENTS); + editor.remove(PREFS_KEY_LOG_LEVEL); + editor.remove(PREFS_KEY_FILTER_PID); + editor.apply(); + } + + //endregion + + //region Access Token + + /** + * Attempts to read access token from the clipboard + */ + private static String readAccessTokenFromClipboard(Context context) { + String text = Util.getClipboardText(context); + + if (StringUtils.isNullOrEmpty(text)) { + return null; + } + + //Since the token string should never contain spaces, attempt to repair line breaks introduced in the copying process. + text = text.replaceAll("\\s+", ""); + + if (!text.startsWith(DEBUG_TEXT_HEADER)) { + return null; + } + + // Remove the header + text = text.substring(DEBUG_TEXT_HEADER.length()); + return text; + } + + /** + * Send a sync URL request to the backend to verify the access token. This method would block + */ + private static boolean syncVerifyAccessToken(String apptentiveApiKey, String apptentiveApiSignature, String accessToken) { + return verifyToken(apptentiveApiKey, apptentiveApiSignature, accessToken); + } + + //endregion + + //region Lifecycle + + private void start(Context context) { + Log.i(TAG, "Overriding log level: " + logLevel); + oldLogLevel = ApptentiveLog.getLogLevel(); + ApptentiveLog.overrideLogLevel(logLevel); + + showDebugNotification(context); + + logWriter.start(); + + // post a notification + ApptentiveNotificationCenter.defaultCenter() + .postNotification(NOTIFICATION_LOG_MONITOR_STARTED); + } + + public void stopWritingLogs() { + try { + logWriter.stopAndWait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + // post a notification + ApptentiveNotificationCenter.defaultCenter() + .postNotification(NOTIFICATION_LOG_MONITOR_STOPPED); + } + + private void showDebugNotification(Context context) { + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + Notification notification = new TroubleshootingNotification().buildNotification(context, getSubject(context), getSystemInfo(context), getLogFile(context), getManifestFile(context), emailRecipients); + notificationManager.notify(NOTIFICATION_ID, notification); + } + + private String getSubject(Context context) { + String subject = String.format("%s (Android)", context.getPackageName()); + try { + ApplicationInfo ai = context.getApplicationInfo(); + subject = String.format("%s (Android)", ai.loadLabel(context.getPackageManager()).toString()); + } catch (Exception e) { + ApptentiveLog.e(e, "Unable to load troubleshooting email status line"); + } + return subject; + } + + private String getSystemInfo(Context context) { + String versionName = ""; + int versionCode = -1; + try { + PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + // TODO: list activities, permissions, etc + versionName = packageInfo.versionName; + versionCode = packageInfo.versionCode; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + + Object[] info = { + "App Package Name", context.getPackageName(), + "App Version Name", versionName, + "App Version Code", versionCode, + "Apptentive SDK", com.apptentive.android.sdk.util.Constants.APPTENTIVE_SDK_VERSION, + "Device Model", Build.MODEL, + "Android OS Version", Build.VERSION.RELEASE, + "Android OS API Level", Build.VERSION.SDK_INT, + "Locale", Locale.getDefault().getDisplayName() + }; + + StringBuilder result = new StringBuilder(); + result.append("This email may contain sensitive content. Please review before sending.\n\n"); + for (int i = 0; i < info.length; i += 2) { + if (result.length() > 0) { + result.append("\n"); + } + result.append(info[i]); + result.append(": "); + result.append(info[i + 1]); + } + return result.toString(); + } + + //endregion + + //region Destroyable + + @Override + public void destroy() { + // restoring old log level + if (oldLogLevel != null) { + ApptentiveLog.overrideLogLevel(oldLogLevel); + } + + Context context = getContext(); + if (context != null) { + // deleting saved session + deleteConfigurationFromPersistentStorage(context); + instance = null; + } else { + Log.e(TAG, "Unable to destroy session: context is lost"); + } + } + + //endregion + + //region Helpers + + private static SharedPreferences getPrefs(Context context) { + return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + } + + private static File getLogFile(Context context) { + return new File(context.getCacheDir(), Constants.FILE_APPTENTIVE_LOG_FILE); + } + + private static File getManifestFile(Context context) { + return new File(context.getCacheDir(), Constants.FILE_APPTENTIVE_ENGAGEMENT_MANIFEST); + } + + //endregion + + //region Getters/Setters + + public static LogMonitor sharedInstance() { + return instance; + } + + private Context getContext() { + return contextRef.get(); + } + + //endregion + + //region Configuration + + private static class Configuration { + /** Email recipients for the log email */ + String[] emailRecipients = { "support@apptentive.com" }; + + /** New log level */ + ApptentiveLog.Level logLevel = ApptentiveLog.Level.VERY_VERBOSE; + + /** True if logcat output should be filtered by the process id */ + boolean filterByPID = true; + + /** True if configuration was restored from the persistent storage */ + boolean restored; + + @Override + public String toString() { + return String.format("logLevel=%s recipients=%s filterPID=%s restored=%s", + logLevel, Arrays.toString(emailRecipients), Boolean.toString(filterByPID), + Boolean.toString(restored)); + } + } + + //endregion + + //region Token Verification + + private static boolean verifyToken(String apptentiveAppKey, String apptentiveAppSignature, String token) { + + final Map headers = new HashMap<>(); + headers.put("X-API-Version", String.valueOf(Constants.API_VERSION)); + headers.put("APPTENTIVE-KEY", apptentiveAppKey); + headers.put("APPTENTIVE-SIGNATURE", apptentiveAppSignature); + headers.put("Content-Type", "application/json"); + headers.put("Accept", "application/json"); + headers.put("User-Agent", String.format(USER_AGENT_STRING, Constants.APPTENTIVE_SDK_VERSION)); + + JSONObject postBodyJson; + try { + postBodyJson = new JSONObject(); + postBodyJson.put("debug_token", token); + } catch (JSONException e) { + // Can't happen + throw new RuntimeException(e); + } + + String response = loadFromURL(Constants.CONFIG_DEFAULT_SERVER_URL + "/debug_token/verify", headers, postBodyJson.toString()); + if (!StringUtils.isNullOrEmpty(response)) { + try { + JSONObject debugTokenResponse = new JSONObject(response); + if (!debugTokenResponse.isNull("valid")) { + return debugTokenResponse.optBoolean("valid", false); + } + ApptentiveLog.e("Debug token response was missing \"valid\" field."); + } catch (Exception e) { + ApptentiveLog.e("Error parsing debug token validation response."); + return false; + } + return true; + } + return false; + } + + private static String loadFromURL(final String urlString, final Map headers, final String body) { + final StringBuilder responseString = new StringBuilder(); + Thread networkThread = new Thread(new Runnable() { + @Override + public void run() { + try { + loadFromURL(urlString, headers, responseString); + } catch (Exception e) { + ApptentiveLog.e("Error performing debug token validation request: %s", e.getMessage()); + } + } + + private void loadFromURL(String urlString, Map headers, StringBuilder responseString) throws IOException { + ApptentiveLog.i("Performing debug token verification request: \"%s\"", body); + URL url = new URL(urlString); + BufferedReader reader = null; + try { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setConnectTimeout(ApptentiveHttpClient.DEFAULT_HTTP_CONNECT_TIMEOUT); + connection.setReadTimeout(ApptentiveHttpClient.DEFAULT_HTTP_SOCKET_TIMEOUT); + + for (String key : headers.keySet()) { + connection.setRequestProperty(key, headers.get(key)); + } + + OutputStream outputStream = null; + try { + outputStream = connection.getOutputStream(); + outputStream.write(body.getBytes()); + } finally { + Util.ensureClosed(outputStream); + } + + int responseCode = connection.getResponseCode(); + ApptentiveLog.vv("Response code: %d", responseCode); + + InputStream is; + StringBuilder buffer; + boolean successful; + // If successful, read the message into the response String. If not, read it into a buffer and throw it in an exception. + if (responseCode >= HttpURLConnection.HTTP_OK && responseCode < HttpURLConnection.HTTP_MULT_CHOICE) { + successful = true; + is = connection.getInputStream(); + buffer = responseString; + } else { + successful = false; + is = connection.getErrorStream(); + buffer = new StringBuilder(); + } + + reader = new BufferedReader(new InputStreamReader(is)); + String line; + while ((line = reader.readLine()) != null) { + if (buffer.length() > 0) { + buffer.append('\n'); + } + buffer.append(line); + } + ApptentiveLog.v("Debug Token verification response: %s", buffer); + if (!successful) { + throw new IOException(buffer.toString()); + } + } finally { + Util.ensureClosed(reader); + } + } + }); + networkThread.start(); + try { + networkThread.join(); + } catch (InterruptedException e) { + ApptentiveLog.e("Debug token validation thread interrupted."); + return null; + } + return responseString.toString(); + } + + //endregion + +} diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogWriter.java b/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogWriter.java new file mode 100644 index 000000000..30ba77746 --- /dev/null +++ b/apptentive/src/main/java/com/apptentive/android/sdk/debug/LogWriter.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. + * Please refer to the LICENSE file for the terms and conditions + * under which redistribution and use of this file is permitted. + */ + +package com.apptentive.android.sdk.debug; + +import android.util.Log; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.InterruptedIOException; +import java.util.ArrayList; +import java.util.List; + +public class LogWriter { + private static final String TAG = LogWriter.class.getSimpleName(); + private final File file; + private final boolean append; + private final boolean filterByPID; + + private Thread thread; + private Process process; + + public LogWriter(File file, boolean append, boolean filterByPID) { + if (file == null) { + throw new IllegalArgumentException("File is null"); + } + this.file = file; + this.append = append; + this.filterByPID = filterByPID; + } + + //region Lifecycle + + public void start() { + if (thread != null) { + throw new IllegalStateException("Already started"); + } + + thread = new Thread(new Runnable() { + @Override + public void run() { + writeLogs(); + } + }, "Apptentive Logcat Writer"); + thread.start(); + } + + public void stopAndWait() throws InterruptedException { + if (thread != null) { + process.destroy(); + thread.interrupt(); + thread.join(); + thread = null; + } + } + + //endregion + + //region Logs + + private void writeLogs() { + try { + writeLogsGuarded(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void writeLogsGuarded() throws IOException { + BufferedReader reader = null; + FileWriter writer = null; + + try { + List cmd = new ArrayList<>(); + cmd.add("logcat"); + cmd.add("-v"); + cmd.add("tag"); + if (filterByPID && logcatCanFilterByProcess()) { + cmd.add("--pid=" + android.os.Process.myPid()); + } + + process = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()])); + reader = new BufferedReader(new InputStreamReader(process.getInputStream()), 8192); + writer = new FileWriter(file, append); + + String line; + while ((line = reader.readLine()) != null) { + writer.write(line); + writer.write('\n'); + } + } catch (InterruptedIOException e) { + Log.i(TAG, "Apptentive log writing interrupted"); + } finally { + if (reader != null) { + reader.close(); + } + + if (writer != null) { + writer.close(); + } + + if (process != null) { + process.destroy(); + } + } + } + + /** + * Returns true if --pid= option is supported + */ + private boolean logcatCanFilterByProcess() { + // This is a bit hacky but we run `logcat --help` and analyze the output to see if + // --pid= option is there + + try { + Process process = Runtime.getRuntime().exec(new String[]{"logcat", "--help"}); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()), 1024); + + String line; + while ((line = reader.readLine()) != null) { + if (line.contains("--pid=")) { + return true; + } + } + } catch (Exception e) { + Log.e(TAG, "Exception while trying to figure out if logcat can filter by process id"); + } + return false; + } + + //endregion +} diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/debug/TroubleshootingNotification.java b/apptentive/src/main/java/com/apptentive/android/sdk/debug/TroubleshootingNotification.java new file mode 100644 index 000000000..07495bf08 --- /dev/null +++ b/apptentive/src/main/java/com/apptentive/android/sdk/debug/TroubleshootingNotification.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. + * Please refer to the LICENSE file for the terms and conditions + * under which redistribution and use of this file is permitted. + */ + +package com.apptentive.android.sdk.debug; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.graphics.Color; +import android.os.Build; +import android.support.annotation.NonNull; +import android.support.v4.app.NotificationCompat; + +import com.apptentive.android.sdk.R; + +import java.io.File; + +import static android.content.Context.NOTIFICATION_SERVICE; + +public class TroubleshootingNotification { + + public static final String NOTIFICATION_CHANNEL_ID = "com.apptentive.debug.NOTIFICATION_CHANNEL_TROUBLESHOOTING"; + public static final String NOTIFICATION_CHANNEL_NAME = "Apptentive Notifications"; + public static final String NOTIFICATION_CHANNEL_DESCRIPTION = "Used for SDK troubleshooting"; + public static final String NOTIFICATION_ID_KEY = "com.apptentive.debug.NOTIFICATION_ID"; + public static final int APPTENTIVE_NOTIFICATION_ID = 1; + + public static final String ACTION_ABORT = "com.apptentive.debug.ACTION_ABORT"; + public static final String ACTION_SEND_LOGS = "com.apptentive.debug.ACTION_SEND_LOGS"; + + public static final String EXTRA_EMAIL_RECIPIENTS = "EMAIL_RECIPIENTS"; + public static final String EXTRA_SUBJECT = "SUBJECT"; + public static final String EXTRA_INFO = "INFO"; + public static final String EXTRA_LOG_FILE = "LOG_FILE"; + public static final String EXTRA_MANIFEST_FILE = "MANIFEST_FILE"; + + + public Notification buildNotification(@NonNull Context context, String subject, String systemInfo, File logFile, File manifestFile, String[] emailRecipients) { + + NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); + + // Set up PendingIntents for actions + Intent abortIntent = new Intent(context, LogBroadcastReceiver.class); + abortIntent.setAction(ACTION_ABORT); + abortIntent.putExtra(NOTIFICATION_ID_KEY, APPTENTIVE_NOTIFICATION_ID); + PendingIntent abortPendingIntent = PendingIntent.getBroadcast(context, 0, abortIntent, PendingIntent.FLAG_UPDATE_CURRENT); + NotificationCompat.Action abortAction = new NotificationCompat.Action.Builder(0, "Discard", abortPendingIntent).build(); + + Intent sendLogsIntent = new Intent(context, LogBroadcastReceiver.class); + sendLogsIntent.setAction(ACTION_SEND_LOGS); + sendLogsIntent.putExtra(NOTIFICATION_ID_KEY, APPTENTIVE_NOTIFICATION_ID); + sendLogsIntent.putExtra(EXTRA_EMAIL_RECIPIENTS, emailRecipients); + sendLogsIntent.putExtra(EXTRA_SUBJECT, subject); + sendLogsIntent.putExtra(EXTRA_INFO, systemInfo); + sendLogsIntent.putExtra(EXTRA_LOG_FILE, logFile); + sendLogsIntent.putExtra(EXTRA_MANIFEST_FILE, manifestFile); + + PendingIntent sendLogsPendingIntent = PendingIntent.getBroadcast(context, 0, sendLogsIntent, PendingIntent.FLAG_UPDATE_CURRENT); + NotificationCompat.Action sendLogsAction = new NotificationCompat.Action.Builder(0, "Send Report", sendLogsPendingIntent).build(); + + // Build notification + final NotificationCompat.Builder builder = + new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) + .setDefaults(Notification.DEFAULT_SOUND) + .setOnlyAlertOnce(true) + .setOngoing(true) + .setAutoCancel(false) + .setSmallIcon(R.drawable.apptentive_status_gear) + .setSubText("Apptentive SDK") + .setContentTitle("Troubleshooting Mode") + .setContentText("Reproduce your problem, then send report") + .addAction(abortAction) + .addAction(sendLogsAction) + .setWhen(System.currentTimeMillis()) + .setVibrate(new long[]{0, 100, 80, 240, 500, 100, 80, 240}) + .setLights(Color.RED, 200, 400); + + // Pre-Jelly Bean versions don't support Notification Actions. Just send logs when notification is tapped. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + builder.setContentIntent(sendLogsPendingIntent); + builder.setContentText("Tap to send logs"); + } + + // Tinting the notification icon added in Marshmallow + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + builder.setColor(context.getResources().getColor(R.color.apptentive_brand_red, (Resources.Theme) null)); + } + + // A Notification Channel is required starting in Oreo + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + notificationChannel.setDescription(NOTIFICATION_CHANNEL_DESCRIPTION); + // These are required in the channel in order to let notifications vibrate and use lights when targeting API 26+ + notificationChannel.enableLights(true); + notificationChannel.setLightColor(Color.RED); + notificationChannel.setVibrationPattern(new long[]{0, 100, 80, 240, 500, 100, 80, 240}); + + notificationManager.createNotificationChannel(notificationChannel); + } + + return builder.build(); + } +} diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStore.java b/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStore.java index 285940586..85bebd09e 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStore.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStore.java @@ -47,15 +47,17 @@ private static void ensureLoaded() { if (versionHistoryEntries == null) { versionHistoryEntries = new ArrayList(); SharedPreferences prefs = ApptentiveInternal.getInstance().getGlobalSharedPrefs(); - try { - String json = prefs.getString(Constants.PREF_KEY_VERSION_HISTORY_V2, "[]"); - JSONArray baseArray = new JSONArray(json); - for (int i = 0; i < baseArray.length(); i++) { - VersionHistoryEntry entry = new VersionHistoryEntry(baseArray.getJSONObject(i)); - versionHistoryEntries.add(entry); + if (prefs != null) { + try { + String json = prefs.getString(Constants.PREF_KEY_VERSION_HISTORY_V2, "[]"); + JSONArray baseArray = new JSONArray(json); + for (int i = 0; i < baseArray.length(); i++) { + VersionHistoryEntry entry = new VersionHistoryEntry(baseArray.getJSONObject(i)); + versionHistoryEntries.add(entry); + } + } catch (Exception e) { + ApptentiveLog.w(e, "Error loading VersionHistoryStore."); } - } catch (Exception e) { - ApptentiveLog.w(e, "Error loading VersionHistoryStore."); } } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStoreMigrator.java b/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStoreMigrator.java index 31320d004..9a9fe5d5b 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStoreMigrator.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/migration/v4_0_0/VersionHistoryStoreMigrator.java @@ -12,7 +12,7 @@ import com.apptentive.android.sdk.ApptentiveLog; import com.apptentive.android.sdk.util.Constants; -class VersionHistoryStoreMigrator { +public class VersionHistoryStoreMigrator { private static final String OLD_ENTRY_SEP = "__"; private static final String OLD_FIELD_SEP = "--"; @@ -22,7 +22,7 @@ class VersionHistoryStoreMigrator { private static boolean migrated_to_v2; - static void migrateV1ToV2(String oldFormat) { + public static void migrateV1ToV2(String oldFormat) { ApptentiveLog.i("Migrating VersionHistoryStore V1 to V2."); ApptentiveLog.i("V1: %s", oldFormat); try { @@ -53,15 +53,17 @@ private static void performMigrationIfNeededV1ToV2() { if (migrated_to_v2) { return; } - SharedPreferences prefs = ApptentiveInternal.getInstance().getGlobalSharedPrefs(); - if (prefs != null) { - migrated_to_v2 = prefs.getBoolean(Constants.PREF_KEY_VERSION_HISTORY_V2_MIGRATED, false); - if (migrated_to_v2) { - return; + if (ApptentiveInternal.getInstance() != null) { + SharedPreferences prefs = ApptentiveInternal.getInstance().getGlobalSharedPrefs(); + if (prefs != null) { + migrated_to_v2 = prefs.getBoolean(Constants.PREF_KEY_VERSION_HISTORY_V2_MIGRATED, false); + if (migrated_to_v2) { + return; + } + String versionHistoryStoreOldString = prefs.getString(Constants.PREF_KEY_VERSION_HISTORY, null); + VersionHistoryStoreMigrator.migrateV1ToV2(versionHistoryStoreOldString); + prefs.edit().putBoolean(Constants.PREF_KEY_VERSION_HISTORY_V2_MIGRATED, true).apply(); } - String versionHistoryStoreOldString = prefs.getString(Constants.PREF_KEY_VERSION_HISTORY, null); - VersionHistoryStoreMigrator.migrateV1ToV2(versionHistoryStoreOldString); - prefs.edit().putBoolean(Constants.PREF_KEY_VERSION_HISTORY_V2_MIGRATED, true).apply(); } } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/model/CommerceExtendedData.java b/apptentive/src/main/java/com/apptentive/android/sdk/model/CommerceExtendedData.java index c03db170b..df84a9288 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/model/CommerceExtendedData.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/model/CommerceExtendedData.java @@ -114,8 +114,7 @@ public CommerceExtendedData addItem(Item item) throws JSONException { public CommerceExtendedData setItems(JSONArray items) throws JSONException { if (items != null) { for (int i = 0; i < items.length(); i++) { - Item item = (Item) items.get(i); - addItem(item); + addItem(new Item((items.getJSONObject(i)).toString())); } } return this; diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/model/TimeExtendedData.java b/apptentive/src/main/java/com/apptentive/android/sdk/model/TimeExtendedData.java index bde0fecf8..84bb513a6 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/model/TimeExtendedData.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/model/TimeExtendedData.java @@ -32,6 +32,8 @@ public TimeExtendedData() { public TimeExtendedData(String json) throws JSONException { super(json); + JSONObject jsonObject = new JSONObject(json); + setTimestamp(jsonObject.optDouble(KEY_TIMESTAMP)); } public TimeExtendedData(Date date) { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java index 6c8aa1b54..b1fc46f02 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java @@ -373,6 +373,10 @@ public int getToolbarNavigationIconResourceId(Resources.Theme activityTheme) { return 0; } + public String getToolbarNavigationContentDescription() { + return null; + } + protected void attachFragmentMenuListeners(Menu menu) { } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/EnjoymentDialogFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/EnjoymentDialogFragment.java index 44ce2e375..0d905271f 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/EnjoymentDialogFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/EnjoymentDialogFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Apptentive, Inc. All Rights Reserved. + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. * Please refer to the LICENSE file for the terms and conditions * under which redistribution and use of this file is permitted. */ @@ -12,6 +12,7 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageButton; +import android.widget.LinearLayout; import android.widget.TextView; import com.apptentive.android.sdk.ApptentiveViewExitType; @@ -39,11 +40,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa String body = interaction.getTitle(); bodyView.setText(body); + int buttonsTotalLength = 0; // No String noText = interaction.getNoText(); Button noButton = (Button) v.findViewById(R.id.no); if (noText != null) { noButton.setText(noText); + buttonsTotalLength += noText.length(); } noButton.setOnClickListener(this); @@ -53,9 +56,19 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa yesButton.setActivated(true); if (yesText != null) { yesButton.setText(yesText); + buttonsTotalLength += yesText.length(); } yesButton.setOnClickListener(this); + // Change orientation of button area to vertical if buttons won't both fit on one line. + LinearLayout buttonContainer = (LinearLayout) v.findViewById(R.id.button_container); + boolean vertical = buttonsTotalLength > 16; + if (vertical) { + buttonContainer.setOrientation(LinearLayout.VERTICAL); + } else { + buttonContainer.setOrientation(LinearLayout.HORIZONTAL); + } + // Dismiss "X" Button boolean showDismissButton = interaction.showDismissButton(); String dismissText = interaction.getDismissText(); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterErrorFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterErrorFragment.java index 60f246793..e12b5b950 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterErrorFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterErrorFragment.java @@ -10,10 +10,10 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; +import android.support.v7.widget.AppCompatImageView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; import android.widget.TextView; import com.apptentive.android.sdk.Apptentive; @@ -88,14 +88,13 @@ public boolean onFragmentExit(ApptentiveViewExitType exitType) { } private void updateStatus() { - if (wasLastAttemptServerError(getContext()) || - Util.isNetworkConnectionPresent()) { + if (wasLastAttemptServerError(getContext()) || Util.isNetworkConnectionPresent()) { progress.setVisibility(View.VISIBLE); - ((ImageView) root.findViewById(R.id.icon)).setImageResource(R.drawable.apptentive_icon_server_error); + ((AppCompatImageView) root.findViewById(R.id.icon)).setImageResource(R.drawable.apptentive_ic_error); ((TextView) root.findViewById(R.id.message)).setText(R.string.apptentive_message_center_server_error); } else { progress.setVisibility(View.GONE); - ((ImageView) root.findViewById(R.id.icon)).setImageResource(R.drawable.apptentive_icon_no_connection); + ((AppCompatImageView) root.findViewById(R.id.icon)).setImageResource(R.drawable.apptentive_ic_no_connection); ((TextView) root.findViewById(R.id.message)).setText(R.string.apptentive_message_center_no_connection); } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java index c98d98aa4..230bc7fe6 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java @@ -1542,4 +1542,9 @@ public void setPaused(boolean paused) { public boolean isPaused() { return isPaused; } + + @Override + public String getToolbarNavigationContentDescription() { + return getContext().getString(R.string.apptentive_message_center_content_description_back_button); + } } \ No newline at end of file diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NoteFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NoteFragment.java index 876c2ca28..0852ee9c2 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NoteFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/NoteFragment.java @@ -26,6 +26,7 @@ import com.apptentive.android.sdk.module.engagement.interaction.model.common.Action; import com.apptentive.android.sdk.module.engagement.interaction.model.common.Actions; import com.apptentive.android.sdk.module.engagement.interaction.model.common.LaunchInteractionAction; +import com.apptentive.android.sdk.module.engagement.logic.FieldManager; import org.json.JSONException; import org.json.JSONObject; @@ -123,7 +124,8 @@ public void onClick(View view) { List invocations = launchInteractionButton.getInvocations(); String interactionIdToLaunch = null; for (Invocation invocation : invocations) { - if (invocation.isCriteriaMet()) { + FieldManager fieldManager = new FieldManager(getContext(), getConversation().getVersionHistory(), getConversation().getEventData(), getConversation().getPerson(), getConversation().getDevice(), getConversation().getAppRelease()); + if (invocation.isCriteriaMet(fieldManager)) { interactionIdToLaunch = invocation.getInteractionId(); break; } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/SurveyFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/SurveyFragment.java index 856de2f85..f9381814a 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/SurveyFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/SurveyFragment.java @@ -8,6 +8,7 @@ import android.app.Activity; import android.content.res.Resources; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; @@ -18,6 +19,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.accessibility.AccessibilityEvent; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; @@ -29,6 +31,7 @@ import com.apptentive.android.sdk.ApptentiveLog; import com.apptentive.android.sdk.ApptentiveViewExitType; import com.apptentive.android.sdk.R; +import com.apptentive.android.sdk.debug.Assert; import com.apptentive.android.sdk.model.SurveyResponsePayload; import com.apptentive.android.sdk.module.engagement.interaction.model.SurveyInteraction; import com.apptentive.android.sdk.module.engagement.interaction.model.survey.MultichoiceQuestion; @@ -44,6 +47,7 @@ import com.apptentive.android.sdk.module.engagement.interaction.view.survey.TextSurveyQuestionView; import com.apptentive.android.sdk.module.survey.OnSurveyFinishedListener; import com.apptentive.android.sdk.module.survey.OnSurveyQuestionAnsweredListener; +import com.apptentive.android.sdk.util.StringUtils; import com.apptentive.android.sdk.util.Util; import com.apptentive.android.sdk.view.ApptentiveNestedScrollView; @@ -80,7 +84,7 @@ public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bun getActivity().finish(); } - List questions = interaction.getQuestions(); + final List questions = interaction.getQuestions(); answers = new LinkedHashMap(questions.size()); View v = inflater.inflate(R.layout.apptentive_survey, container, false); @@ -134,6 +138,29 @@ public void onClick(View view) { ((TextView) toastView.findViewById(R.id.survey_invalid_toast_text)).setText(validationText); } toast.show(); + + // scroll to the first required un-answered question + final Fragment fragment = getFirstRequiredQuestionPos(); + Assert.assertNotNull(fragment, "Expected to have a scroll pos"); + if (fragment != null) { + scrollView.scrollToChild(fragment.getView()); + + if (fragment instanceof SurveyQuestionView) { + fragment.getView().requestFocus(); + + final String errorMessage = ((SurveyQuestionView) fragment).getErrorMessage(); + if (!StringUtils.isNullOrEmpty(errorMessage)) { + fragment.getView().postDelayed(new Runnable() { + @Override + public void run() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + fragment.getView().announceForAccessibility(errorMessage); + } + } + }, 1500); // give other accessibility events a change to propagate + } + } + } } } }); @@ -248,6 +275,17 @@ public boolean validateAndUpdateState() { return validationPassed; } + private Fragment getFirstRequiredQuestionPos() { + List fragments = getRetainedChildFragmentManager().getFragments(); + for (Fragment fragment : fragments) { + SurveyQuestionView surveyQuestionView = (SurveyQuestionView) fragment; + if (!surveyQuestionView.isValid()) { + return fragment; + } + } + return null; + } + void sendMetricForQuestion(Activity activity, String questionId) { JSONObject answerData = new JSONObject(); try { @@ -296,4 +334,8 @@ public int getToolbarNavigationIconResourceId(Resources.Theme activityTheme) { return Util.getResourceIdFromAttribute(activityTheme, R.attr.apptentiveToolbarIconClose); } + @Override + public String getToolbarNavigationContentDescription() { + return getContext().getString(R.string.apptentive_survey_content_description_close_button); + } } \ No newline at end of file diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/InteractionCriteria.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/InteractionCriteria.java index e04914ff8..b9e5026bd 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/InteractionCriteria.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/InteractionCriteria.java @@ -9,6 +9,7 @@ import com.apptentive.android.sdk.ApptentiveLog; import com.apptentive.android.sdk.module.engagement.logic.Clause; import com.apptentive.android.sdk.module.engagement.logic.ClauseParser; +import com.apptentive.android.sdk.module.engagement.logic.FieldManager; import org.json.JSONException; @@ -23,13 +24,13 @@ public InteractionCriteria(String json) throws JSONException { this.json = json; } - public boolean isMet() { + public boolean isMet(FieldManager fieldManager) { try { Clause rootClause = ClauseParser.parse(json); ApptentiveLog.i("Evaluating Criteria"); boolean ret = false; if (rootClause != null) { - ret = rootClause.evaluate(); + ret = rootClause.evaluate(fieldManager); } ApptentiveLog.i("- => %b", ret); return ret; diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Invocation.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Invocation.java index e1ccfbbec..07ca043bf 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Invocation.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Invocation.java @@ -6,6 +6,8 @@ package com.apptentive.android.sdk.module.engagement.interaction.model; +import com.apptentive.android.sdk.module.engagement.logic.FieldManager; + import org.json.JSONException; import org.json.JSONObject; @@ -32,12 +34,12 @@ public String getInteractionId() { return null; } - public boolean isCriteriaMet() { + public boolean isCriteriaMet(FieldManager fieldManager) { try { if (!isNull(KEY_CRITERIA)) { JSONObject criteriaObject = getJSONObject(KEY_CRITERIA); InteractionCriteria criteria = new InteractionCriteria(criteriaObject.toString()); - return criteria.isMet(); + return criteria.isMet(fieldManager); } } catch (JSONException e) { // Ignore diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/MessageCenterInteraction.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/MessageCenterInteraction.java index 816d6b689..fd83d1d31 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/MessageCenterInteraction.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/MessageCenterInteraction.java @@ -237,7 +237,7 @@ public MessageCenterStatus getErrorStatusServer() { if (errorStatus == null) { return null; } - return new MessageCenterStatus(errorStatus.optString(KEY_ERROR_HTTP_BODY), R.drawable.apptentive_icon_server_error); + return new MessageCenterStatus(errorStatus.optString(KEY_ERROR_HTTP_BODY), R.drawable.apptentive_ic_error); } public MessageCenterStatus getErrorStatusNetwork() { @@ -249,6 +249,6 @@ public MessageCenterStatus getErrorStatusNetwork() { if (errorStatus == null) { return null; } - return new MessageCenterStatus(errorStatus.optString(KEY_ERROR_NETWORK_BODY), R.drawable.apptentive_icon_no_connection); + return new MessageCenterStatus(errorStatus.optString(KEY_ERROR_NETWORK_BODY), R.drawable.apptentive_ic_no_connection); } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Targets.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Targets.java index 6291d29af..8e90bad79 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Targets.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/Targets.java @@ -6,7 +6,10 @@ package com.apptentive.android.sdk.module.engagement.interaction.model; +import com.apptentive.android.sdk.ApptentiveInternal; import com.apptentive.android.sdk.ApptentiveLog; +import com.apptentive.android.sdk.conversation.Conversation; +import com.apptentive.android.sdk.module.engagement.logic.FieldManager; import org.json.JSONArray; import org.json.JSONException; @@ -31,7 +34,10 @@ public String getApplicableInteraction(String eventLabel) { if (invocationObject != null) { try { Invocation invocation = new Invocation(invocationObject.toString()); - if (invocation.isCriteriaMet()) { + Conversation conversation = ApptentiveInternal.getInstance().getConversation(); + FieldManager fieldManager = new FieldManager(ApptentiveInternal.getInstance().getApplicationContext(), conversation.getVersionHistory(), conversation.getEventData(), conversation.getPerson(), conversation.getDevice(), conversation.getAppRelease()); + + if (invocation.isCriteriaMet(fieldManager)) { return invocation.getInteractionId(); } } catch (JSONException e) { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/BaseQuestion.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/BaseQuestion.java index 93de06016..12c9eb610 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/BaseQuestion.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/BaseQuestion.java @@ -16,6 +16,7 @@ abstract public class BaseQuestion extends JSONObject implements Question { private static final String KEY_VALUE = "value"; private static final String KEY_REQUIRED = "required"; private static final String KEY_INSTRUCTIONS = "instructions"; + private static final String KEY_ERROR_MESSAGE = "error_message"; // Internal state that doesn't exist on the server. private static final String KEY_ANSWERS = "answers"; @@ -44,6 +45,11 @@ public String getRequiredText() { return optString(KEY_REQUIRED_TEXT, null); } + @Override + public String getErrorMessage() { + return optString(KEY_ERROR_MESSAGE, null); + } + public void setRequiredText(String requiredText) { try { put(KEY_REQUIRED_TEXT, requiredText); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/Question.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/Question.java index aa4ca498b..77e254634 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/Question.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/model/survey/Question.java @@ -22,6 +22,7 @@ public interface Question { String getRequiredText(); void setRequiredText(String requiredText); String getInstructions(); + String getErrorMessage(); int getMinSelections(); int getMaxSelections(); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/BaseSurveyQuestionView.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/BaseSurveyQuestionView.java index 9b79d6aa6..16f272793 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/BaseSurveyQuestionView.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/BaseSurveyQuestionView.java @@ -125,6 +125,11 @@ public String getQuestionId() { public abstract Object getAnswer(); + @Override + public String getErrorMessage() { + return question.getErrorMessage(); + } + @Override public boolean didSendMetric() { return sentMetric; diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/SurveyQuestionView.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/SurveyQuestionView.java index d1a34d6dd..175eea038 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/SurveyQuestionView.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/SurveyQuestionView.java @@ -28,6 +28,11 @@ public interface SurveyQuestionView { */ Object getAnswer(); + /** + * Error message for the case if required question is not answered + */ + String getErrorMessage(); + boolean didSendMetric(); void setSentMetric(boolean sent); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/TextSurveyQuestionView.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/TextSurveyQuestionView.java index 7104596e4..710b8a31e 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/TextSurveyQuestionView.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/view/survey/TextSurveyQuestionView.java @@ -78,6 +78,8 @@ public void onViewCreated(View view, Bundle savedInstanceState) { String hint = question.getFreeformHint(); if (!TextUtils.isEmpty(hint)) { answerTextInputLayout.setHint(hint); + answerTextInputLayout.setContentDescription(hint); + answer.setContentDescription(hint); } answer.setOnFocusChangeListener(new View.OnFocusChangeListener() { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/Clause.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/Clause.java index fdbd22421..b7fe5ea10 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/Clause.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/Clause.java @@ -8,5 +8,5 @@ public interface Clause { - boolean evaluate(); + boolean evaluate(FieldManager fieldManager); } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/ConditionalClause.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/ConditionalClause.java index b9fc5673e..e64098153 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/ConditionalClause.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/ConditionalClause.java @@ -62,9 +62,9 @@ private boolean isComplexType(JSONObject jsonObject) { * @return */ @Override - public boolean evaluate() { + public boolean evaluate(FieldManager fieldManager) { ApptentiveLog.v(" - %s", fieldName); - Comparable fieldValue = FieldManager.getValue(fieldName); + Comparable fieldValue = fieldManager.getValue(fieldName); for (ConditionalTest test : conditionalTests) { ApptentiveLog.v(" - %s %s %s?", Util.classToString(fieldValue), test.operator, Util.classToString(test.parameter)); if (!test.operator.apply(fieldValue, test.parameter)) { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/FieldManager.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/FieldManager.java index c1d0c25a8..af3b74622 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/FieldManager.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/FieldManager.java @@ -6,14 +6,17 @@ package com.apptentive.android.sdk.module.engagement.logic; +import android.content.Context; + import com.apptentive.android.sdk.Apptentive; -import com.apptentive.android.sdk.ApptentiveInternal; import com.apptentive.android.sdk.ApptentiveLog; -import com.apptentive.android.sdk.BuildConfig; -import com.apptentive.android.sdk.conversation.Conversation; +import com.apptentive.android.sdk.debug.Assert; +import com.apptentive.android.sdk.storage.AppRelease; import com.apptentive.android.sdk.storage.CustomData; import com.apptentive.android.sdk.storage.Device; +import com.apptentive.android.sdk.storage.EventData; import com.apptentive.android.sdk.storage.Person; +import com.apptentive.android.sdk.storage.VersionHistory; import com.apptentive.android.sdk.util.Constants; import com.apptentive.android.sdk.util.Util; @@ -21,20 +24,38 @@ public class FieldManager { - public static boolean exists(String query) { + Context context; + VersionHistory versionHistory; + EventData eventData; + Person person; + Device device; + AppRelease appRelease; + + public FieldManager(Context context, VersionHistory versionHistory, EventData eventData, Person person, Device device, AppRelease appRelease) { + Assert.notNull(context); + Assert.notNull(versionHistory); + Assert.notNull(eventData); + Assert.notNull(person); + Assert.notNull(device); + this.context = context; + this.versionHistory = versionHistory; + this.eventData = eventData; + this.person = person; + this.device = device; + this.appRelease = appRelease; + } + + public boolean exists(String query) { return getValue(query) != null; } - public static Comparable getValue(String query) { + public Comparable getValue(String query) { Object rawValue = doGetValue(query); return (Comparable) ClauseParser.parseValue(rawValue); } - public static Object doGetValue(String query) { - Conversation conversation = ApptentiveInternal.getInstance().getConversation(); // TODO: get rid of singleton - if (conversation == null) { - return null; - } + private Object doGetValue(String query) { + query = query.trim(); String[] tokens = query.split("/"); QueryPart topLevelQuery = QueryPart.parse(tokens[0]); @@ -44,23 +65,15 @@ public static Object doGetValue(String query) { QueryPart applicationQuery = QueryPart.parse(tokens[1]); switch (applicationQuery) { case version_code: { - int version = Util.getAppVersionCode(ApptentiveInternal.getInstance().getApplicationContext()); - if (version == -1) { - version = 0; // Default - } - return version; + return appRelease.getVersionCode(); } case version_name: { - String version = Util.getAppVersionName(ApptentiveInternal.getInstance().getApplicationContext()); - if (version == null) { - version = "0"; // Default - } Apptentive.Version ret = new Apptentive.Version(); - ret.setVersion(version); + ret.setVersion(appRelease.getVersionName()); return ret; } case debug: { - return BuildConfig.DEBUG; + return appRelease.isDebug(); } } return null; // Default value @@ -80,9 +93,9 @@ public static Object doGetValue(String query) { QueryPart subQuery = QueryPart.parse(tokens[1]); switch (subQuery) { case version_code: - return conversation.getVersionHistory().isUpdateForVersionCode(); + return versionHistory.isUpdateForVersionCode(); case version_name: - return conversation.getVersionHistory().isUpdateForVersionName(); + return versionHistory.isUpdateForVersionName(); default: break; } @@ -92,11 +105,11 @@ public static Object doGetValue(String query) { QueryPart subQuery = QueryPart.parse(tokens[1]); switch (subQuery) { case total: - return conversation.getVersionHistory().getTimeAtInstallTotal(); + return versionHistory.getTimeAtInstallTotal(); case version_code: - return conversation.getVersionHistory().getTimeAtInstallForCurrentVersionCode(); + return versionHistory.getTimeAtInstallForVersionCode(Util.getAppVersionCode(context)); case version_name: - return conversation.getVersionHistory().getTimeAtInstallForCurrentVersionName(); + return versionHistory.getTimeAtInstallForVersionName(Util.getAppVersionName(context)); } return new Apptentive.DateTime(Util.currentTimeSeconds()); } @@ -108,13 +121,13 @@ public static Object doGetValue(String query) { QueryPart queryPart2 = QueryPart.parse(tokens[3]); switch (queryPart2) { case total: // Get total for all versions of the app. - return new BigDecimal(conversation.getEventData().getInteractionCountTotal(interactionId)); + return new BigDecimal(eventData.getInteractionCountTotal(interactionId)); case version_code: - Integer appVersionCode = Util.getAppVersionCode(ApptentiveInternal.getInstance().getApplicationContext()); - return new BigDecimal(conversation.getEventData().getInteractionCountForVersionCode(interactionId, appVersionCode)); + Integer appVersionCode = Util.getAppVersionCode(context); + return new BigDecimal(eventData.getInteractionCountForVersionCode(interactionId, appVersionCode)); case version_name: - String appVersionName = Util.getAppVersionName(ApptentiveInternal.getInstance().getApplicationContext()); - return new BigDecimal(conversation.getEventData().getInteractionCountForVersionName(interactionId, appVersionName)); + String appVersionName = Util.getAppVersionName(context); + return new BigDecimal(eventData.getInteractionCountForVersionName(interactionId, appVersionName)); default: break; } @@ -123,7 +136,7 @@ public static Object doGetValue(String query) { QueryPart queryPart3 = QueryPart.parse(tokens[3]); switch (queryPart3) { case total: - Double lastInvoke = conversation.getEventData().getTimeOfLastInteractionInvocation(interactionId); + Double lastInvoke = eventData.getTimeOfLastInteractionInvocation(interactionId); if (lastInvoke != null) { return new Apptentive.DateTime(lastInvoke); } @@ -143,13 +156,13 @@ public static Object doGetValue(String query) { QueryPart queryPart2 = QueryPart.parse(tokens[3]); switch (queryPart2) { case total: // Get total for all versions of the app. - return new BigDecimal(conversation.getEventData().getEventCountTotal(eventLabel)); + return new BigDecimal(eventData.getEventCountTotal(eventLabel)); case version_code: - Integer appVersionCode = Util.getAppVersionCode(ApptentiveInternal.getInstance().getApplicationContext()); - return new BigDecimal(conversation.getEventData().getEventCountForVersionCode(eventLabel, appVersionCode)); + Integer appVersionCode = Util.getAppVersionCode(context); + return new BigDecimal(eventData.getEventCountForVersionCode(eventLabel, appVersionCode)); case version_name: - String appVersionName = Util.getAppVersionName(ApptentiveInternal.getInstance().getApplicationContext()); - return new BigDecimal(conversation.getEventData().getEventCountForVersionName(eventLabel, appVersionName)); + String appVersionName = Util.getAppVersionName(context); + return new BigDecimal(eventData.getEventCountForVersionName(eventLabel, appVersionName)); default: break; } @@ -158,7 +171,7 @@ public static Object doGetValue(String query) { QueryPart queryPart3 = QueryPart.parse(tokens[3]); switch (queryPart3) { case total: - Double lastInvoke = conversation.getEventData().getTimeOfLastEventInvocation(eventLabel); + Double lastInvoke = eventData.getTimeOfLastEventInvocation(eventLabel); if (lastInvoke != null) { return new Apptentive.DateTime(lastInvoke); } @@ -172,7 +185,6 @@ public static Object doGetValue(String query) { } case person: { QueryPart subQuery = QueryPart.parse(tokens[1]); - Person person = conversation.getPerson(); if (person == null) { return null; } @@ -181,7 +193,12 @@ public static Object doGetValue(String query) { String customDataKey = tokens[2].trim(); CustomData customData = person.getCustomData(); if (customData != null) { - return customData.get(customDataKey); + // We didn't trim the keys when they were added, so we need to iterate over them, trim them, then compare in order to get values. + for (String key : customData.keySet()) { + if (key.trim().equals(customDataKey)) { + return customData.get(key); + } + } } break; case name: @@ -194,7 +211,6 @@ public static Object doGetValue(String query) { } case device: { QueryPart subQuery = QueryPart.parse(tokens[1]); - Device device = conversation.getDevice(); if (device == null) { return null; } @@ -203,7 +219,12 @@ public static Object doGetValue(String query) { String customDataKey = tokens[2].trim(); CustomData customData = device.getCustomData(); if (customData != null) { - return customData.get(customDataKey); + // We didn't trim the keys when they were added, so we need to iterate over them, trim them, then compare in order to get values. + for (String key : customData.keySet()) { + if (key.trim().equals(customDataKey)) { + return customData.get(key); + } + } } break; case os_version: diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/LogicalClause.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/LogicalClause.java index c29ca59f2..3ad02b409 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/LogicalClause.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/logic/LogicalClause.java @@ -54,11 +54,11 @@ protected LogicalClause(String key, Object value) throws JSONException { } @Override - public boolean evaluate() { + public boolean evaluate(FieldManager fieldManager) { ApptentiveLog.v(" - <%s>", operator.name()); if (operator == LogicalOperator.$and) { for (Clause clause : children) { - boolean ret = clause.evaluate(); + boolean ret = clause.evaluate(fieldManager); ApptentiveLog.v(" - => %b", ret); if (!ret) { ApptentiveLog.v(" - ", operator.name()); @@ -69,7 +69,7 @@ public boolean evaluate() { return true; } else if (operator == LogicalOperator.$or) { for (Clause clause : children) { - boolean ret = clause.evaluate(); + boolean ret = clause.evaluate(fieldManager); ApptentiveLog.v(" - => %b", ret); if (ret) { ApptentiveLog.v(" - ", operator.name()); @@ -83,7 +83,7 @@ public boolean evaluate() { throw new IllegalArgumentException("$not condition must have exactly one child, has ." + children.size()); } Clause clause = children.get(0); - boolean ret = clause.evaluate(); + boolean ret = clause.evaluate(fieldManager); ApptentiveLog.v(" - => %b", ret); ApptentiveLog.v(" - ", operator.name()); return !ret; diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java index 9e6e8c820..9342e125c 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java @@ -98,6 +98,15 @@ protected void execute(int messageCount) { } }; + /** + * Testing only. + */ + protected MessageManager() { + conversation = null; + messageStore = null; + pollingWorker = null; + } + public MessageManager(Conversation conversation, MessageStore messageStore) { if (conversation == null) { throw new IllegalArgumentException("Conversation is null"); @@ -263,7 +272,7 @@ public void updateMessage(ApptentiveMessage apptentiveMessage) { messageStore.updateMessage(apptentiveMessage); } - private List parseMessagesString(String messageString) throws JSONException { + public List parseMessagesString(String messageString) throws JSONException { List ret = new ArrayList<>(); JSONObject root = new JSONObject(messageString); if (!root.isNull("messages")) { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/AttachmentPreviewDialog.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/AttachmentPreviewDialog.java index cb701d34e..d531ec3ab 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/AttachmentPreviewDialog.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/AttachmentPreviewDialog.java @@ -30,12 +30,12 @@ import com.apptentive.android.sdk.util.image.PreviewImageView; -public class AttachmentPreviewDialog extends DialogFragment implements DialogInterface.OnDismissListener, - PreviewImageView.GestureCallback { +public class AttachmentPreviewDialog extends DialogFragment implements DialogInterface.OnDismissListener, PreviewImageView.GestureCallback { private View previewContainer; private ProgressBar progressBar; private PreviewImageView previewImageView; + private ImageView previewImagePlaceholderView; private ViewGroup header; private ImageButton closeButton; private int width; @@ -64,6 +64,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa previewContainer = rootView.findViewById(R.id.preview_container); progressBar = (ProgressBar) rootView.findViewById(R.id.preview_progress); previewImageView = (PreviewImageView) rootView.findViewById(R.id.preview_image); + previewImagePlaceholderView = (ImageView) rootView.findViewById(R.id.preview_image_placeholder); previewImageView.setGestureCallback(this); header = (ViewGroup) rootView.findViewById(R.id.header_bar); @@ -99,6 +100,7 @@ public void onLoaded(ImageView view, int pos, Bitmap d) { previewContainer.setVisibility(View.VISIBLE); if (!d.isRecycled()) { previewImageView.setImageBitmap(d); + previewImagePlaceholderView.setVisibility(View.GONE); } } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/GreetingHolder.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/GreetingHolder.java index 6caa7937d..4b11f6b50 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/GreetingHolder.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/GreetingHolder.java @@ -37,7 +37,9 @@ public GreetingHolder(View itemView) { public void bindView(MessageCenterGreeting greeting) { title.setText(greeting.title); + title.setContentDescription(greeting.title); body.setText(greeting.body); + body.setContentDescription(greeting.body); ImageUtil.startDownloadAvatarTask(avatar, greeting.avatar); infoButton.setOnClickListener(new View.OnClickListener() { public void onClick(final View view) { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/MessageComposerHolder.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/MessageComposerHolder.java index 8e42a781a..99a240ccd 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/MessageComposerHolder.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/MessageComposerHolder.java @@ -79,6 +79,7 @@ public MessageComposerHolder(View itemView) { public void bindView(final MessageCenterFragment fragment, final MessageCenterRecyclerViewAdapter adapter, final Composer composer) { title.setText(composer.title); + title.setContentDescription(composer.title); closeButton.setOnClickListener(new View.OnClickListener() { @@ -153,7 +154,7 @@ public void onClick(int position, ImageItem image) { } } }); - attachments.setAdapterIndicator(R.drawable.apptentive_ic_remove_attachment); + attachments.setAdapterIndicator(R.drawable.apptentive_remove_button); attachments.setImageIndicatorCallback(fragment); //Initialize image attachments band with empty data diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java index 10bfa23b8..53910d588 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java @@ -52,12 +52,14 @@ public void bindView(MessageCenterFragment fragment, final RecyclerView recycler imageBandView.setupUi(); messageBodyView.setText(message.getBody()); +/* // We have to disable text selection, or the Google TalkBack won't read this unless it's selected. It's too tiny to select by itself easily. AccessibilityManager accessibilityManager = (AccessibilityManager) fragment.getContext().getSystemService(ACCESSIBILITY_SERVICE); if (accessibilityManager != null) { boolean talkbackNotEnabled = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN).isEmpty(); messageBodyView.setTextIsSelectable(talkbackNotEnabled); } +*/ boolean showProgress; Double createdAt = message.getCreatedAt(); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/WhoCardHolder.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/WhoCardHolder.java index 7381b4f05..3e69b80d8 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/WhoCardHolder.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/WhoCardHolder.java @@ -6,12 +6,15 @@ package com.apptentive.android.sdk.module.messagecenter.view.holder; +import android.os.Build; +import android.support.annotation.RequiresApi; import android.support.design.widget.TextInputLayout; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.View; +import android.view.accessibility.AccessibilityEvent; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; @@ -20,7 +23,6 @@ import com.apptentive.android.sdk.R; import com.apptentive.android.sdk.module.messagecenter.model.WhoCard; import com.apptentive.android.sdk.module.messagecenter.view.MessageCenterRecyclerViewAdapter; -import com.apptentive.android.sdk.util.StringUtils; import com.apptentive.android.sdk.util.Util; import static android.view.View.GONE; @@ -60,17 +62,15 @@ public void bindView(RecyclerView recyclerView, final WhoCard whoCard) { title.setVisibility(GONE); } else { title.setVisibility(VISIBLE); - title.setHint(whoCard.getTitle()); + title.setText(whoCard.getTitle()); + itemView.setContentDescription(whoCard.getTitle()); } - View viewToFocus; if (TextUtils.isEmpty(whoCard.getNameHint())) { nameLayout.setVisibility(GONE); - viewToFocus = emailEditText; } else { nameLayout.setVisibility(VISIBLE); nameLayout.setHint(whoCard.getNameHint()); - viewToFocus = nameEditText; } nameEditText.setText(Apptentive.getPersonName()); nameEditText.addTextChangedListener(new TextWatcher() { @@ -158,7 +158,17 @@ public void onClick(View view) { } }); if (adapter.getListener() != null) { - adapter.getListener().onWhoCardViewCreated(nameEditText, emailEditText, viewToFocus); + adapter.getListener().onWhoCardViewCreated(nameEditText, emailEditText, null); + } + + // we need to properly announce the profile card: sending an implicit accessibility event + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + itemView.postDelayed(new Runnable() { + @Override + public void run() { + itemView.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT); + } + }, 500); } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/network/HttpRequest.java b/apptentive/src/main/java/com/apptentive/android/sdk/network/HttpRequest.java index cd950c1a6..604c2d04d 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/network/HttpRequest.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/network/HttpRequest.java @@ -587,6 +587,10 @@ public int getResponseCode() { return responseCode; } + public String getResponseHeader(String key) { + return responseHeaders != null ? responseHeaders.get(key) : null; + } + public boolean isAuthenticationFailure() { return responseCode == 401; } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/storage/AppReleaseManager.java b/apptentive/src/main/java/com/apptentive/android/sdk/storage/AppReleaseManager.java index 7964a4e07..432c31c13 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/storage/AppReleaseManager.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/storage/AppReleaseManager.java @@ -49,7 +49,9 @@ public static AppRelease generateCurrentAppRelease(Context context, ApptentiveIn appRelease.setAppStore(Util.getInstallerPackageName(context)); appRelease.setDebug(isAppDebuggable); appRelease.setIdentifier(appPackageName); - appRelease.setInheritStyle(apptentiveInternal.isAppUsingAppCompatTheme()); + if (apptentiveInternal != null) { + appRelease.setInheritStyle(apptentiveInternal.isAppUsingAppCompatTheme()); + } appRelease.setOverrideStyle(themeOverrideResId != 0); appRelease.setTargetSdkVersion(String.valueOf(targetSdkVersion)); appRelease.setType("android"); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/storage/DeviceManager.java b/apptentive/src/main/java/com/apptentive/android/sdk/storage/DeviceManager.java index 5d40e5390..aab86f0f7 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/storage/DeviceManager.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/storage/DeviceManager.java @@ -43,7 +43,7 @@ public static Device generateNewDevice(Context context) { device.setBuildId(Build.ID); // Second, set the stuff that requires querying system services. - TelephonyManager tm = ((TelephonyManager) (ApptentiveInternal.getInstance().getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE))); + TelephonyManager tm = ((TelephonyManager) (context.getSystemService(Context.TELEPHONY_SERVICE))); device.setCarrier(tm.getSimOperatorName()); device.setCurrentCarrier(tm.getNetworkOperatorName()); device.setNetworkType(Constants.networkTypeAsString(tm.getNetworkType())); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/storage/EventData.java b/apptentive/src/main/java/com/apptentive/android/sdk/storage/EventData.java index e4e530936..0f74b0978 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/storage/EventData.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/storage/EventData.java @@ -159,5 +159,11 @@ public synchronized void setInteractions(Map interactions) this.interactions = interactions; notifyDataChanged(); } + + public synchronized void clear() { + events.clear(); + interactions.clear(); + notifyDataChanged(); + } //endregion } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/storage/SdkManager.java b/apptentive/src/main/java/com/apptentive/android/sdk/storage/SdkManager.java index 91ff9fa05..aea9df391 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/storage/SdkManager.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/storage/SdkManager.java @@ -6,14 +6,17 @@ package com.apptentive.android.sdk.storage; -import com.apptentive.android.sdk.ApptentiveInternal; +import android.content.Context; +import android.content.res.Resources; + +import com.apptentive.android.sdk.ApptentiveLog; +import com.apptentive.android.sdk.R; import com.apptentive.android.sdk.model.SdkPayload; import com.apptentive.android.sdk.util.Constants; -import com.apptentive.android.sdk.util.Util; public class SdkManager { - public static Sdk generateCurrentSdk() { + public static Sdk generateCurrentSdk(Context context) { Sdk sdk = new Sdk(); // First, get all the information we can load from static resources. @@ -21,14 +24,10 @@ public static Sdk generateCurrentSdk() { sdk.setPlatform("Android"); // Distribution and distribution version are optionally set in the manifest by the wrapping platform (Cordova, mParticle, etc.) - Object distribution = Util.getPackageMetaDataSingleQuotedString(ApptentiveInternal.getInstance().getApplicationContext(), Constants.MANIFEST_KEY_SDK_DISTRIBUTION); - if (distribution != null && distribution.toString().length() != 0) { - sdk.setDistribution(distribution.toString()); - } - Object distributionVersion = Util.getPackageMetaDataSingleQuotedString(ApptentiveInternal.getInstance().getApplicationContext(), Constants.MANIFEST_KEY_SDK_DISTRIBUTION_VERSION); - if (distributionVersion != null && distributionVersion.toString().length() != 0) { - sdk.setDistributionVersion(distributionVersion.toString()); - } + Resources resources = context.getResources(); + sdk.setDistribution(resources.getString(R.string.apptentive_distribution)); + sdk.setDistributionVersion(resources.getString(R.string.apptentive_distribution_version)); + ApptentiveLog.vv("SDK: %s:%s", sdk.getDistribution(), sdk.getDistributionVersion()); return sdk; } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/storage/VersionHistory.java b/apptentive/src/main/java/com/apptentive/android/sdk/storage/VersionHistory.java index 30e1a9452..cf1e9b8c8 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/storage/VersionHistory.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/storage/VersionHistory.java @@ -7,7 +7,6 @@ package com.apptentive.android.sdk.storage; import com.apptentive.android.sdk.Apptentive; -import com.apptentive.android.sdk.ApptentiveInternal; import com.apptentive.android.sdk.util.Util; import java.util.ArrayList; @@ -74,9 +73,9 @@ public Apptentive.DateTime getTimeAtInstallTotal() { /** * Returns the timestamp at the first install of the current versionCode of this app that Apptentive was aware of. */ - public Apptentive.DateTime getTimeAtInstallForCurrentVersionCode() { + public Apptentive.DateTime getTimeAtInstallForVersionCode(int versionCode) { for (VersionHistoryItem item : versionHistoryItems) { - if (item.getVersionCode() == Util.getAppVersionCode(ApptentiveInternal.getInstance().getApplicationContext())) { + if (item.getVersionCode() == versionCode) { return new Apptentive.DateTime(item.getTimestamp()); } } @@ -86,12 +85,12 @@ public Apptentive.DateTime getTimeAtInstallForCurrentVersionCode() { /** * Returns the timestamp at the first install of the current versionName of this app that Apptentive was aware of. */ - public Apptentive.DateTime getTimeAtInstallForCurrentVersionName() { + public Apptentive.DateTime getTimeAtInstallForVersionName(String versionName) { for (VersionHistoryItem item : versionHistoryItems) { Apptentive.Version entryVersionName = new Apptentive.Version(); Apptentive.Version currentVersionName = new Apptentive.Version(); entryVersionName.setVersion(item.getVersionName()); - currentVersionName.setVersion(Util.getAppVersionName(ApptentiveInternal.getInstance().getApplicationContext())); + currentVersionName.setVersion(versionName); if (entryVersionName.equals(currentVersionName)) { return new Apptentive.DateTime(item.getTimestamp()); } @@ -133,4 +132,9 @@ public VersionHistoryItem getLastVersionSeen() { } return null; } + + public synchronized void clear() { + versionHistoryItems.clear(); + notifyDataChanged(); + } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java b/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java index 3f53ae04b..01eb41585 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java @@ -9,7 +9,7 @@ public class Constants { public static final int API_VERSION = 9; - public static final String APPTENTIVE_SDK_VERSION = "4.0.2"; + public static final String APPTENTIVE_SDK_VERSION = "4.1.0"; public static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 45000; public static final int DEFAULT_READ_TIMEOUT_MILLIS = 45000; @@ -58,8 +58,6 @@ public class Constants { public static final String MANIFEST_KEY_APPTENTIVE_LOG_LEVEL = "apptentive_log_level"; public static final String MANIFEST_KEY_APPTENTIVE_KEY = "apptentive_key"; public static final String MANIFEST_KEY_APPTENTIVE_SIGNATURE = "apptentive_signature"; - public static final String MANIFEST_KEY_SDK_DISTRIBUTION = "apptentive_sdk_distribution"; - public static final String MANIFEST_KEY_SDK_DISTRIBUTION_VERSION = "apptentive_sdk_distribution_version"; public static final String MANIFEST_KEY_INITIALLY_HIDE_BRANDING = "apptentive_initially_hide_branding"; public static final String MANIFEST_KEY_APPTENTIVE_DEBUG = "apptentive_debug"; //endregion @@ -88,8 +86,15 @@ public class Constants { public static final String PREF_KEY_INTERACTIONS_PAYLOAD_CACHE_EXPIRATION = "interactionsCacheExpiration"; //endregion + //region File names + public static final String FILE_APPTENTIVE_LOG_FILE = "apptentive-log.txt"; + public static final String FILE_APPTENTIVE_ENGAGEMENT_MANIFEST = "apptentive-engagement-manifest.txt"; + //endregion + //region Old keys no longer used + public static final String MANIFEST_KEY_SDK_DISTRIBUTION = "apptentive_sdk_distribution"; + public static final String MANIFEST_KEY_SDK_DISTRIBUTION_VERSION = "apptentive_sdk_distribution_version"; public static final String PREF_KEY_APP_ACTIVITY_STATE_QUEUE = "appActivityStateQueue"; public static final String PREF_KEY_PERSON_EMAIL = "personEmail"; public static final String PREF_KEY_PERSON_NAME = "personName"; diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/util/Util.java b/apptentive/src/main/java/com/apptentive/android/sdk/util/Util.java index eaea519cf..3f4f4ad68 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/util/Util.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/util/Util.java @@ -9,6 +9,9 @@ import android.Manifest; import android.app.Activity; import android.content.ActivityNotFoundException; +import android.content.ClipData; +import android.content.ClipDescription; +import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; @@ -712,6 +715,29 @@ public static byte[] readBytes(File file) throws IOException { } } + public static void writeText(File file, String text) throws IOException { + if (file == null) { + throw new IllegalArgumentException("'file' is null"); + } + + if (text == null) { + throw new IllegalArgumentException("'text' is null"); + } + + File parentFile = file.getParentFile(); + if (!parentFile.exists() && !parentFile.mkdirs()) { + throw new IOException("Parent file could not be created: " + parentFile); + } + + PrintStream output = null; + try { + output = new PrintStream(file, "UTF-8"); + output.print(text); + } finally { + ensureClosed(output); + } + } + public static void appendFileToStream(File file, OutputStream outputStream) throws IOException { if (file == null) { throw new IllegalArgumentException("'file' is null"); @@ -1006,4 +1032,36 @@ public static String getManifestMetadataString(Context context, String key) { return null; } + + public static String getClipboardText(Context context) { + if (context == null) { + throw new IllegalArgumentException("Context is null"); + } + + ClipboardManager manager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + if (!manager.hasPrimaryClip()) { + return null; + } + + ClipDescription primaryClipDescription = manager.getPrimaryClipDescription(); + if (!primaryClipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) && !primaryClipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML)) { + return null; + } + + ClipData clip = manager.getPrimaryClip(); + if (clip != null && clip.getItemCount() > 0) { + return clip.getItemAt(0).getText().toString(); + } + + return null; + } + + public static void setClipboardText(Context context, String text) { + if (context == null) { + throw new IllegalArgumentException("Context is null"); + } + + ClipboardManager manager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + manager.setPrimaryClip(ClipData.newPlainText(null, text)); + } } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/util/image/ImageGridViewAdapter.java b/apptentive/src/main/java/com/apptentive/android/sdk/util/image/ImageGridViewAdapter.java index acfc3f1c0..d2ea90f85 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/util/image/ImageGridViewAdapter.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/util/image/ImageGridViewAdapter.java @@ -1,7 +1,7 @@ package com.apptentive.android.sdk.util.image; /* - * Copyright (c) 2015, Apptentive, Inc. All Rights Reserved. + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. * Please refer to the LICENSE file for the terms and conditions * under which redistribution and use of this file is permitted. */ @@ -9,6 +9,8 @@ import android.content.Context; import android.graphics.Bitmap; import android.os.Environment; +import android.support.v7.app.AppCompatDelegate; +import android.support.v7.widget.AppCompatImageView; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -22,14 +24,13 @@ import com.apptentive.android.sdk.ApptentiveLog; import com.apptentive.android.sdk.R; +import com.apptentive.android.sdk.util.Util; +import com.apptentive.android.sdk.view.ApptentiveMaterialDeterminateProgressBar; import java.io.File; import java.util.ArrayList; import java.util.List; -import com.apptentive.android.sdk.util.Util; -import com.apptentive.android.sdk.view.ApptentiveMaterialDeterminateProgressBar; - public class ImageGridViewAdapter extends BaseAdapter { @@ -111,9 +112,9 @@ public boolean clickOn(int index) { if (item == null || TextUtils.isEmpty(item.mimeType)) { return false; } - // For non-image item, fisrt time tap will start download + // For non-image items, the first tap will start it downloading if (!Util.isMimeTypeImage(item.mimeType)) { - // It is being downloaded, do nothing (prevent dobue tap, etc) + // It is being downloaded, do nothing (prevent double tap, etc) if (downloadItems.contains(item.originalPath)) { return true; } else { @@ -282,8 +283,9 @@ public View getView(int i, View view, ViewGroup viewGroup) { } class ViewHolder { + AppCompatImageView imagePlaceholder; ImageView image; - ImageView indicator; + AppCompatImageView indicator; TextView attachmentExtension; // a circular indeterminate progress bar showing local file loading progress ProgressBar progressBarLoading; @@ -295,8 +297,9 @@ class ViewHolder { boolean bLoadThumbnail; ViewHolder(View view, int index) { + imagePlaceholder = (AppCompatImageView) view.findViewById(R.id.image_placeholder); image = (ImageView) view.findViewById(R.id.image); - indicator = (ImageView) view.findViewById(R.id.indicator); + indicator = (AppCompatImageView) view.findViewById(R.id.indicator); mask = view.findViewById(R.id.mask); attachmentExtension = (TextView) view.findViewById(R.id.image_file_extension); progressBarLoading = (ProgressBar) view.findViewById(R.id.thumbnail_progress); @@ -311,14 +314,11 @@ void bindData(final int index) { return; } - final int placeholderResId; // Image indicators are overlay controls, such as close button, check box if (showImageIndicator) { indicator.setVisibility(View.VISIBLE); image.setVisibility(View.VISIBLE); if (selectedImages.contains(data)) { - // set as selected - indicator.setImageResource(R.drawable.apptentive_ic_image_picker_selected); // Of item selection is enabled, show a translucant mask overlay for selected item mask.setVisibility(View.VISIBLE); } else { @@ -327,6 +327,9 @@ void bindData(final int index) { indicator.setVisibility(View.GONE); image.setVisibility(View.GONE); } else { + // Allows loading of vector drawable resources from XML + AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); + // Add remove button overlay indicator.setImageResource(defaultImageIndicator); indicator.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { @@ -353,37 +356,39 @@ public void onClick(View v) { if (Util.isMimeTypeImage(data.mimeType)) { if (TextUtils.isEmpty(data.originalPath)) { // This is the "Add Attachment" image - image.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - placeholderResId = R.drawable.apptentive_ic_add; - image.setContentDescription(image.getContext().getResources().getString(R.string.apptentive_message_center_content_description_attachment_add)); - indicator.setVisibility(View.GONE); bLoadThumbnail = false; + imagePlaceholder.setContentDescription(image.getContext().getResources().getString(R.string.apptentive_message_center_content_description_attachment_add)); + imagePlaceholder.setImageResource(R.drawable.apptentive_add_circle_outline); + imagePlaceholder.setVisibility(View.VISIBLE); + image.setVisibility(View.GONE); + indicator.setVisibility(View.GONE); progressBarLoading.setVisibility(View.GONE); attachmentExtension.setVisibility(View.GONE); progressBarDownload.setVisibility(View.GONE); } else { - image.setScaleType(ImageView.ScaleType.FIT_CENTER); - attachmentExtension.setVisibility(View.GONE); + // Content loading bLoadThumbnail = true; - // show the circular progress bar while we load content... + imagePlaceholder.setImageResource(R.drawable.apptentive_image_placeholder); + imagePlaceholder.setVisibility(View.VISIBLE); + image.setVisibility(View.VISIBLE); + attachmentExtension.setVisibility(View.GONE); progressBarLoading.setVisibility(View.VISIBLE); - placeholderResId = R.drawable.apptentive_ic_image_default_item; } } else { - image.setScaleType(ImageView.ScaleType.CENTER_INSIDE); bLoadThumbnail = false; - progressBarLoading.setVisibility(View.GONE); - attachmentExtension.setVisibility(View.VISIBLE); attachmentExtension.setText("." + MimeTypeMap.getSingleton().getExtensionFromMimeType(data.mimeType)); - + attachmentExtension.setVisibility(View.VISIBLE); + image.setVisibility(View.GONE); + progressBarLoading.setVisibility(View.GONE); + imagePlaceholder.setVisibility(View.VISIBLE); if (downloadItems.contains(data.originalPath)) { - placeholderResId = R.drawable.apptentive_generic_file_thumbnail_download; + imagePlaceholder.setImageResource(R.drawable.apptentive_file_download); } else { File localFile = new File(data.localCachePath); if (localFile.exists() && ApptentiveAttachmentLoader.getInstance().isFileCompletelyDownloaded(data.localCachePath)) { - placeholderResId = R.drawable.apptentive_generic_file_thumbnail; + imagePlaceholder.setImageResource(R.drawable.apptentive_file_icon); } else { - placeholderResId = R.drawable.apptentive_generic_file_thumbnail_download; + imagePlaceholder.setImageResource(R.drawable.apptentive_file_download); } } } @@ -393,9 +398,6 @@ public void onClick(View v) { progressBarDownload.setVisibility(View.GONE); } - image.setImageBitmap(null); - image.setImageResource(placeholderResId); - if (itemWidth > 0) { if (bLoadThumbnail) { ApptentiveAttachmentLoader.getInstance().load(data.originalPath, data.localCachePath, pos, image, itemWidth, itemHeight, true, @@ -404,9 +406,11 @@ public void onClick(View v) { public void onLoaded(ImageView view, int i, Bitmap d) { if (progressBarLoading != null) { progressBarLoading.setVisibility(View.GONE); + imagePlaceholder.setVisibility(View.GONE); } if (progressBarDownload != null) { progressBarDownload.setVisibility(View.GONE); + imagePlaceholder.setVisibility(View.GONE); } if (i == pos && image == view) { image.setImageBitmap(d); @@ -417,9 +421,11 @@ public void onLoaded(ImageView view, int i, Bitmap d) { public void onLoadTerminated() { if (progressBarLoading != null) { progressBarLoading.setVisibility(View.GONE); + imagePlaceholder.setVisibility(View.VISIBLE); } if (progressBarDownload != null) { progressBarDownload.setVisibility(View.GONE); + imagePlaceholder.setVisibility(View.VISIBLE); } } @@ -427,8 +433,10 @@ public void onLoadTerminated() { public void onDownloadStart() { if (progressBarLoading != null) { progressBarLoading.setVisibility(View.GONE); + imagePlaceholder.setVisibility(View.VISIBLE); } if (progressBarDownload != null) { + imagePlaceholder.setVisibility(View.GONE); progressBarDownload.setVisibility(View.VISIBLE); progressBarDownload.setProgress(0); } @@ -511,8 +519,6 @@ public void onLoaded(ImageView view, int pos, Bitmap d) { if (progressBarDownload != null) { progressBarDownload.setVisibility(View.GONE); } - image.setImageBitmap(null); - image.setImageResource(placeholderResId); } @Override diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/util/image/PreviewImageView.java b/apptentive/src/main/java/com/apptentive/android/sdk/util/image/PreviewImageView.java index 5643c64a5..8e7c140ca 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/util/image/PreviewImageView.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/util/image/PreviewImageView.java @@ -1,12 +1,9 @@ /* - * Copyright (c) 2015, Apptentive, Inc. All Rights Reserved. + * Copyright (c) 2017, Apptentive, Inc. All Rights Reserved. * Please refer to the LICENSE file for the terms and conditions * under which redistribution and use of this file is permitted. */ -/** - * @author Barry Li - */ package com.apptentive.android.sdk.util.image; import android.content.Context; @@ -14,6 +11,7 @@ import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.support.v4.view.GestureDetectorCompat; +import android.support.v7.widget.AppCompatImageView; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; @@ -23,10 +21,8 @@ import android.view.View.OnTouchListener; import android.view.ViewConfiguration; import android.view.ViewTreeObserver; -import android.widget.ImageView; - -public class PreviewImageView extends ImageView implements OnScaleGestureListener, +public class PreviewImageView extends AppCompatImageView implements OnScaleGestureListener, OnTouchListener, ViewTreeObserver.OnGlobalLayoutListener { diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/view/ApptentiveNestedScrollView.java b/apptentive/src/main/java/com/apptentive/android/sdk/view/ApptentiveNestedScrollView.java index 54f6ed98c..985f5c3b9 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/view/ApptentiveNestedScrollView.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/view/ApptentiveNestedScrollView.java @@ -1452,7 +1452,7 @@ public void computeScroll() { * * @param child the View to scroll to */ - private void scrollToChild(View child) { + public void scrollToChild(View child) { child.getDrawingRect(mTempRect); /* Offset from child's local coordinates to ScrollView coordinates */ diff --git a/apptentive/src/main/res/drawable-hdpi/android_textfield_activated_holo_light.9.png b/apptentive/src/main/res/drawable-hdpi/android_textfield_activated_holo_light.9.png deleted file mode 100644 index 1aaa9aea3670e006a4d9ae69de2162747c2933e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1129 zcmbVLPiPcZ7$2%F8b}GXVALL-V=hW|=e?QT%?rM)yEo&_UnkU+(QZ<5{UA>`13nfHBf zzTfZr|II-E`PP=>EgZ+S7W#}bJ5RG$JoFL!{yw?6#ExS$H%x~}mDbGwbG-A(^N|K-^piCwcbBJPsStP<~kD5`!3r{r}3>;d4<5P!tAZ9d2$rR1< zEYh76T)$M>CHBHbp;*a;$n*u2go5kFd2L&Vw2a?{v8Q!dnf9?z#vz#sEY^?esV11! zZhuFyA&W-65IC$U=7d44DHnURU}SmrCuuvj3XuX4l2cF?VV8oCqN9{9rNoSpQ;;O( znjCv!bBbh$MoL$7jUjVLQIx!9h%nz}h`N+VO>Dsnsp(m`>DOU?8(3{$tf~jtq$H>i zGSQrXfiXf!I7WP+52ZoLv>Y$i8H(>o4$6U)=fQ#>BO% zzS;Iw8|aPx)MM*?KRA>d|o6n0JMHI&~5)<5@Ai?OKG@u00+j^AU$t4i{FXABtFAMRKgBQJu zhn#Yp(-OSy+1(}y$w`o)2QOJX=^=-p5D1!GKi}DUlQ%WpGu_p{hS>*Ss=E5sd*5$Y zP5-Fw8Jud#j*gDj2>m(O0G9&ZqkJ=f;?zF@e^LG(@H6Fu!C>&5a=8tW7r-{S2VQ_w zQ(whUtP4x08d95J7yJvFHpNuz%_f8o>I8wrW%_>$G<9P;qTyGNf!~0p>>uE7ps6g= z^nMGx4>avR0YmU9$m8~a_HUT(8D)2d&~>l_VmqWE1J}Sisf^S⅏j7_=MQ{z|a zN206XS;Ro3?t+gh1uNmKm?3s7TpX^J2$AkWf}7wa@V3XsXX#PP^;8a^T;9axX1NFz zya;+0jC>~QPe8jzIESNhhTIer6SuQD?$w(Jq~FuSN$BIsKE?U!(VFR@+&~<>iDUA4 zW6X>I8rfLv9ok-RhI)DwaRB1tO=&ci!x1|$n z!XPQp-m0C*=&2KfKO5h%;LBRV*H3S8FLy%4Q8yL-I=jzy@4wka2U;9~xSC1B;+qqk zcB}`bE*L~-?SLnFp zJJ8_o$nNLT#c9ilJ*3|H?P4yG5{+ZkTVaaF9wCYl(^R*u+s@d5s+#wv#e*^SFKKpjc_~nl5QdKLTdMzSTmc_B8eyh&MEGl#e9%z%_i} zox85XqfxQqPt1!>-+>yQx`y7KjNs6?*dX}4)Av+@?UJPSGhL5rAk~W45c`Z1{32N} zLEZqT>mDFtv?jJlaOEitN!_gc1bzg`qUqbJ*dTajN*|Ee?Bb#k!%<7O5^I(un$E3@ z4T5J*T9q$Lkp02bhO(0AuEYkxL&tS|SsJ;9>x)L%_R}XxbeCd-;OkD`NGGjZuHm)` zDpS(0l4$%pnZ}+wId40Cw3Ut(t;4|U`qRC@uSNOWIfgRU>hZ+5%@5Oy@O#6#qGq<^t&q0}@!r<`3Fxs=ar zYKf<@MLeR%qAg+9Vv85?bhKf$Ys@HXEz{CJ7Tu}Xpr?45HaKiL!8&=>T8MX|`w$y1 z#OHtG1<6KVwGi(H=JQ518e@Y6*^)%`23v{W2|xJ~^*TgWz>WS1*&z_NlDy z3-KWOv}wYu@piB@%WKTHdvPtK=@Zfa|! z{q)vIKLMRzrZ=%v_3Cq@1_afb()02|bSeLe Z_dgQW6ky&}Q`P_g002ovPDHLkV1j3}$^HNU diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_generic_file_thumbnail.png b/apptentive/src/main/res/drawable-hdpi/apptentive_generic_file_thumbnail.png deleted file mode 100755 index c65a3d318b42689f3b0d17d5a9eea2b59a80029a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 978 zcmeAS@N?(olHy`uVBq!ia0vp^RX}`|gBeJ!KP&PUNbL&n32_C|H*em2@ZiBiFld^- z;MlQa_wV0NtnC7l4O8d8eEIUtn>X*?y?g!oHBjXF^XJc=J$w81?Wo;-Py-q=?? zarWwMd!9ahdiU<#hAH!aMx8x>v3~O07cX8sdi3bdojcdAU0b?gTV?;uw8q}sw{M?6 ze;#PX(W6ICo;-Q#)Tt9EPMkS&2I!277cZVZefsR#vq1LMt5?sRJ9pv2h3nU^-@0|{ z(xpq6FJHcQ@809bk8j+#0dcVTjonXyO6^L5{DK*rx4rwnj&u3{|Lgw)!B!A~6EFg0 zn2=FKQ33L>o!KQ4Ti`|91hs{hwZuT8eSR=bAj^>671 ztp}K^YO3lsUVnY~=-$2iBhJR;MNeZs#-cw(-q1#*?}pZ|B)x6P6V@JF@c3Dhw7yQx zWWO2RxqtGzi;Sk4-AcQhbU8EibLNejsM|GCX7jI^%@>>PpFP|E@UzReo?YJXbIUd$ z+G&zww>H;~7c7%K+Z(IoZP~dyFO)f?pH1DyY?ZFJVeMs&S5LXcZ}Pox*%-3#K$%0k z_SLAp7jt40ZZDgxx&FqxlIr?Z+F#l4K3rkE&1Z3eM(i5jU(T`dQVU+LF@JmJ?d1)7 zvkEuHoU7Y1#j0-g)sz=4ZF5(t?78)5^{y@dF0L^ybXc5XA?3R_=g+O6x9LCsl>f~;J&!UBYm&O*ImI<-{kLV75N?xTX%p%|E!_zwle;9=ElAw zQ(qrm(C>cTBUE{rIEJ{qVmc!53!TZkqR}YP~g^*!K6Ok`ZroOvvi1GfZ*{ofits zbPL?UQDS#~Y2xn!t*Os1ZwTi2G7sooF4ynXcD&YI-+nX96|?@cdhc%?9|fKT3KdT; zuK&Np^5Fh86S5vMA6nBmal`Jr&M)d-%DL6wT7LPZ;+N%rEq2+f_AhF7TYNFYM5>oW zYM0Jkwb;y^-naa#eAX>}>1_0Gp8mR6&mF&~1lM1>s>`48x!SU_Vb8zay*;^}+jC## bf8$eqeLb+|{F8oQ@@DXK^>bP0l+XkK@L(|} diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_generic_file_thumbnail_download.png b/apptentive/src/main/res/drawable-hdpi/apptentive_generic_file_thumbnail_download.png deleted file mode 100755 index 2f5471be18eafba07c93a479ffc573f5719b5501..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1078 zcmeAS@N?(olHy`uVBq!ia0vp^RX}`|gBeJ!KP&PUNbL>q32_C|H*em2@ZiBiFld^- z;MlQa_wV0NtnC7l4O8d8eEIUtn>X*?y?g!oHBjXF^XJc=J$w81?Wo;-Py-q=?? zarWwMd!9ahdiU<#hAH!aMx8x>v3~O07cX8sdi3bdojcdAU0b?gTV?;uw8q}sw{M?6 ze;#PX(W6ICo;-Q#)Tt9EPMkS&2I!277cZVZefsR#vq1LMt5?sRJ9pv2h3nU^-@0|{ z(xpq6FJHcQ@809bk8j+#0d(;4t-FC1m8D(<`NzH_$S;_|dE2}H>o}MH|G)k}5Nrhz zH~}M2h6!1AsjaH7|)lS}k&?y9y9-u}IQoo(>3 ztwKAppXWF5Gl`c}mdbuu|KRAs)+$T<*|6Q819L;SUw_9R0Aw>z0JGhFo10CiUBS zyU(u7H|2UCYWJAz-LmQa&e><(tbI3LU)Qv7d-PqCZ`I|Ky>h=^K2`Tt=!>7Vuj*5~ zgHvw5?YVGceXNm7vi7%&rXI=rn;w7Mp*ic#^mn#0KLhdmHcNCy#`-JfFFAi(y#JTreK2@e9$T&-=Poj73`RA?~IhwORH8zOI{_wBAUVp3V`ucD0KCekM zXlUHPE&HW{IbZ49eXgK-^@kaamzmaA|JTU`f|v6bEnT|wcR?CgMw)qpTN!gk3XxQE zMuK?FVdQ&MBb@0D7`f!Pm3r%Aa6UN|M45NEu>8xsqs>Et$ESfNoUgZ9#R zs6&3kG2E02WmC@u?9Qzm3`WOt4a+}mztD=gzXULu zY_13ad|@k<IgXJ{?E{v_5>T<_Hy zyk;~RWIh{ybBd<2=O52<3JbmX1Hdzel1|9r8;7YU$2t>`@KsCj!-9=#aML@mH-Px6Gp$!d%O#@&fyOpLtNS?%sF>mKkAZ>lw5N+>NCo54>8#skGl;O}%N%m)+`apKeg1ykFLUJipZLbG)h~Ol zGHGRr+U(*vF=mtfRE4{GW`CE-E8waO57d};%4T7V)+=FA{)ScYtIcPvE!%xH=Sp^+ zD8u^2d7E6s+QzeC`8V?#?!HRgYn^ca8vCv4g!2E}Eq(aA4kU7Y-kr?KlE)&w!!oN` z^Nr|4Tc7pkBFZ^tZ&SK-@4$!eSuYPJtv-<>e&KSx)`38Oi-Rv;{$$hQ`nX_$#U`!? znhQA2JUVHt&~w4KN5uachnM4ysVn;)pL(p7YHss#-lJ2W6y*1Pd3^eB!c@-oRnqZg zt1UQH4~Ex7+Nn%!x@BI(8|3BuS9&L3X6k}Zy)lhFn=bru%X12|%!vK}e-?L)-}M*M z#hyGlP^$8I+Upf;$5m#V-7Y(@&o-3z#0)*5%TF`8c!E8oCOICQ(zb>(K-Kw`sY-43 z&Op|PW4a}>-kqkR<YzWMfXVWI6S-s2kzw{Ac4E$yzI znvHCL*29LNPNM}k+!r%^|6nksl0CeC#<7F;RUSS|7!zjZ0aFEor>mdKI;Vst03hsF ArvLx| diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_ic_back_preview.png b/apptentive/src/main/res/drawable-hdpi/apptentive_ic_back_preview.png deleted file mode 100644 index f61e8e3e3cf82a87cd8bc76d9b55d82e49e9732b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 279 zcmV+y0qFjTP)w7c^cQ+BR|*P!78#H(k`Iza7CH~Qe9V{WBvxMkMW8td zSQtQhOs;vsBoR^YZoYtbp19+YF~U6$+;aUp&GSypKbjp~ zJMhL$Oth4XJQ`DJG=10=#_uZcD*uPnD^g==;{km-)h@RDt5yVrXWfxjE&d!;e;}Rw dCtLH!MBkKR0aNgwRs8?}002ovPDHLkV1kD%ay9?} diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_ic_branding.png b/apptentive/src/main/res/drawable-hdpi/apptentive_ic_branding.png deleted file mode 100755 index 19e5cf35f27faf7800961ebbd63b19fa8426bed0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3307 zcmV

5Q;P)Px>rAb6VRA>e5nt5I$lRC7DqYg?H zq0Xp(w6=D!MJo|2vZzE1VG&f8T2^tbTSbWr5mAsW1VWO2zSnmiH!r`0fC6^RojE!C zx#w=@-uHv}xGLJhg$vs!B_-X4NssvW_|wbE%H9D#yk^as=~JgpEv>?}M)iL>1M!vR zy?F8BYZ4L?{*Jz044aKbMMVP!4<5WNhOS2R?ae^^qD6}`5)%_!m6Vj^_UqSg`?nW5 zcBGgag38c|%J2%+ptjto4DUjJ3O*NnN+4UlcJ12qswxGWstfj4cwO(!$jJDs$JdZm z%)rv6OYcHGRVK{+i_D!rmlA*LEvd4IB=8Wr5#XEq_U$`ccG=n4DXm+#{te_EEOhT~ z-MVE#|4q7B4Vx*z0AI%-pHELuf5(@dXnNkfdC3hMHvEzLWs+Y3m7VAutUuPn_Tf&&kPYykyCe-c*NXd-m*^%w(Nrn?ZJ&nVCf-eJ6=N zBOaV79IH`fnlPC3s1Bd2qp}mtvl*@;x0eOer%$i+P@IUon2%iLQCeDhYqY;ZhYsC~ z>?LfLab@W69rxxYgA-GSNqT_Z#*$pJdWGM^=9qKv;K6$b4I1>Jp9wZk!4CmC`f{IU zQw@i&B^d)+j!*AEKN>tGpidV1`N`_o@0a;KpLzL-FZ1aE0|vYae~B+U-gG>hA(6#j zLt>&=vDGxv^{4u1(=@!KVi@wU?mp$FIPAf;>7%Sx``LQ{%>sQ|i{Odo%16 z*d}7Pjt%|$fddDAWIpsWinvd}+xQ;F)_pONXAa|B>e;5F8w=kKr~|!;le&P%U9Q;( zlgDIq`U?Ak{O;f(cq$J;`Sk^K=sx1KKit26|5ebg<>ux#t5vJk#C{9>88A>b@Q0YEiM-(snU65zyNvOT5{*sS?%lg@9XWF3Uahm@ z;jfr&0F8e=W1h`;!hYkq!>&j1AfN!6j7*Gn;Mj%06W~W7&nNI11TK*sK5Ic~*v(=B zuaV4eOi(NMPl%C#Z%JWcVT*e8>ZvN+AUkA#Wa4fTZH<_(L;qMjaj(YrexRl4h4K4@ z1-XQY%@>c)N>C5cwCm8{iBGB+Ysj`E>!EiG_Op?@$ufNe-;UjVLB-6&@A8P=*eBU& zr{n7Mrx8}~qu*f@5}mMzKc+O>NC8?BGV zzKnU9MC?swkE}2AxWss2a>>C*)muJm(089de|~cg%8SU)mORpQ`2S2^6TxMAL;Oqz zI3HlL#}S}_9dm$%{uf3n@0!3?R1sI&7|a>)X@GoY3CC!C z*x63+$wE>m7{8Xp*Mt|F0$CfbqG`rQ@FVC`H4fxOrbBirvirn?I|ngME!l1Za+I&G z%Q^VD&45m_Il$wM1fqm5zUFFenY~=d%o#Dy&4#-a7FfKxFo8c?;GwJJTu&PTua08X)*WfrU zihFH?U*_a}CZXTh6m#Lnv-1@wj={J`ApyTwzkdBP-_~e4*Cw*IP{g`*>sI2kQ#ATk zX=!P0!o{nh(@ynUR(^hdV@l^Ks1}$4`Wj9_%xenW-BhwB_%y=)5%ZzH!EEI7*zD&Z z8)ohU`;QSa5oDTw(t0>sdi{4+->(@~{l~z@qi_p>St9zLfoX`4<&)YBg*iEvJh8<##Ip5jWIPbH*hLnFrEYRDzeo9pH!z#oeFuNdz(D&QXU#J_xzub zS!L0IN)7yv3GLs%e-=3$44fO+uV3HZAX-B$vbCqleK#_HJUNWvJu_gApCQ)A;<0PR zK|5O&;<>=!Tm<*&b1~p6AnxD`aO@Z;VqO=N%&kre9Sk3I~k8pC&v7q56HTh9^BTW9Z8?%a%WSN zBHQNK#T>JzuaeaDi$VCPB_DTf1lL7h&)F(TI39Ev{#ZmKYi>T|*+wtmy8*owS`d5^ z3px?QT;3CpaV0E{Q~_5VaNNQ|udzTrCWd0U2Hl=b=1#WBJgk!04?agSVwS<1+TG>G z1o~o6-^$mCrixVXL2M^U@moiIV)69R%#+uL?%?rJvR+hxzZNXo!Z{$1{ZZx7^2C@y zKf~n*9;A0dqehMT!`2C6eaQN(5bci#T8F*dfk!4Y*P!bs;kbiOpssuZ=~31j&<-BK zYjy;`M1IbKKEdXgxo_XTH%MfZ0synIDf>Fi;lETDy+`a#A_b=I^Y5^cM^QenhIJdl z6KnCB`g}n9C(FI=eH;3z;DfA|XH&t)(}g5`@5ImX(CdMjp)x{Xw>BaYyDx?;6cJC4 z&2QBB(QqjnU@JjdlS6|REn4&;?qJIsxpH>vgZwMxE!81(9D#%&BNe5-=j{{@;M!=YyUv^fT<+1h zV8Mb0$bV=y#NBMPhs*g;*>oMA>*?PYO(iL1vxnj)O`3eY`k^H5T}VA1wVRVUFb^J9 zeRGPK;bW0;l)}59;AkF|cEuZGs z^gwi1OK@$>#6CPBkcbnW!)_yk&?jVA9iX4%^H8U_Lc?bU1G_;AVw`6N#Mr=i)`{l_ zr7ctlolJKap!4Ww9X3sot>WdKMU3a6d&wUB7x?QSH;M&1BGYNq7{bRLbhR43C1wb{ z*`vGDkE*aX$vK@nckW=iSXgs_y?$XyYZ_<<`sH8u4X$PVZdfIR$GgWqDz zI%Hah3*nyzFL#pyQEAiX6P?fIr0WIS7WhXjV4jrmH^$Fv_IusYHA5w6el0Jq) zFEg7U=6LWgfJ*}(Qy&%9m1Pd}p$Z&6e2JY3bORci%@Od7h@PK6cFp%?`gG_2u3Sbx zubVs=Ll!s_&{vZixAaHc5Eew3O;G^s@MRvYUlvyf@KB6*L1@ZmdCF`N{yRB2S)a3E zQq0+W^u2)Pz;@t$Ks*1!=s&bsP<)m{Yq7L3J_kNPHjBP4Am?&d+}5pI$D_ZOn4bXp zEGz`{fOMOf|M;_q-w!hI?~hC;=WXy#ARmz3J?O?Fx3&qH8$0qXCNzvrmCos@Vjr2D zyk5ipr|4b;3X$tjY=wT5t91`p<92??-!MPJY}~oBg`X)P)?^)E(;H?yTlvAR3wk}` zHOBt}`l0ayU=?tCadGh^@OP(C#$KazmkFRJRwpxTS9(6vs^b&2(S042oh+VrLuFU^ z2}|jyD#VG(ieiy+41Lu;2A?>+*pJ2Uc=$wq^En<}95Lp1azjuC{V$3m4nhWOqNDby zR^acM(RX!29Cco7qNDcto~?DYhFdd<)taX7kI_kg#Mo5x0v-l!?||(luL|Qcmda39 pHoTI*tje}VS2F`OGjI$u@IR!+EvZ1O*%kl*002ovPDHLkV1lrKd07Ae diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_ic_compose.png b/apptentive/src/main/res/drawable-hdpi/apptentive_ic_compose.png deleted file mode 100644 index cd9aa2afe02903bf39dbd51df8079309ef4ce1a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 420 zcmV;V0bBlwP)cKXd-gS@F*<{WA{>P%a})B4lQpz!5N!^qNAsgUoCPxC54fci>RcQw-$_8en=u z66FRmvvuIPi_9<}QIs1f2+ZspxQe7Fpmv8fHFr>#rVU9q1*kJg*VEv+f~IO_2{@57 zNuWZ6_9VTyfJO@VD}nN@p-4A{7av2Nrdt2kDNA7bObk(LlHOeAPyuEdb=()a%cQQr zg!8i#x<}5GGA~R(Rf9Y+)gW(76{rQK7}N?=1Zs)Ng3N3ixCd5pt7lDX&oqZROxW~R zTVbLR`YX&R$jr8Yht`paPHHo|1TI>pDY*|7f?DUS4^y^V>RTCiGlWka1XCrkD3`CQoVk7)J?L>ybsJhe-WWvguVgT<-H}y?pVSA O0000Px$R7pfZR9Fe^R?!WEAP@xyYdV9j&^T1nj-WF%b}uQ9aJ3P79GFV%(xDyz}8BVRmC~$$3_+lgLkO#zw zQ%;p&Tsny$1m+~jiS>J42B{#as7+#Al0}>77ne|>zCH>VHIq8pAZd<61dfWr;#M(^ zgR*3ffv8V>i8F*Rap;X*9}yO|hyk9xhY+y$Q|i#6jw}#^V}g^vDC(#f|9#v2wdcgp z$5s-9QLLaNHfWRW@LY!|*b&22}^D1OMc}3&_DX%pD>d{r~^~07*qoM6N<$ Ef>gG$E&u=k diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_ic_info.png b/apptentive/src/main/res/drawable-hdpi/apptentive_ic_info.png deleted file mode 100755 index 0a864c690554cad785d47788bed3ccce41e6a7a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379 zcmV->0fhdEP)ed&2&Bk{XVG4?N=<+c4+^GuXy;Kz{a)Q5#Lu zEsig!P$#-ocqty;5mdj?^w1gV(?Rbis^QvXhbz>_)bqM{?(<4L+>AQO0fQtGa|&a=|mqQX@*`W>}H%Spu)8>i;bH znFM_Tx27W6PG`IXZxd()C{iOkCY`yJ;8y}=#hBQla%tyFpNOZ%iFj&6?5T*T*u4Cl zh?k!?Bq!nx$*)K?F;OM2i1wvbd`8qBHl?SQJpPtG{#HExQ;egn;p0eiKq`!E{ZGUK ZtZ#xNGl~$(d-4DP002ovPDHLkV1nB|t6=~D diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_ic_profile_edit.png b/apptentive/src/main/res/drawable-hdpi/apptentive_ic_profile_edit.png deleted file mode 100644 index 746ebc61f0078d2fa5477ae334cf6e0afebac4a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 343 zcmV-d0jU0oP)Px$5lKWrR7efwl`#s!KoCV;YYkX>0l^cb)XR7v42pPghjolZ^UdG5drWZ?RS#^PK}x_=shAy@+|G&l6C7_%hm$$jF5 zsn&$=gd~-qY0Ql0v}u%8=cbWaO6Jy3zLM0l5=;EeIoB_7&)e=dGA8FU*asMyYkdZb z0E3XVFInC}yPv6SFln#Rit@a7(#}y)nEdzkYbR58b>$RHz!;3c02JM-F28^yIDjqK z(9PoQKsW^}a0j8G9Ob4J2gp8Hf>8gILr0p4nrZ$)#vaaf9Gs}xZ@;}t pu`9$`26=^!Ncc|EC^oGdJOIM8t$s8N4WIx3002ovPDHLkV1nB5k}v=O diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_ic_remove_attachment.png b/apptentive/src/main/res/drawable-hdpi/apptentive_ic_remove_attachment.png deleted file mode 100755 index 808dc7ab08d130b6730640d62c6ba4d5f74caeda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1252 zcmVKc9+xa}@%8Zy17l{aQ5mQ;Ww6CZ`E@`BUw2?8g5xACC znPg|u-l9-MFrmbm6)RR$eDTE>YmXc`a%Fve{X;D+EuVCBbQ}f#<{F<-X4|%Hl@h0J zA}Z`78kGzLvv0li*222Fx_eBh%_x*e8+G1%^UVds2!uVN2K4)J&|ct$mop zJ`jUg#8m89SF#RC4YhjlufP7fz*jH|F+;tpsZdkqI&^6M*s)_b61X=YHaW=U z>e((O8yXs3Ctz@o8}g))w{PtA3fAk8i=5;xHU)}F#*NI+KmU9V0s0bhk{gGp zY_TCPud1q==n8oF@L_jSkGkZ>Avy)3y_qm7Y#1KsEYQFI{#&^8(n|{uKm73jmZT1K ziQ$+658xn|vSOk!BYoqIH_mnS28pVxtD$sRNva+(oIQ&JE;t3Efg~i1$^!=u++J!z zr>sXE9B{!Y@Cy%nc`lb5*52OU=8@Q25^%r;r(pQQ!=AnQ=9^c!gE$4eB%|Ph6K-MA zgfZy*@4vs8LVmLTl7I_NxP?Vi#xVOf-b*1*S#L?e1t;9XqUFY@qeqW^NFh&IZ%M!f zC)@(jGTjZv+Gh7Ch5TgwB>@+l{r1p6`7+@m(Ogt?{QK{}f9*h7o^Zh_Dw;9ISin64Wx>Y`TZ=ZaLtR==4!UEtzSo{Oq&O9S5zJ2>ypM3Jk({`fV z-qh4o2na-ghH$O1u@MTCwJG#8b%~)^3l)2$>)ffU^U+wSXNMb;j5)?qV~w%V*n0Zu zr=RoaqmSNT63^Mz>?>O*PXK>&jn61US=Cvi7;_YJc&I01C7h2sdp4^{K1Mw-SMzG6 zu~q`~(v}FD^x0aKrOsT%7^9e3S5LY{i=Xh7YuOm4XPGIwgUr`FTV||~5UkL(#VRw4 zI@DE+3dM{&CEcR#vwS5Ps%_Xf4IvWKjOk*Uu1!*zQL0nnIJ@t@sN)q*xsg@k!IBte z3>U+6jn67nw%qaRrnlbQX-be-FUBO27UjB@R2dDi|C>8MX*b^QLjMB`=|P`~tCT+g O0000_M@ diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_ic_toolbar_close.png b/apptentive/src/main/res/drawable-hdpi/apptentive_ic_toolbar_close.png deleted file mode 100644 index 0fd15563a263e138b1f419e02a807ff8c40f2554..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;Lb6AYF9SoB8UsT^3j@P1pisjL z28L1t28LG&3=CE?7#PG0=Ijcz0ZK3>dAqwX{BQ3+vmeOgEbxddW?IB4!nj``h+ZQHi3!dZp0ZQHi(yYKvDeYOf`+qU_-YR{L+=I;itYIZltr29?J>+V?= zQ-p+s1ljF!X+cnXh@v)M6jc@X3zDSXl_c#IK7YpNm-u`KOa5)|RyoF=j3*?pM4u>NdGXiW=TiPz;TdO_7d;vP2B}qzW zheK;D2udw|muka#Q_Sgx-{;}8g6C&$$mSv0W6m&k?ASnZY>?dkE6>$$U>2Gu}z1_IP)M#N(OlB zx7+P08Gn`PHH>D=JJ6-0bO8DL9O4S248_B-|4i5w5+WyO#t>k$$vI)C3N;Hj9fy6=?r>H){>9}ep}7zWy_YuauJnakf{lBi>Ouq z?SQj$vq)+bRenRW#|O#C-#DG6#r%_u_;D{)1;zm-1I>Z+C+2FgdY8^Ew0NFe;A$%m38m=&M|qG%X&{DE{! zr3rT%zTGgq7 zL3Ar*@CEn2%tC|_p;XT3BI%4^R62-wBfWBX7iibj;d}*l;}*sj zJ$k4b>Q#JRfE_B!`~`v_kfa1RZGH zJSc_eha}$uL?#=I@D{2<%wGUP<9LM81vmJNFu#&0Bb`WM4ZmjlKH@|EBD_LBr~5Y~ oN$IC+c!_z!UIbcxRpudl2LplU#OOwzxBvhE07*qoM6N<$f}{428~^|S diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_icon_server_error.png b/apptentive/src/main/res/drawable-hdpi/apptentive_icon_server_error.png deleted file mode 100644 index f7ce1d27acab9713d1cab305cde01e6a810dd934..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 936 zcmV;Z16TZsP) z(uBJVq|pxTAt&o(Baz5QLZpVmiXf0FAP4dw*E-o`GWi-Q=|VUUWmy2^c7Yz~v*fdC zIfQ2$(37#xyRP>S2|C0lU=HYmUL(SVg{n4<_Nxqq)&RZG&m`>sYo9QmI4sWbVf!v& z=qljz%qW4ukb#mbg!P1olxheahd)d#TTH_w_&hbL2;p}%?8-etsQRw!zNwQPkHtYWjl1+CV(_Rn#OLUEmi~ zOWa^u_(CM&e;Pyz_gz<(l~Vqp`zRsQf83N`tX4tsV&KQK1Gv0^!B?b+!h0K|QTbi) zz*n1@#5)&h%#Il7uEqh@Yot-8f=Q=la3jg%xD3niN&7VeESJ!QLiB=#ag+vMM@qki zVVGMbrSggbey$m?M>OscG0@u_T{MADn%yfMHKcd(<*D)7F1477`vepAYZ=N*INW&2 zz-f|QT~jW6LeF-a$OT`JKAHvVZq|jlcwBu+Iyacg244q3+cM#kv6%mj#)m7D(i0i# zxM|(eE0000< KMNUMnLSTYq)xoj= diff --git a/apptentive/src/main/res/drawable-hdpi/apptentive_status_gear.png b/apptentive/src/main/res/drawable-hdpi/apptentive_status_gear.png new file mode 100755 index 0000000000000000000000000000000000000000..770329aa937c802a15aecdc8614df851e6eeb59d GIT binary patch literal 969 zcmV;)12+7LP)tXMy-TBU$@0@as`oqA?UVE+mUu&KiZMj~5;y>b0s^d1R9yZsgGFc0(5pOI}w+f)-8${ad^ zFYy&dGqNqH9j=4t;xXJ6ui_Y7i2cgrJ1j>R7T|hZm0ojMGTnF<MAmrUE*d<(h7VqGw zDug=lLP;`va3kjA*y+Wl98#Mxs|ul|*jJL!L0s3w-o^~6eK@}vi3{)pe$klF#^$I{)raKeQ}m(;KjO>+N2X&{bRvzyA>5km z+c1g!H?u}-*io?gS1e2RF2vnfkBi0DfNO-WC&d@&i1LdjAymh_lu#GmE7<%7TH?M| zyzS3OjNn1c5YhFcp>62N3;(qmd)4|xeov0EKav`2GO|55I?DQTboUEI zxV0#;+wsvPgkCQ2aIY{QU7A^cM4XLqdyd|All3*BfevPr1`>H6ewJVC9>N3h_quS^ zol)<2e4eB84Q3XRISWr?ETc3gsTo+N@mdLU(vC>>MI0OVw+M66p&Xr2JdRVcWX={6 zvdY2ce&u~)QSBnQWLtV_Zi37SdPJ$`Mg~E1uqSLGK%N)ewWX~<~Ba`Pu zOEyZIN+`nGM5hDq$MxMfFOglM{0OryFNe;>t9T6`$iEIkYq?EqjzYrrV@3SC6;}x5 zpa^xL6%7b^dvZ}?*W%APiYqr^@_SUA`Xqxq&cIJiBC=EXVr$Ag0-~2sG%0?#Nah6RMW@OlZu^=Nz!da$*G4k3vbR3Wrn$dxh}7xHePmBghbXRG~K%J ru3M=}z4?d4S};3jy+=A9|JU(57y4tr4AF=j00000NkvXXu0mjf9p}wp literal 0 HcmV?d00001 diff --git a/apptentive/src/main/res/drawable-mdpi/android_textfield_activated_holo_light.9.png b/apptentive/src/main/res/drawable-mdpi/android_textfield_activated_holo_light.9.png deleted file mode 100644 index 622c6849034a7263e9e1f60017080021a425915f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1099 zcmbVLO=#0l9MAkh#-^U8j=|ni1d+9QFKw4JtQ%|7Xu;0W6;=hoG0x*8UmFXm@(z@8B9S1Pg_o!|N7_&4=gjyPbCYm;AU~nIwZMa>37tvvt4@^*6Cg`G43aSz zHQ*2gLnwyg2}zO$fd~;4peP_QiXmOD*DnkWsIYIhy8~r>h~@ZlSP7?D(xj zv6Kmc?g}Ud1=|keYFhiWi2t~;uC-s9cd<~!KAH0jR*!0=4Q9Ffw@_%vyipE$7AuNA zs}f_*#tzM^X`cOwnU<-*qzn;~5>OK1kc^O=MTu-YA*R%vjNsm~=g@ymbDp?Qflz1gVX4@SwQ6rT2HR6Ko zWD*o~!*arNSf15rRqR4cG$#tY&5P(kN2^$I+a()O2PZeF|hsD`O4*v zNcnrC(M3C!mKxW0eeTktw-*Mt`TZOGjYp$q-;17GJ(rHi$3NUXS9-A0xc`0N~ z+M_Ec-X4aZ&fGw`k*E0O%B!Bivx{c!=Z<$5dcQn>y|=$|_0CdPu( diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_checkmark_alt_40dp.png b/apptentive/src/main/res/drawable-mdpi/apptentive_checkmark_alt_40dp.png deleted file mode 100644 index 55ed6db6b87149e100725c47f7fc7649c90e3f3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 940 zcmV;d15^BoP)Px&W=TXrR9FeknZ0WiK^VrfC`ceFViC|n(1U=roz(@jQc%(x{{$flmJ6}feQsFQU-$CIId{zubswk$#rpR;62ZhF1Gv~w|Q`c{( z7brGV4naAaXA+|n3Ua*Ni!v{$a#${kEcJ$}RSfh(=r^aw+S|;PGb@+nRPOp0hk*s? z-qz^9xw5Eoo80wH#j>ps-nt(Qtd~YSGzKgVKB!(8+kR$w(1;W^^v1doXdsnmTB6Mz-?!BFu#srqeyI`h%Zesq+0ERzW`-xK5h}Fna8ZZhw%h7Uw2_lFrBvRu7E$#uPfm1&|LvjEiTn{ z1$+-ag#BCr6Sx3Ewd3d(!tLEugCQSnspBh+BJ$alpc$-lC((ucH^hHYNZ^J1g>?V` O0000!@^(y diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_generic_file_thumbnail.png b/apptentive/src/main/res/drawable-mdpi/apptentive_generic_file_thumbnail.png deleted file mode 100755 index 1494e5fec50713f77cb8841a0d5dcb8b7c49f4ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 699 zcmeAS@N?(olHy`uVBq!ia0vp^fk52H!3-qpEJgkSsnr2KA+A7r=gysX?%a6@22Il! z0OVch8?cfBW|Bix)4RJ$shhHmQ5=vh$ZNXEyi0 zeEIU!*>fGU7w5E2eEs_M-Me?spFe->*s-HWkDfSj;?${ACr_R{ckUd}qF1k8UAc1Q z%$YN%PoF+}_UwfV7l4A-uV24$wD;TdvVZ3uf88th_nd>lm(?4- z`@SsrC+D{4p83+tlD}$uDj!bnpYm#AkZsT^cdxG=E9Eq=Dle^CBGNzQ6E?xHV?SPB zD)6a@pYE1yF|#UCs>h?+=;oc(mom<2X*A0A4`uUKo5CDGU6a;)`GN_y3!k6Y5rJ_~NVTlDBi&BhHTLH9}`c-Hhz zna+3m>48TbAC?}ju-IZ1G|y_^$BG@Btdy$W2ym=nQGU9zImzYMjiX5$uSOXLy|ZdL zoPDz6*}lVRizPJ=cepK{y*6V>&$}htR|)>ikZNtpS>j_p+xKBdg7N(MJ}t_rcJ_0* z++CU;O}zAYVqd|(?b-6I42Ky64(~Fr-xcdAaVMBffn{EYi_%076`@W9HKQBMPuiXC x9DDf&-+h4!Klj}ef^}=ZPdYy1)3JxF^6tLs?ho{KUjjxegQu&X%Q~loCIG^3hb#a9 diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_generic_file_thumbnail_download.png b/apptentive/src/main/res/drawable-mdpi/apptentive_generic_file_thumbnail_download.png deleted file mode 100755 index da9fa73bb4df091caf975bc1f9034067ebbe1667..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 777 zcmeAS@N?(olHy`uVBq!ia0vp^fk52H!3-qpEJgkSsdWK9A+A7r=gysX?%a6@22Il! z0OVch8?cfBW|Bix)4RJ$shhHmQ5=vh$ZNXEyi0 zeEIU!*>fGU7w5E2eEs_M-Me?spFe->*s-HWkDfSj;?${ACr_R{ckUd}qF1k8UAc1Q z%$YN%PoF+}_UwfV7l4A-uV24$Pef?T29lO%x&a*eJQ*5-YTFZXd zstG;`m$`L*>x{-LGFCFrBwa=7o?Xb=ctWe`ip-v?S%qh`7X9dTo>#8Ypd#qp`mKtjOv z34hksud_6o)?77{Ueuv9U#CfD>I$VGFPGq_`oDI&3c8AXj4~_RD&#oJ(OPf`=N7@U zDh}0xOBlC^IZ8QXgBaqbD;=9wc=8Il_-0K|Xu6`{&9c&Q8i$ZVFiYj%WH(KvY56LT z=2xw86$x|!8izu3pL*W7PwSO^jpu^ptA6RHgyq?>Z;DE(Jj!&Sf0Mj&XS$j2PhbjR N@O1TaS?83{1ONmKnv(zk diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_ic_action_attach.png b/apptentive/src/main/res/drawable-mdpi/apptentive_ic_action_attach.png deleted file mode 100755 index a262bf9256f43d0e5d231402119bc56dcfb7b434..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194 zcmV;z06qVSP)1|1D4p!gQeWi~rT| z*slcCvJAnU2sB*{%#!=R8{JtDH9%XQ!8HKgz8T8e4K%42)j`-aeE#19XU)RxBtkYI w;7o|83Ht#vSP6#`0uUV!B*!%Asb&-a0Nls&8iP|wu>b%707*qoM6N<$f;a?Jf&c&j diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_ic_action_send.png b/apptentive/src/main/res/drawable-mdpi/apptentive_ic_action_send.png deleted file mode 100644 index 25843d1d0070d54e2b9a562cf567ef5ce9779863..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268 zcmV+n0rUQeP)Hd&#wCEg5qhvule}Q?4ar&BhqE%q{)dy0-e}dp?OjiV0$o`%S<# zutPrj;sFmXXvIT3;K>5omq}} z@0c1azMDw{J3`2$jv=;qa7`cnpFh{di3oCOVvLRFc2B6m^67~UL8MbjH;bI{(Hd!Q z<^cF+Q$C_=J)jH|kxM^ZI{`(puW>;eo}zzghXSD=%M~z1Eb8i(^OyWAD_bNotA$EY+ghuHUu&{;z*V zxB7geue&!iW)^g&TCaQld*16CVseX04%o9qJ(Np)GP!V4T4ms~$XQ30$hYoTxa#Dx zw;!CZo2A4)oMb0u;kP46%F@O5pMic%?wx~iJI~fXi{2r>ahq`8j7^w{R`1!{&p)gRofhOUCjwO$a{i3u4ye2MKc<^Xfc*N}qndyrxUT>|p72#TDAi{clbEENLi^8KJ zOTO|++(;0S*O#H{b8v&aZtcwT(?jM13zv)G&N; Wc8i`r!$TA3Vg^rFKbLh*2~7Z}B2=FM diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_ic_branding.png b/apptentive/src/main/res/drawable-mdpi/apptentive_ic_branding.png deleted file mode 100755 index dafb0f11b5170927267f6e199a7d3814a0e2c5fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2057 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 diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_ic_info.png b/apptentive/src/main/res/drawable-mdpi/apptentive_ic_info.png deleted file mode 100755 index d7e6239628c2c68c03ee4c421425dd9b5f59887c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmVsz+0rA)3doE`$F$61dyJ7|32(}!9)a!3m*JkAc@RAd4L;! z)gPIlU2GuNf)g?bxcmuzoivxjXc{Q_2MLUtn}jS)n#m}+*BaZ?CPB4Sm3vY!Dv=UO zbS-8Px#x=BPqR5%g6lCcfKFc3v;#(+#g#S$qgVZ1afL79pPC?OpyVBRN|5?vf877`~t z`|SMtKG|_D5g~*M8t5X*tAupAB_X`PhW3_C5b3nJXr@P+9V*rKTy#e6Hg=5nJ!~UPPR}Q9aPi)^%tKIE!yVR! zwDs44Q6M1{PF{~%`8)x@l*r=0000>#BB( zwfl~Rg??!omSE^L5%Z!DAy5!jLJ}>BR)GI4c}(c?n1q_hK;XW8`#QaQ_ilMjP0byL z!|~MZc2@!X8{0m8`m`K1EH{)mDxoGzU%7H+`@+J)V;+ykP5g_18@1>`ZzyRnnIL3# zcJ?Tj%T>lfUQnMEUapHaU?AbzO`Oh?98E@adJt85QCPkM2 z^6Elk@ZiB6oK9!JGB!3gMid0AK^8KRt%UmQT7CKQ<%oY%et!PHOP4PFtF5gKDZ?0Q zQ0qU2Ok}HBDxnxTa%30(vk`lZpkv35g_J58*94oX8`*H^LYbGBw>b3P`%5E_=^z^p zCB#(Q{{H>@1_q;)MlA!#hNIcVQ|(k)S@{@)(MT^`xB#M(0c69`?BX-1yJ?!07>p!U zA{IxK0c67gmlF1LI2=`}5+WN8CA8u{rKP3MQnjSWW}#IHd(hM1VX96VWW%9^g6MkY z%$e<}x-5_l2V6?nk$&UdZnr1d7d|qP4Tln1h&IGvo6UAU*|#=iBAXo+b*D)udbVoS zYAWqvRkCj0$U-Kv*^#C{blVfdSFBjEfgYkhS_(A94fXq0uU@?YnVc=)(jQNfFV1nN zPMz8rrxYSQmVC%S7H7&}&qKlM+>e;Fc=6(`bZn|fjF6~As6`KYk%27E6uMBC8bmuT zoG64?n39@L@-y`0fbJ$%ExL|M78FENIgA*EcrfB*hH zcDp_M$B!RxD=I2#0RD|_7()$exu-8@SXmbFHPPUu=*Fk?SYjG6o0v~5VCM6-Xc}J&gBNU+^{5nosYJL?@;rZ)?ppBKlYT j=)W<5!H8(TDHQ(!NAWK`cB@KQ00000NkvXXu0mjfC9-`F diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_ic_toolbar_close.png b/apptentive/src/main/res/drawable-mdpi/apptentive_ic_toolbar_close.png deleted file mode 100644 index e80681aeb7305ab08c1f55df7edd35fc9d0eb171..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1g=CK)Uj~LMH3o);76yi2K%s^g z3=E|P3=FRl7#OT(FffQ0%-I!a1C(G&@^*J&_}|`tWO=~G=WkL+ z@9E+gVsZNEWNV?r3OuY&?=Z?L&Ho)f{7Mm9$xa9H@#qTmGi6+RV TUAFrSbQ*)FtDnm{r-UW|v%+BV diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_icon_no_connection.png b/apptentive/src/main/res/drawable-mdpi/apptentive_icon_no_connection.png deleted file mode 100644 index ee02385727839e2921130fb1c51a91e25d0702d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 595 zcmV-Z0<8UsP)<{?KC%i5~)Zo@irDGim|!v5nyY zRgJ1Eg%iY$YJx7Du*Ma40A5kT!#2~8=ZqQce8f&e>Sco?>4Hk%n8>F})OUJ_0llNQs;1SSK6u=ElEiL}E{(mUM%49Fq#7Nwf$U*qX@bP z_u;S`3A-hDKIs7dlonBtt+muN2A`p$WLXq+^g(qr*U)b!-wnQjiA-=<9^-rjXJ0tT z=7aCq7|`vD7A?vk1(Y;sRSys^i``Emq*G8?mUF;&2nt9qC5KR}X|2Yv{10i&s+=6N zk&<69BCP@N(PfXnflbR~2c`w#V}=)|P}O3b3+R%V6`C?avuo4l1!mBcs(f$)&^c0S h3M%i1bDtj8{~tp7v_njOzBc|61Ra+kG!xrSFn2rX$CluH!tIOh_6UZ42+t~uE{w#Vkpn~NjhINxW<2>MkCuq7Yz zH6nH0pdW%fqhLmWFU8Q|EP#yX8WRejSQJx%G}>WJD1c)AlU%)0481hP-Q9}e2JYgf_uiMusn=gS25m)c4G3hOjNCXj90 z!cwriE-7FfHyl{9g!C3qaO6nP1_4eI2{1&^Nk>_q6Q@JdMxokOLRFdk`@@HWhJTVe zQb9p0%_+kr3WhWiClQeG$~aYY<<`2ofo8yn%b7ukQ- zBz*KIIr>lMz#a4LYa0kt4jW&9XAye9DBLIAXZRcNKHUwLz zA*yM%Tc0m98bSJ0Pt9R(tIeJ{Si3}RZ^b=VFRKl`IoQ1a_7?{B_t9dbfcjXrF}P3R z-aq`+!?u6g-cpO;`B~bT;M^=$uwF5|>kr!_IKRYsHa-6aMO=-Th4D9400000NkvXX Hu0mjfVm2ts diff --git a/apptentive/src/main/res/drawable-mdpi/apptentive_status_gear.png b/apptentive/src/main/res/drawable-mdpi/apptentive_status_gear.png new file mode 100755 index 0000000000000000000000000000000000000000..43c2cac1711fba863cb83dddd4ad704e5edf9a39 GIT binary patch literal 712 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 diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_generic_file_thumbnail.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_generic_file_thumbnail.png deleted file mode 100755 index d9a8846a06ea4989bcd84314b7205a4a1d5f3749..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1331 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 YpN@sgvC*aqmjD0&07*qoM6N<$f|!nvtpET3 diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_branding.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_branding.png deleted file mode 100755 index 722689bb6abe367bbe40a2904b1cb3861ed8fa64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4624 zcmV+r67TJaP)Px`%1J~)RCodHn+bGP#TkH;uqO~uKtfm�t1z6~ZQ3&{NqLp{%7?1Q!(RL9~GO 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 Q@Bjb+07*qoM6N<$g4lf)W&i*H diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_compose.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_compose.png deleted file mode 100644 index bb2b49faed552658c3423635d84425329d946600..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 484 zcmVxh zNO7IS&y)MHb;QCK7tW7Wz&e6!1l9-u5RrWV4*(7U+yS^G`J?$c<|)*{zXI4B0N(>R z(@2;KOu+XZDhV@z0K8hlQs4r>jUvyzkuVc*;39Gb;94PZOY(f|xvBzP+8mI4?qQS? z-z0ZT1qM043*eOGQ-s7j$s;p?k%Ik-kk|k?Ci!V1;ORCR2`{`8Dp~`IR_T)n!WR`# z!1oz3CgD2H<5b!VQ>jP;g039g8aGx8<@$zydy7 z1gzk*2w1|;7O;k&CC~zVvOp{FNdhgwM+>wDA0;3nZffwhH9gQCnn{P0=Hse^tb=!> z4>!MwUB%#45oj4cD9}2*S6~V7A%Tw;b6$NL6%mQ8*3>I;!ao16Om?9Jfuh}JN-~## z8+o|Vhm)wfatN5ghl*HJ1E%nE1Px$u}MThRA>e5m_crXFc3vU)$_nnA~sz#i(ZARbdgOrC`aKwmFRrRNC-9djQvqr zjHQG~jOYLN9Wdf@i4h4z0+B!@5D7#A|Cd1HksgNOwd=Z1ne*uT{>w8rS38d5o77yV zY5EYI?_9l}f6*VgBh0sLdzZR*`P^5*+%(hqwb#-c8qhLLlp-?#l5d&@DPcf>0%8O9$%M2im9`e~PZ8gN+{Av~&&@v6zHINXzd9MjpFBbqJVF)vN=<>J$Y9W~B z;iU+m6oPHO3cw3-g!yU!E5uReDF8VLoR@)3YP&h%R_VTTq0xR6UjzF_iIh=#h8n5kcw!!gG0uGvC(Pe|{h#3wexrYCROi040V>=Hy_C0BVfX%>4_-4ZtwK=%Fw!0H!djml=R1 zsLA2T=;?WsxQZrqLt1aM*ei6y0~a))Wg2DxyfK^SS>MLd9trjk(14c7y%d@MLTHFL tW@me~Xa$YBNFWl31R{Y*AQCttfgi^y9$Z1$)m8ui002ovPDHLkV1nL;*vtR` diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_info.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_info.png deleted file mode 100755 index 821ca8abf23257c8154993f5a18501998cd013db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 442 zcmV;r0Y(0aP)|$c{H=n)`oFa-qpR!OFzT@jUr9<>2Xe< zKIin$Dsps`EY`liP!X;DXyQK0m@?{Jz!I(Bxb}17h zMwwlzv>CfT7?!p4>l`^Buc#7_^ovvF%JDp8T@}4UKf(}O=pDl_awPm&V4T>uR2gqM zc^GeNoe|8bdzN!Xxw3dLFKzUeUM*p>xMag$o>6phY?N~fHS&~+G=1Ts5D?+@=WI8@ ztUR$-3B+b)3ZflsqpA|~2w1#o2PFDp+O3Vh`g+A@+g+4kGlbf2y1wm@r759(Q6Rm^ zBJE447ec#l64(t{dJ;Mhp|XG!O}0ik^f{N1-GSJf1Y&jPx$cu7P-R9Fe^mOoCzFcgO!hO(5g11Dgpgv1G$$_)@40Ex3OvGf#h10;r?05LGI zB2)$@Xcv%B_}M?OmpYe#DKne?Y{v0} o1e6&IE|jwTk}U+aIk6J(4o5hw*#p7vX8-^I07*qoM6N<$g4?0Mg8%>k diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_remove_attachment.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_ic_remove_attachment.png deleted file mode 100755 index e5068a8029868ff35a76d8c00524a27222d8497b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1743 zcmc&!`CF1%6vogA_hqs)$lSL~3MUoR1j3Tsl2mdjD>F?}(o(B2F-yvsDa$3dibu>f zbYHxS>hxqs(Ne0aSxRgree^*~xT54-+Qz#U!uC5Y^ zghrzQ=Gn7n0)YUDL;}90rDb$<6b6G?Sy^$pT)A8>6bhG@my?o`^z`&V8Xg|LxVQ*~ zLjUD~dTVRz?CflNdpocJdIB657x(btLy#^kEPxmh5n*Ixl$DiLQBh%LW(Jt3sHlmF ziMhGCn3xz#OG~j>40`tU^?`bTLCnj`1I9q5hK2@@$LsFy1{jOQg5AQxLLiZmkwK+W z0SU~rSS;Xta&i)+pg<;*0Y#})3TFBE@gs-B0sPR=(7?a|z-%@fI2VaTV5sEe
Y zz=J7(95@JU068X;2_^+Sfs;U0&l_;Q-~=gfH$+2QQ+?$RYAc{Rx-cWHRh#uKtO+Iv zLwnavmTL_3%skdPxOroK^jvFdF8K)wcd~OwZ@}9)8*f}KM{)ET5q!^agAr7)mv4vc zk~qrfRpk6Oo_yLpfw8S@93F_{Y>m)6jyAMCaB=+5&bof2Od>cULT!FoizO@0&mc)w zvDZEoIzD}in@;X8Uyt$V>=Fuz@iv{{gVZJxa3LqvipFvZc2i{vSJ^db<=~|USvHFb-?7P)6ii?qJ2@8yG z>&_Q(GzUEHP%+oE&4_cWT;D|>uFR^>$D5kkC8!cSf=qnVEHbx)O$BM2&*0;G9+w~~h!=ivQZ1jlDO$QNvy$Rm_*?U02~w%ov);ve z#aXt(P-ZhVotLO}?11aC=64)4+@Kw7+otm!$9CvM+_zSb5#bK}tV4%!cs=THxnHLk zACUe)BN9D@*sD_OS;<38(Xb}RAN;^mdw|*OJ56Pr6QwX{l?L45;dES@G`%tyZV2Oy z>Qm1l!l>T&>dgs?Pz$dGN7mUd3HBS?RrO9~br;g%-l^kfN>D!BoJ|FSj89s5d7k~_3nH(greoHA#aH$=p&E-DzQ}L8xa>|H9~>MJoDz^I^nK_O zLblnZNaY!t^PrRe=hwZ1(JE<}XT5g(aI@d-@QaaOYns+E7>v^DR?N&`Z|`SH&2r<( zM~8|-U7bQ+;HfPqs`+2M!By6FIh0JS)-3x*{p*t~AZ};>WOf}MQ%g>}u){<4p|Ut{ zT)9{?j!sd=qo>eo#R_*@LA9s@0liGxP1UD{$sYm+iSWCgw(1gJ8Aw fY4O)agTFyju>k?KXTn;+UkgI?2_!V(_h004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_009a~L_t(o!|m5g4uUWgh2e{kxIvTw;NDPC;}$JB4lqhd zALpV>OkoK9KLVwJ46^RFS-GEp1SB8;6w*sYS86#*?l}h6Uf>SEpn?#4jRC*~x$CHV z$Q9$p5DkXc*(V;TVMyYWH`wz4OGNX2fFas<{^84qfEYpL!$622^D)3j947f)xWLTv zIibiiz?@L!Ilv}9`H~sS0aHSi=K-6b^H{iCXR@WwrLTXmZjnL#%Uje;9<9+4+I(rv zD1y-D=aV){#PY3k-YW<`Z@;xPu`I73{Q3BrLlI2gzuptXH+hP159`UiO>{hv;}-f- wa1v+DhnFD7naqzw=gvd2^p}}{1pEQ;1dp!cmVSGKY5)KL07*qoM6N<$f)#I~?f?J) diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_icon_no_connection.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_icon_no_connection.png deleted file mode 100644 index 85230f224718210d82faa316e8fb1563df74c5da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1129 zcmV-v1eW`WP)pm!$rG+=Lt=%*s~6QDl;_OXb*mVACv#BLMOivZgT2rEaCP2=hn z?d>w1NZ1yz>l1rl#C|WrctMF>4unm;_mjEdL{n2`0>E|#^Z`Cx4eYnSvLI}E%{5_6 zS1Wk03yEkGpg;0KhR5_9K(C0RFq#L~lsrIAHAnM*W)xc1|jyPgMVp z$)+%s8)mTX(@YOQZ(*r9eo^H=cqxu6%egv(_qGB1N0p9?V_K5H4^an~TzTb{qq$=6 zKi)Juba7n1eLSY^5YB!AV17q*bcCrz^yPk{`Ylk|!es!R;;0eP698>X>^Z=`B1!1Z zl>X|b_LPX;?0q;Y`Mhk_%cVNwjPJ*fk3?jiUNxap^qjr=A#WsQLm9_=-44(@IE!=4 zagIgtUN=tbJj+hRzV6m@KIrPI%<1|ANdREais)O(*R!}PLG8+}4cK?ZvoiY}(31g7 zT>Zt{Vt{_e+KywJ-3IFD`wFJijm+@);9T#k@ zxvbIQu8IuL)hoDZ@V>GpVAmz~W_MBX_xq(+C_g!xNNQZ8f|2BSVU4FC5^n)vJ=bXX z>*bm~nu9hfnDUJPs+4Xkmpt|Y*Ez}ZT!JzDJ}t*7UxVbAXF z8V!J+lp(U6BsQ*5A!5g-Q9b$fZGA-g@G2tPlwW+*SELUb#Mv9_nq}pP^uE2F|$;;T#fMu5(emokQMPo00000NkvXXu0mjfMT;^0 diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_icon_server_error.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_icon_server_error.png deleted file mode 100644 index 330b076ab24bea65a60a44cd28f06e77b82efe90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1181 zcmV;O1Y-M%P)HdH_-b_M7@o%lZ=TzpwHie@EO11KeYM1?Y`(6RKwNO6fUcEbU6X(_B)`T z+d{wh?S`>1X1fDQJF_b>S0X0A2gAbjJ;ufyxdSbiD|-+#-NBd-!d#`2+1)$P#>UDD z#@IK&L_TES01sZkY8@UxlYWAUbEZ$gi(|0%Dxx2~0%HigfF}n)^?XnpxdLPeyn#n4 zu*=Y(y)bY)r(WPS^Uit(D*!sfPWwN`GRM2k0ty3EBZ2q-t$JKYW38jFjIje~?2tY; z(7XQKj{ZnmdILjxqe4{A+KI%#&BmBb>+0&}V&uhIO4-Y(?O-WAoys^7vY@b=9}`{7 zfMiV8=t$~2MZzLuCxV?S1a?BP7_Jdyxa#UEOKNTVWaWjmy#*WrfSpw+*cAhT>y=l+ zg$VShtPV$#RNhTuca@5cl?^0Rw#_O)V_i%5oC4CZKYvW?7EsEbuXXqg&DTur@1yUV zr%;hL<1Ux}F<_xkSWd`!zdniSLZPyD!twkGQk)m0;b~ce2>*zjAe15_tn?PlE_LMk zBACFatStm&%jJJt!Kj-A;3U1LRJ2Ko+u<(Gff3-Z+ux&$-wN&UdF z-9MON@rI4gIF+04W5P$myhy~|w>_?x`>aWBIt+OQN0oL4IKsXd+ zN*=@r={cy~Krz=5-b#Le?Ic?D?f95?bgbYl*E_(ZIr*&hTI)r5E6c6}Q&n<-p^`rE z9cknYl)t-+)OMQi{2v5aRZ<26fH}sM!{A;zSnO{-1GaCp9yGKMyA+V#jx>&PsT8f6 zysK(80z1Sp57RsfEn7*BaFo}i|EGH3VTez)bUou(6g{1?j@}FprR;g}Zew8)j{@^` zkEUgKJm*PyTJ+0Aod3IYK09BKI z>B@w7YLUVV|50wl1o3KtzHV-AUYrTjx*^N~Aqk5M0t8VGL_|Ey`&w+RmE(Kpu6Qde z+{(4kM7o7fwK$N_H{Ep8+)Rq+5r=>~v4v)i0P9ww8YjAPSdiHeNSDf{U|<0`0{nv0 zgg8Ur6$)m(xcTU)&*|t^`UzRg+)5s3yx~fzb^o1QGsZsVNHR~(y{HA!_;*+E9s>Fb z6SESL8#P(B!~njp1`E^p)J;v69y0Fey|q_d$_uS0YNdQQeK;ro0&%Z^N9O+sfM5Cv zZf})8hOj|S`}@E8wMC>k{rZJ$sX^d@#QDO>pBi!aU} zxVljOB=MjY7LNK`)O2CY6t$TfP}}FI&!;g9c01G6-=la4yZn~>weR3R`us8$3#Wz6 v8#5PnQ|s^$8uJb;7>zfEXg1u>Kid2PN|pVvrgh1d00000NkvXXu0mjfSFJ{* diff --git a/apptentive/src/main/res/drawable-xhdpi/apptentive_status_gear.png b/apptentive/src/main/res/drawable-xhdpi/apptentive_status_gear.png new file mode 100755 index 0000000000000000000000000000000000000000..97592a5f09eab95c6c684b739f097246e44bc412 GIT binary patch literal 1585 zcmV-12G043P)##a=kC4s z`u16St#7Zh&pvPC{{+|{XW=85Uh?}?yc<);!@p8sCN9J}ye6;}XJAq`ZW=DfFt*_r zxC)E&apOVYXlyYO>u?liq`%|wO3ApDm@}RP7G*o1V+gBo1-_mLmEjH?vNs%^mtObm z!t-PB&kE=2;65BtusIV8(KA-gA1vbaG2DQqn2zJ{9qjCaz$Sb%*_wot@ja};nV8(I z^9PDB_!}A+#2;`Y9>Df4oNwZdWb0da6uU8i$FU4kM(g}L@P)KXjl!ZsW8ip>hLLY_ z08io5=p7A#!*Oeg^LrBmxC#4>hCnYa#y`f9z$Sbi6FVl5NF0p2bpIBf!)kmN-^W9u zptZ6)jJ23MD(5p2Us7JI>R>%itgw5i$YR?n=5E24yLJAZxTnodRpD3YtFgvMMP?f= z%pbA=8M!krLgX4B2^c$ zRn(wG>F;RFY(?PX*oeO;2a3CrJO4y7elq5WLq7)}!nGpq2Sv>|2RGwxk=ZU5S#Dys z_6p^1dS}|i*YGMXP$dBIg9?XpH1IG!*kU6l<7`pA8%D!PZ^3lq|uKIMY1h@YyG zK%$qJkZ-Fd4Z~`8zu(LxP;=XMBjWyPP74yoRKTvyJvja=AITOTrxmtwB zS|L4-kirA+!;2O6Uchmgy=65BG_bUcz+uV{QjUjZhe#aC)k4oS@vlVW{q}^%CCcT; zZk(FgJE;bN%{aY`Krc?gkHrBl!xfT36d7x|$T&p|h#D|I+nnE*j2kQvII)G}gW_JX z1T(76z(i4fzgA)7A}IrijPppF1y`oAv+$#mF;C$=+4`TXu+_lz;-1j@3YtiKrozzj z0)h1{2oP`LcyZysweVXrCH7`(uWmu$LMbHc5cpJup;c0r!4#3tt7=6Pw~4c|F?+TH zmtk7A?n3d_$}o)c>o`9Xr;3Y38Ma_SVf+fASgVLMoh5ei4P1j+nVtFgO^Zz!#+`U? zPP*uPAHE^7NGsgz&AEF&d=W3VAkm+k-+>=Whda%mi`!N2evX&$Rb_`*#A6-NHY_Uk z!ffsgoQr2g+?Qde2&W^nc?XH&_3s+%HZg>w$_SjG{#CIdb}cVLQ^eVMyoAJVaqm4g z8-IXkxm1b8Dr}a8Urt~${@8(`e%vo=M^9#BiICF$+1N+$fo!c=_=*U-PNn)fEzZHp z4vqDT>b%sR^xBh1-6!JuMVykYF7dO84@}Y(Eb4BcRdf0}9a_voa)^s?(iS@GV)v5DM zP4w4MF5VDDs?*GtW0z2&Bfj|5Aut=?RzGIn3Jl<9vZ~(+fnISje_B-19NUDh87piT zZ#oav-J+_Wt&7%TugLGeO}nuZzZMeUdeH!ZI#3E^OA9Y z8gBxVgt)p=$lT510AB9R{i8|vu(*0Q#MN{S&eyF}=oUif^ol;wY|&yI(LqkXpDv{L jJdp&(?<@V=7$f`-B#d&-*PM2Y00000NkvXXu0mjfmO&K= literal 0 HcmV?d00001 diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_checkmark_alt_40dp.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_checkmark_alt_40dp.png deleted file mode 100644 index 313df150557d301e3f201cd3b782539d6a787e59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3474 zcmV;D4Q=v?P)Px?Oi4sRRCodHon5FM)ft985}S}8urX-h7zvb+3e8P5MD*sITqOh%B(%8_f&~NK z2+fVbyLcDqWz?Vz2)SqxOcbgRNFg-2@YEYANU`PE5E_$445W%NHtF;3tT{Q^dwpwW z_WZ5+`QSaX_nP(deeZi__L^C1*38`30lR(s_A0{I0=6#0!+c)n0ZI2=_uvX?e_w_# zW@cu-=X7rz+>QkP^R6YvJ2o-@Mmxa!9Qo)Dr<$n2)Y4Qp92zA z*a(`iuW0m)!zl#6+JqB%+Kg6UL|sWB&w>}gF7N<|$!_Az$KYM?A!6T%$+^Ur=mbXC z?Kt-$_%(PiaWwMnHT?Sncn6^uBKNf!_YigtoCa+-#W2?li<7N3egs3tZrpkeJU!`N z=9Jsyya<-}g8#{P9a-Z&W|Ag)*E&=D3@q=3Kg#za{G6x!>m1P^vF)EB><+L1rm-I= zbPgN_^I%Qc46067x7tu!YI7P>j62HqFWUMDc0D)-Zh<`ZHJRT4yTIDI15}%?ZTTQy z@|a>(%XHy!IFU}|VmgmS;?BbxvsXxWL26hwB zCU6#HwJT(N6+F~{ySbW_kIq;5oYlm|rd$ohnwdcMfUHODMe@D^R>vBT<(GVRzAJ_- zCQkNP^+lhK^DDp+kma}bGWiaGXime^608_pEQ%@3#Em#wF>QN|l*8d!a2}-D|HyC@ zwB?3IW8(f;owss z?e|u_&V%6ocq1v-GsWs+PU~@tyQj)+y`(I4;v0nrBg9R86M?hRzCXVavUDMz! z2we(&!~SOiaSgkcF(9shII~P#*K?grL%Ks1x{0Cx#zEX=0%rLr&Oqo$7U$L9@uCsk zTC+^QC&Otui=v)9;tu?1kxTj!PqFfnXkZTr-CG_yR0ZjVUv<1J6Zh2&P*Aak{6d|o z;ZmrexJhw%4qZY?gK~!≻6I1(uykoEx^~FaXiIF=UyvC~wjLm1!1&WnZ$R_jjnu zk@apZ;uM5#Yieq7aibBR0&9RmniQYoMJ308We1~YspSqr zyhh$EJ60$>YSq+MtJkdY+};fN6(X`gVQ~z^wa=u@^iy&vYzkH^oYEf|w zteGJTQ#D3~8YQyq=v0*sg{EczA&y#Nke+|ki9(vq@3YG!c5V*U)XdjZP@DsC@3X(; za)TQ5Aedz@<*IDRTp9xiqM4_b&1G(g8crLvXwGlzr?zG$qQs2wHV+DQO2s{}=3Sr8 zdN9B;JzE_%O1@>3zCwEIo;V0cTm4=*OTR&6!1}Lv-dku$oL~SBD;HOd(vF^)_L(%?;B(9x64cY|!==## zW0MK+RExN3S(*TArGd$zL^7WMJ{xXJPHH)k0&%s8n>0?FT28`eCz3o%TXJ3Ul23Y;3yOZU~^fK_- zxybo#)IA7mOxz@Je6R+EURIvuVtZ#&U~H>}HwW`DAaO~416Y&a{=>eVEQIzqPw_I7 zERE)u8o}8`;Iq4#mU0gtAgb{rH&Fp!G>GA|#ZeyitOCB-0=hZACaGxH-eCYvq7hdf zNh2Vw#!Z^8Qig5gd))U6gQ)j1054IAn|Oy`dN|Ez+w>c}HOV-()xw^GIR;=amfu{T zCYDxP2Z4Qbjip5{uDl%t9@8xI*A|GID)1vlwEr;Ddz0J}aixdW#`f7GIz_MZ?IG=& zk=~2s7Ktl8zA;2uCxNY7k^eOcbw0Ue;z|!otF^jJS_D4Z+<7HE0YXHSmqH#_my+;# zvrjHUpoH zI$59j_K>!%LUEHO8xt7^Iw7tT*cveUOzK-R0*bteY~p`|c9J7E5jWY^E;0>wMqDTG z(+Qbl+jF|np;y28th8rK(irJqv)=*g61X?0x!>&@3b z)4Tl2vVT+2p8}QDB63H?6|I(5S0u1G)D#dT*DmHI>E)5X0lyCvtW@LJM1I?FGD*(d@uEO)#B~B&H>yUDu8c&6ltv#u zqkSF8g+=b6xNC_y{oynBpKyuHKC9*NQ5r5JGUa=9gK++%TbFX0f)A}l#X{w;ZZ4_=Wxvcjv`EI-S|^qJ`L zEyCgsd21P^lXVA209j7gcVzVc?X0*?t9;8SxkA=`Y4y||YLUoY7kBD~&{iU3R7)A+ zPu?TB)8e`Vak`}pUE$~!Bh4XlAH-b^ABxjwZ>FAQDHY{%!uXYTBzIn1cK{Y!PS{mq zjW0I3Ab3FJzKC0VL2xJVobUK|X$MkI0~KcQh};Wtoh}Cgy3FOGor&{ubhHtP~EHTEaex1NzdW`0Hhz$ktFIZH!)GT+3r81^H@Kad@rg1<_7m^;pkJ zO~X#LioF&%3(xhv;@ye7iAJqcwRAt!0^VBTqPP^HhDn1>l>|b?dq8M_eSakl_o!0% z-484i_j@X(g9eURt&@HeJX@&)9j;v5fggcoM=B4WmRErDmItJN2cD_ik&ZPW&K!4a zye7_9)Dkug%>wIzCwZqy1B1vJ)eu*XGd5lm*LsM)KBGZRmJfBhbR-X_>l8`E5fE3F ziQ~I(P)Vt;)ZH|!3-NC)&q&vA^3d@zSQj^rBQ{?kw z*O9E)9S3Yo6Nhmex#OhZm;wlOycCsgo@<0e3&8Zk6swEb8aQD0$i!XT2LKMLcOANf z8b!jNPeA7<4JbwzE1RH+vu1kBc@HxjoduzrAxWf~rJ$)O))fJD;jr#_>9%I*-Zi^NcA3ALG1&SwsuhEaMKPtBxDiM7+@UHes;@lGYk(r{ zcbP0B)4Xd<>|X7wE9Nx$?0i=YSxlT%J8)1JVFaR~#Y((VV{Ji}OjorS*)-vSf-~9L$u( zYjpJxoaT5P16h8X$+l!)^GO{ttxI9O3aGMp)uwA(KFF6mrdSnoIdiBgi?YOu306~b z7r->8qef3&90v1XO^L3Js#2Y<;s5{u07*qoM6N<$f*I_s A^8f$< diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_generic_file_thumbnail.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_generic_file_thumbnail.png deleted file mode 100755 index f71b7babf915f494cbddb427d327621e6e13ff44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2036 zcmd5-Yh2Q26jn)WN?R>$(nb2U(Q3`5VLEkF%uAVNYG$rsVy!=BA)2?+yx^v#dC3(H zF_mOxnVAOGk`SGWil878A_8WL7tp5Ym{<09`|W%Cw4D#H; zn;IAxtn)tP5dgkg0|Ud#wGc2GSEOfxz})XhpeG2~Z1%vwfKsV^{g0*pM5WW|a=9E# zge7N-#p1rcJ}~a>?HwE(B$B8gIgL~X_JW+Dp`p>yQMFnj=g}vf4DcJ?(m0iLf95EN< zGgwVhsr2WXXEK>gB9YYAHvq)kSFc{Rck=Se?t@}LC7cd!c{QC#Dvi#%-QVBe)z!t} za9UeiTUuJ$+S)ogI=EbJXJ;pm$LsFy77B&!?d^O%Umy^GvOyDxL_Iw{;A!Apph$2F zcnG)@jC0U$_Ja&eY=G}^1DH3pb4p)rn!2F3@m<-guhu^?Ows>kW~=^?zVvVOj@}3Y z5+|=(FC9+a=x$+RU;ssVd$UtFz*pJU&nf0R_}2Aok4R| zVl*GNcolVew~F#s&Y;d6@9+#Q#aw^Ztn(Y{6s$5Y#+qB9md#>5~TCq z3H0#LYKP+Rf3xUsJ%u>vWhs0)m&M<~B?-sE_xhE|yp^j;e-q zrB)22YKFVioKF!Hl0`Mc4ktD z&LKpy1)w1k?n%$H7nbJ`sSUkpnbKaa+O19Q`^41}7THDk&5!N6HJ3n$%%ph}oKVsn zH_3!sbcWUM7K>F2^QxG0r7);=y8QW)+K~q(#F8ztqqT`nln=VYO9_mKDjuu&_2qqa z&6v}7A?%*;E)MNht}Z^w`I{pq+=1eib@bO`iGz!zKO!%^Y>j7OMB`Pip~Yfqm_0n? z5#ZLOllh2aQ#&zqeVi*o`Ne%75g%RQ9sC$~kDBzHeNwhefBtNTt`OC%gOAnKZ^{%$ z3`Eo=T);~l`wp-&q^x-$r+%yFdCDhQsU=UCA=;>1P5|pI)7i|W>~4_8;w#gc56uzP zPbX4XkdK1MO^Vxw>DdQo9PmN%&rp@kYkTjSe(-oIn29ffkKHIomnRc&f9vJV7 zfG*fs?v82$P=YJJg+&*}eeM8B-uY!r8*J9fre%suba4qIixXh>#r~7KEO*x|1Jq;R ztLN%BuD&IE(LnIq1T6OI4%%&u`gGXk3U5iCZ81efm(z>=JS+p5+F_ZxjF#P_vWQZYbHXsxCY z6~@g2;lBXT&ESM}2l;5pGoK$bSBp(qbijP1(WdQv3Nh1C^<}&m7W=fsXm#wCJNF-o z0IFdj7V31O2@?%g>PbeAF#Boy+6#=#Y#`ent|1eHPQw8z%{r!bR}(DO9|^h_pZ^MD z9KH?@`I?;k9zeASMmEA`NpH<;A=Yg4!vzr=Yf715a4Bs97 z=wbus4%gwBAq&tVfzTzPJ3`=NpC6*pK8~7kB+JQ{T#xo1b8i|ttMpLrju-{@i}4F@ zSAxyvwR@6iqi2!B?x*S{7q&|lXHPB4NMB6FQCnF>FZH_0Gs|N0NhVp diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_generic_file_thumbnail_download.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_generic_file_thumbnail_download.png deleted file mode 100755 index 54e9a855e3117bbe1410e62240f00fe29696ab50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2209 zcmd5-Yc!kb78XvUCFoV_TGP(dv~JOa6s`I?Zq=4f6~j=s`lRZJV-%(8lD3K_qeVy} zWK?xZO9@(3)9E2`Nr;kA3(u|IdPEJnF%*@Qs&(F=xK}>CJ z?bz7Z?Ck8+)YQ<>5Ola$EQU&^r>7+n$@uvA#Kc5!5-~EJbemjQQeEHK-4k##?S5fN zdnZ3Qi2&)V8h-2V?=N~@GdMUX5C|&jUV}-5-rnBkHV(0%7#aqegw@hoSjI@o&i_Yh z*1*6(dwV;J#cFD5YHVy|v)L^zEv>DsZEbBF4yU7|qqDQKxw)CkUwB3XilgRv;L{6C}r(#tDs3g>PZeR7H?egI44P4|Nul7aL}KKf&x;keHCfV%J~9?t|p`hx?7V zdn&{c`isO%q5+rN6j7(O<%-N3b^@r;)YtuEVG*MVPke9}x?;!&QNAd2L z;m?{8UiUSs4tyzrW%zz6^~D-<6jlbN{%?Jt!{R|+?jtHwN+jVnjw})&ZwYys??c?q zVeE<+$6SIqs-Mc!BhG!Oj~8OBSALS!OXvI6G-y8c1^=#F8m2+1agGFPM_k?YI5ILVkg;o;q-4k--A z%9JV>WA!8Ynz*xNN*bVkr?$o>hi|_iiHIc)MqZtq-0Q(eMg0uQ{M3o_B!1QR4Ye4n$1$WGQf=D)uX|Ws!i5KW%o}$ z-UUSvPBVa?Rn^WXQ_5A0vz=g6U=qJWF%-V;<;P*eD8RzjLyA#bLf|yDVg*IjK?J2H zX2*V8KRE5AzsCr8WMM1o_`X}4=|hUTw?g3!D)(|NX}}1`vr4vF%mr|;gG4rBbz@s# z)WW_~=B{g(kQU*8fV`EFuoqglH6pE#X`&?B;Wt3uT^RccoJK>MjhW)-FE_^cEapDR zUpzqUMp!Ddj%%|5;WSvFZe4&W{Ks{afOT(878ty)n+DhytX46U^oFGPY0wWe8RBGHz3W^sj@t zg}jUjh=b7E&nW$1F!us4L*Xc1-M*a?ME?r9ccZjCvoki|sqzqB+byoDC*IM1s)4?) zr)-WVooc6Sfizd)M)*84Wk}P9@RI*i^Afr;i=8ORjR-WzyMFl>P=;;(o&xL||CUSN z7Lf(={$}BX!X|4!)<6TqL4;<+F;ETLyn_mS=k5nr@l4V{k7K#?uMCj*JKD8SAmP$| z`(9LWLjPmiNz!qf&wuBW@7lF{ROI$s{*l{if(#u?_9>I)|4Gx?635u~-KJ~dbU8*mu>EH&eD_|^a&ST2=nR6_VqFBoacHXjH@?$0u z*1mF3@?jo#>Gp(MoZ%RUhq^^v;WcevS)cFf+@Bp9I-@1Tb+uO zj-@;%b}l=V+s-prOt6$^1fN-yp6Da(uOo)oMQooWV>_`ra}y$LBR7i{$$_!-n&7S^ zV}#(#;Mid~Efiz`t`Ll;HHp}zgs<}imDJ>UCrPLgs}B6LT2SH_Iz{kSl5msY$)LK! zM%o^7vPenP{$)*qTd7|cwu*uxsF@@3dLZQHhO+qP}nwr$(CZS&eFuj_W-Wlb4$inEvfByE%Td=0J0WHOnIZyaK} z&~>OqsjDm;x(0QCdN10fD+K|6ILZuNDF`avXo--Ddc+#NZmZ-$k^h`%=B^Y3{Tv>O#T4eZp@UuG zF<%&_Nn8GPazTHe%w#3IIL#g2^0zAO*XT{#gnXIOA~tilD?RO7qvfX3%{hN2na%3< zbhdlFr;l3s`ol3D`qVbHC2i#x*LlHDDilt=mu(i>$9^vGppOmIpcqPBZQ(R~DE5=X z;%$^BsMa$!$m6M_phmjP{2`Vk=vxPvCd3j1ReQ{uA(kX)hzrb}=GYMX%%1Ucewv_3 z9BX9SU}sZ?Sc0JO?uze?se=A diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_add.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_add.png deleted file mode 100644 index 9a4f996bb0d3b52b6a3c731be423b5efe6b57435..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1529 zcmXX`c{E#j7){Vnq)M0AI@;9IQ4&k3a%xwiik2AN>}qOaOBie7$wtUjQH0h}u~ca- zV=3w=O$Du`)hcR`8DnfI>8QPAUeY<|_rCZ2?)mQh?tOnehP$gHTvk;U0)fCWPWD&8 zcbw>vkp%03HZBhWf$F)tcshVrKLCgZGVs)N0yRCFl0l#{|35TlG%X{Vnn3{QAR=n0 zqH8pbNdN#m4V)KEhJ}R@K!nDOqB2AZvMG)EPM(h6aa3=rHWRIw}Um{R|e=4^d^!5b;ub}RI0caQ9$!zeUS$cv>}4bBSy)u~;mKgC~ld4#o+Kr-RDk_)M^gqKI;R{|+KLg^3q01#8_! zy*bcFQ1lg74~UGOM?y(U_wY1->s08Isa@gWfU$lJ3FB@C7IdW#&bHkm@^^YHd znfC4U(Cp+DS%SigaH#)cqnBFeXVOv3(tM0m+MepGA|2k_Z%LA0XRTU~P_e7FP7Q%8 z<(`RbqTF8069_~~8Dnqb83%3bqCf#_2&D7b=TFIRVZCjV&upmsgKs#MH)WHJoeju5 zU#_{vUvyrP2~Xq4d{u>!>_eO09O5gv3qA0pkV3>YzHMLB4>A&w&zmFT^9ocreMZ!R zb1OpC*o`4gl+Y%pgB_W#H4z$I>@qQJ0azT!>}8kQnZ+jA+PMx5qEWRq5#cM#;Sn{p zDD>cv>+Rk?!w0R&$4h%2g=8WE3{U-Tzo)-hV zY=}iU<4X4BHy%xMAh3`{Iv zdHQg@Rtt{dy@&`T+A~c4Y}2lvm*%D=DOEf2+MJ5U=31snC%nR}Q!eC=y| zC^fMgPiWA$7`YFf7%UCD<=K1ad;UiaSy)tWc|xWzXYWB9xytWGd07NU=4QavO1TSp zV}?xEveBoH<$ZEsaS{}}0ED{=Q!XIYkMFeIP+{tw(?OJ)MAe&pfSq*ZLnIT8I6fm? zJ_WPqWpI5Yp;{H?i@s0=XVc$D5;zhCnS8Ce$Jp2mxv$-P&NV zVQyc0i2NzP?ys0QC?|U8NIy%B)Cpf7FbE0XhMpZi+e2=hmBvZ^oFYY-P-q$Gkjm~q zX2mKN3~K9Z3fDS4 z(km^G_@XAe5pJyuFaOqV>eS9T9E_}THO<>U+x8B?DYMmty)d6D#bS;-;p#2*`JR^S zt|mXvS|goGzOt@ldOyC@NaZmOt9!EGwfQ3>xhj5^u3hCH64hsS7sCb<0-sI2-WzVW zS|oP2Ppc8f+l6Z}GzO=Q9A`r@{5J0V+P$4x>T5BKzDBgt9a#ve4t^i%(BQK1LecBi kYWMrKuI{8}CBbA1j4M269LwYuga0H5#=+IT#@3JgA9ZQq<^TWy diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_back_preview.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_back_preview.png deleted file mode 100644 index 39178bf31a97f5c40f5db9a1f2e77d40d0e86bfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 413 zcmV;O0b>4%P)4!DI^BJQXicS0Gl34PMw13Oa)VN;=ejiKsJCa*QR+Y zUY!v*765*MS8n`5zF0>x02A=W+Iz3{hy`#2cHEH|NFMscnt&a*BrZrkdc}HYZCA%j z&sdivKSHq#p;(4cEJG-kAr#9Hie(7JGK69or^Nc;zQ*cJTdWMWqMwhJSQ+@_fq^TQ ztXwQxh32tre)#6V-pv=Q2BBH3{&Q#%GM<5n%z0+tc!l(YYO<`6OzcN3ciS67A@Nw1 z=6{STOGp28UVU+G3+I3Q(0@SFe}vTur~ewH^`a;cPJgpOYdc0Doc@-c(x#^)+-zG| za^pOX7HYT=fYH8d98YZvb`}%|cyr{AI4dF4pAZV65DK9`)R2=uXz9CQ00000NkvXX Hu0mjf-FdOr diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_branding.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_branding.png deleted file mode 100755 index 06327977d3dc9928dfb285bdb40592538f5bf85f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7138 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 dNs=V#N#80Vak& z@&G$3SwPWL5SchyOVeBxjs1UDW|O;7qF` z1j!4hIv@|65F~G$s(=D;e2{{0ssR$hPAZ^gaGZf^8M!6a;WXw;EUcDu8qmNmVL%2XD^^R8CCCya6R-ry a{Qdx)o^x2;UhPZ(0000Px%c}YY;RCodH+TV(TKo|w^b%|cCyMmzGeXwqWpzeCP2--Q~7sI0E`287ij}W@9 z&Ybx+S0F9Y9B|x$rXtM+Cj_Vz3CClK zf~Rn7_bpNLJk)LW9Msp4eBan!(T17{PMalfg!lFsq<0x2dyeD?>p@cCRHPa>$Q%xY zN=uPy;Zy@EL8^&^oT~4GP{7g`4zUkcI2@?-{v-Ko4Yg39sW>%}!hpu$pqBt+E>F>I z7P&f}>#;caEe$#T)l{PdM}BCWa*o#pb{%4xhHB2W#Bu|&XrM(IS}YeJ%Z6E&H3iEY z$fH3XWsb!%1@df&XW8$t%zz>q5K+fpEEAx};E{C!OAQnq7@;HUQ~^Z>1x&s~)vfwI zC`}1YwdPHD>c-SW=5INkYqP3Q&Lo6rcbF lC_n)UP=Epypuj=|egU6kK#DVT^f~|l002ovPDHLkV1hD8E=K?W diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_image_default_item.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_image_default_item.png deleted file mode 100644 index 1f7ad00ee5d33b9f5a0ccace2895e74559a8badf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 zcmeAS@N?(olHy`uVBq!ia0vp^bs)^a1|%OTFYN$QDR~7U$qXzkoIo}VFasIL7+Jg; z$N?Dw0w6WWe6S#tU_|DC*u5+(KLE94c)B=-RNQ)d+csOoQKsQzy0gGqpJyL_s?Lel~f_gc1>?Vl_C?dk&2!26>4hh~2`RL#+1{?HdB1*0su zVp!)f#W%=4Q2$`}=l0ct*|%n0QORs?e0_j7q3S_(dqeQUBE}uecUa#s-d^{k$eMEx zQy9O4{fd_j|Bdd1|6rQU7{{<#`A)gnopQGypZwnYA8VP-Y23#V?{~dnCr9zKLpl$+ zUq}>aKiV@paoLBN<&rbHEb_I^h}eBTr#hoD?#CbN*$K}iAAWvcp=jLNf5%UgKjg=b zwdyl|#{T&8dqTpqY@k$S)6DZN=l35!5O$<88f40M=7?^KeBCo5`x@Rc=PRG76i@rP zYTtxyjot^g8>ZE;>P`B+e?uQA7PQ{qUtq~QhvR-cJ22dG`Wt$8$<6ribqk{n$8?=fA@?t~h}-R+ zcIc?p7n%JmI`4n(QV;zd{zu{0Chh%yKQzC1RL<}(|HY&2693|Xq(EIn$;W7x|NDV# zhPsfFkKAqY;<1029wsmBju)uO0SYwux9Zg$`>^uj(encP^h!P&H?5bB{loKMwv+gN z#~;fs9?fU46EFFg-Ey8c_K(zqVpnl{#hQ079;r9zv&R1E_^@;xMpwY)0^kw&c z{vn(!vtip6k-Ej!t#@>H|Fyhcg7TiHtDnm{r-UW|9qHIw diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_image_picker_selected.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_image_picker_selected.png deleted file mode 100644 index d0243ec92ce3b345371b952f1701f3fcb869813e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1708 zcmV;d22=ToP)c0i#X zDOdzSP{9KQ9I-fvqd0|zlG=i$T%{?LWOFswCfW55+nExwX=s`@bocvLCcih?m(Tv* z`yFo+2s%ZQB%qTZgp@V}FuE5Qm8XOv`5>sbo(~}e5CE`@&R#*1WMv=}X88mWtLufq zV9?U(i>uY@<;+Ig8&3&`;9yWVD}wP91_}d(fxlU|jEs%484Q$8rD-G+ zl#_XLm5=l0K3Wn#nf6c~E)ZuV%oZ%|to)&RMqGYMq4+V{LP?k1WwxZ8_iX;gAzZMBTX-gUxlz?++79|5LfotKeOm@ zGp(SAlG&oH&9XO9K9mO9?)>Hc@#_ALMp|vOTm{O_+9E4t2@qwV&DrYH*R92l(<&sh z1duiUBgJc6Ihqt`^EpW4`4X&(BmhYpD3AqV?smlzo(fG1w2=hxUaGKa9W6d5tuor& z?eay!WcGw$Hp9=(gNEbI8?;LEGdIa*O42z~g4t~UdjD+LV)=tswa=JR>69UPyg9*a zxP@rZm6#6DsvsP_T%0xRY5u}sHo{A~{@HA)#4!S=4V01j!nDK%!U7Qde2Tnr$g#(G z#@$Yv*1@o6_#={E60Ly9y(bO;0D$Q{Cz`Z29c}t4iitdBdQrRvVMBf}ySv@rq$|e0 zi`MnShLX5Im@;wakQX^JgcD65l1Dg_v1ReA5DpXtv-{nowQe0&Nq9+Oz@a=ePw>2G zG&?VEw{negGH+-!Cc{^w{H)C~O|bO6GeILR@3QT*UG&u0*5Vv(}OnW0O^!gOaS&iwSv&C0O;r5A{@5$a7y-b|hn+ar>%jbyG z*py9X(hu;)ZC0(z;CJ;`^a~3L;U$S0jd2%lA#PH*f85A?;fkE?iuouXqTybA>^kW* zSvL3CP-9w;I`-eHcD43rN)UGR!7&1_E5j=ME|RLn2c_dU(J-x=+#YFF#^uN+l?1eD1W!hxdXmqn|y-dB`p>$r%K;Dm#ag+!L0S#3Eu+&1pojp@3LKJJK+j_7a@T1T<&v|_9vhp9q!ccDBe9x+c)5bQXjyIcl;!}(I| zr-3d=BZATusy!zE)kr7ebCTw|GOQ|^g(-h-2@$G$6iEPIlh#&gZ}!?_ zp>@$G{S<2>ZtW>lhtlnnu0uC}a9oL%eomh?nQm3PTAO#+wZt~iQHeIpl3lL-K^LAwYCi5xd8TXMM_YoiIX(+d7-FN(+K@SB0 z0CXkTQB#fQXs9tQ-#hoV|L$%BF{r3Du4~^i9l>;-UxL<9_4vt471pyLMitd={<$|y zhb?-%`mTnR(ci3l+jJPju%dp%aaLpe#@c|N0^t8gt}d)M@ANrHUo1mmMf(CI0mzz_ z#slL&9)h%=cAe|(BUgh8N*9>FSKQeL9uP5)p)*hzC=3(^3Im0K5}SDn-G0f=c*^~H z%3%NHI^!u3iuqHSKp>reDihI%&?5TKW{HGY3I72F&^U7mkHRwm0000RCog6)inJEz2AlnOM0*Gy)bt7^pmr02U-U zpdt>0O0X8C{F!f6!*8ctpR(51^4GIn%l=5%PmQ$5epk8S&h_PII@WCY&p5e5Y0}#3 RM<0TG=;`X`vd$@?2>?6+W`_U( diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_info.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_info.png deleted file mode 100755 index 37be9214b685bc31be05f843a2c0a62eec51a528..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651 zcmV;60(AX}P)k)h0m}oJEcY=%vP7s@8MV2I%UTMR)D=;=I#fWuiV-Xz<>P76(?Q;wyasct6J(;2ap(&Ub=itaL#$vI}|>g2OMSr~j!oT-ElMS7SZ zRMOGO676Ksl1^MF{hB4FJkEBKwa40$n)k1CKu0py;#n?0>TzP5N9hubI8hq%(FsU} zMzVg2Jb*}|^2*eKRwQ~yW3xd?ziRr`6-b4eq;N~4D;LEv=ez*TNl+=IH|UnP+_RO^ zun8q~-}eTzFWZ4|c*Wmh(4jY=Pz?L`@QPKne{Z6`TunE(MXx}`RJO`VqT04spzXv+ zC&Q~>IVZy-y%@ zd-uTT4&)XXb?NX4q)UhU;_3$EzPLK29}1K`{cumvT!GY956z{p=8}A4+aPlrMPplO zYljU#jUC6>J+QKWq-X!o)Bmxs{eyG+R}1zpU;JNB*}uTEf5qwR68P7Da80gRWiiD= lf+LD7S$b+=RC38Bm%lthjtat@p!NU&002ovPDHLkV1i}VLCXLD diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_profile_edit.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_profile_edit.png deleted file mode 100644 index 54bcbff9874b73897137e918db74e9fe89f02a88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 673 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 Z)%CR^rOMVWg8v4Hv7xy^iJo)#e*qDYNHhQd diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_toolbar_close.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_ic_toolbar_close.png deleted file mode 100644 index f54f4f9d1103017ba9e6f5444001dfe815cf70e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 499 zcmV004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00C=BL_t(&-tF2=j)O1^1z@*}a5!2nN*Sp?hZ|O}3l?ps zfjE9ENwB@l{4hYi30e}$)7WCj)Ne|9MI&z>BUfZRT^vVH%o&zOZ2+}*J_>9Xz z?IZ(71G17#934oIaQzefS_p3BXhF3kGe-}qArYJ!kd{Po>OdM2$*Bbi(%Xc$rwM6J zJ!pyKz_EblNG=>3C{J?XSV6hvapBlO%OoP1vxDYIOm0bm@+69b?NuFLv}7B5sW-Om zbEh(sdy}C2M}jK{2+;gD%Z22}aUywgCQ@xVK!9`!21)Yf&?J8jNm_$Lk=Ef%q@{9z z0NHb86KOq;kyHx#LvZq>fdjS9S9-sti_dbvgX5)Vk)zvXN2hCH1xI@hb?CX&9SsHz p2eOMF2?7+L00k&O0SeInwmXy-hQCk^XBq$i002ovPDHLkV1i=*zf%AJ diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_icon_no_connection.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_icon_no_connection.png deleted file mode 100644 index 7cb90c633eba4d493148adbdd38f22876077cd56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1645 zcmV-z29o)SP)46rMuVr*S2ljyZKx9B+m+ZGBe5CbNb9<(o<7i zU3G7DR9xVB*~u~)UY5x05(MUKX5-0KGuy}I`brSk51Gw(^8MfP{h#vvH}d`aa(zk0 zqw=#rzQ0qhrx4lgGMVgRp65-V>KU!AtrPmbU7y)pP%zTh%ywKDLtgt6xmvlNDi3m% zAP7dOT7`Jl$RN5%2S6tlU!u;j0_A98{r$td6;>E$n4|${-kmC-i2kN_saMWlTPv|Y_?Yt z(ab6?K%A3_wPAuaIQ}Lw*UJVvyNU`(#gKl*(m?J#{9p0#TQV6lr>Yj3nwln;H@$(` z=HhQ8=LY`^nbS=--85Q-h#|~+cV_!-;*8`zMSR!y?b^yUi0p#$G{;u)W^(yT(AvTV zdn2>C1l}ZHA0^{hB6}86M=WXizDdSI^8M#kHu&9*joE3H3&_nKh$RzZ9{a0|th~pG zM0P7=FH+!)DSy7fMA)E-%#O_FOjMrO)Iv1&558|UQk6~Ecp+^pj}qyVeLuV6HP>7- zLWPW5Z`I?A!>lXseLk~!F`N}>&XFo}csV)o+m1c=Re8-LTU*U^Dq^4tgtvnSaqL77 z7adBN_0G)p4_9G9-uyBmvxJHvz;h7kHNpBh;$IL-z65!t1_Fo{M^E-A@CTVpW(t)M zw6*D3nay>G=Z@0AE&AK^&U3LbAohYQNG=g(XA(nQ1!GmZ7a<+)N?{H|0pj2(-W&1`=u(Z~m=u8`tkRitA@{Iiw# zHDy?aB+@H^e3u7#alT@-@5$HSV+HlKyBD~ZH?lV-N#Dl<{tv6FXi*h8al6WZ*yKiyF{{f&?u(Mk z&W9Uw4`>EQ#y+uo?re5YB>g_?u&6{X&$?0$^O z8fAEHX8T~wiToUD32Ew?y0R3IXNjV!8ii6E%QQhU)%S%BY=}w%n0XKYSa|H%_VF#)PMw9JNcqxLPiwm>F=IwRljD_PL? zSUE&yf3%*-_ZKl+hL{^h+6dtSaXa$%Tf{Vna@UJ6D!7+&1X|Ct6EmAl(awe5X@{ZY zhDf_kkrp|)iErSQXlYQ60ZIWpxs2Z&IKg!)DnN)t*J!yL4v{$wo?D&nDswhSvvPS8 zw7^9jKBk7kU0SE6IZ;xm@l=%oinXw5=Sq?1KuN?!_L&lANs5u+FZ}U7z3<339Jmu*g6aJA%Z=hld$V@#&1sq;N zg{$HWq*yqj(C!sDh8BOtTW`|N%V3jkYs=1`nB#5CrZJzgB?DM>%;p0~RjS?rHQM*} z0wC?tS>!r%NrgT=fKd96!8gRDbTl9fsr3Xqqs^@wDNIW z8Ai6{sp_d`A5lU~&ZabJg_>Rw*#$ZH;J_5cwwC-Op*8O9cA2>G=BMiwQ-^jbY8ik00000NkvXXu0mjfq^T&o diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_icon_server_error.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_icon_server_error.png deleted file mode 100644 index 73895eb6139999c0a1f6bcebf6ea55cfe3537ff0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1702 zcmV;X23h%uP)&5o>|^uc3%?7Zvei>@8Qoz{+%B9H~6=B z2A(zYvGH@(S!YdXjI3;oJ)YSyv;4^H{%H&Z&tg0q@4&m7j^IS&R$`W`iR5#Tq5-@M z@5H;iG`U1HEs;Ae!Alr;k$?=41u}IRf(H()&qyTa5V>zK$dCY;ARA;XEx|o|+Nqf3 z0%rFE1{FAdfUJb%?D?NlRIT&LJbg{ErsoG%$`;9RL zwAc-tlt`|Ea9t4?8^%~D$<=CgW+HhM0(E6zj2LTS_L#`M20@wxud3T^#1fe0BM8u3 zkdH8SHIj+sYrMD_fw6-F1@}!~lS9;OaFOG}HtGq_7R$CAu&1AYxgj5v~&0>sMH2JgjiR9P> z{fY=?fusMmI2IEil8=bwVj@~Hqu3J=$$HGvEy0h9vUBE8r?U3`WQ;wHh$d^GJ32eF z^wb&yIP(wM>rTOY^4#9mYV~!9+$S3GY_H@2vJHxwJfd5-Zj&qIEEi&yw-v~~AeBHv zhYp=dEB!o1= z6WLpcIYg_F>#)%%!{@a-PMj^#;z-gW)jJr9t+~i8ikeMw$)3O zi0+Y>#$g-pvpv@sFSs3hik_etQoJ%x8=5v&GIXe&RflMMd_hq8D587*Td^LPfIp%+=9b3U4v-3$up_( zl$LDZSi^BwfZU4omPZlLnws)~;}*DECC)(qN#st=kfOU=Q%-OUq8})!7QX|{^e5RK zqAe>pZo!tgghk@jfdk!i8Di1fVHOl1@AECtj52u^L~=GFbr}QxzZW(8V6VO`i#^8b zoiWgVAdWQ`DF2r&jSxV6E9()dQg7xM1K$na>vgmu0DOs5 zR2xlPCosnC%`Be<>TT?+q3$p7RXxiMe3RpxFrE-#YLWnf6fR)qwOI<9lFoql+_6VD96jm zqCK&98;M|oG3jREt;G{BytDibgVIQkTLH1fHqgZW9J$h4CXH?e*r zUg4x4hmMz$>AQIGnmv>y~%2>-Q`msdu%ZDV9&h~#u*>}JXI wol9qC))pkPJ0`evWShCiVP+uP_=(zo0d#|MbuwoZ-~a#s07*qoM6N<$f@QxhGynhq diff --git a/apptentive/src/main/res/drawable-xxhdpi/apptentive_status_gear.png b/apptentive/src/main/res/drawable-xxhdpi/apptentive_status_gear.png new file mode 100755 index 0000000000000000000000000000000000000000..6e078877617f9fa9a23a93a11e588f8accd98e52 GIT binary patch literal 2034 zcmVV&{e#1E-`912 zpZmV<>(|rObreT&6h{(pJZ9nL=qd303H4w1Xy`X4z_GX(pT&K63jf8@oN?2z0UL1# zuEA_f7%km93QWc4>trNhA7-YE?Z(Ga#`WSZoH5#KsuWm=zLZ5aa3>}ujGckMH0^%_Tn5(Kr2Ee_S& z4fF8@ycy3+dFB%72D%D7ijz`gPr-65HrlryUWI>%W3U$w)RpP3|9?-NxIbgKg9IJG z@3Bg(~6I3VZ z+Ob~U2(cdvIzmnpNe_;}!iE*|tn={Qj*?R+=ymb~&~{P7W)a0N!fBXTm)j#Qiu3Vd z5tfwkv36teXb^Okh@Gm&9<0P91;PiBV_G4u_9A%FXrxC(ey57<-i$#kYg3;&BEZet zO~bgUYCc+(nUDWfOin}j)fm^NUeCvm3&`omtSX3@j8}-avrwcS3hJL$)-}+t=CY;!!%LH-kGReak;uz&&Jzgy`4UONzR=IfueF%TYKSi*&SNWiG zm)I4r#K|~L7}^Oq31{N1c*rwHb_hQbJK_|4759r5vk4!`S_sY&S9unO@gHHd8^2zB zq9{4t_)|$TnlXgCrKBMe{r)A8$LKwnk zY{%@B=igsYZZ9rO82_m@*3i)D%q)VY3Ikad-^(EUM(Iap7&qgDmT?nA$}|r(yemQO zyW3a;JdLxn2D#EAsQ?U4Gj*z|-C9f~2WHTPobc+c4l!h9< zsO3mty!5I|D@I=1$H#Mo^h;=C!KDS2Y{h%)O1v=n{Ul#qGLNXh9D1-U$|OBp{;R9DNO4;P8Dby8~O zF)6+ZULpeQqPVqPV#Z+s{#sDbew>~%*9%0%K2$>S)%aV&-?vF|NJXZzzl03J5BnUZ zE7}Ahg4J7<^MwcldvXRzcbAwe$%gdeqLlfkiL^+&cueHE6Pqxa1--ETaJyJ1Jq^(_ zf<+vVQLa%wk(Y)IvN92(^E53FQv@~KgO{evKN+{QG4Cn~M?iGUetiV`w&E9LM2a=hGZlWysuJ^EBgOp}U9)9uTOPiYN={wi1l7HftukuhxK4H_$e@&K7!!pd zue!RD-$#V2D-`&+ga*x~mvOoDo9ABXIio9$%oL>I#YG5uk$8Jmp-&{r5*r4v#KG>w zkg#LV$`6b9Y^ma&av5yPC8tS=s&0h_c4K9Ryt6&y_dJYKQ=VNQsx6(s?S%-cE3!yf z^vzAb2aK#^bqMc~&@^6`IUB!{?r_df-YZW+pSVP}h>GmDMf9J4yb2Kafe|XVPeueS z-R8`~A4e#=fvdGy!7V~icSVZcBg@}7Sms20$H;H28t(51F)a#Ts+#8T@5^!R#b;3M z76Mz*hu4n=LB~r^LzKl6Qc6X_q0GxDmce#a*qH(ZU8Y(eWDDlD$Y^{DRb?m15I#8? z1Z`BU2U`=(1aq2XtWvEn*1&*_;${`(T&8;WzJVv}^Dk4pYpfmoP$xR>Wv4)^La*|9 zsIutC8#+PId{JgO+_3`}cY>hFA|ZY_W3Q;!B_{Q%B5IBFa`K?Kx_9cFtx7^o?Cytz z!B3JsAf-fJH9?a_E~fRC8NdyqKj%V`gB}f%hQt@p=ZSLn5@Cp&6KTWvpp-bUQ$)Q@ zc&B?rDDd2bXD$&fbDhE-T%Mxe1)?su3#&WN$g>p~FFto%BBi!nf1|(bAVE8DZibGN z#0P-YfBsYj>LhL&D}oMrh*HnS0t+3$6`~h=xo{SrIN}NF>gwteb@V)}Nf>v&{BYxl zAm|%8i`*)qL?rS+cjSys><>DufS2LR(vQsbQtIO3^Ma(F=bEU~uhm9R_8|+AI(?_; z``IWyK*{t?gy*}nPVi5KuQgYv(x!(BMB?o^1)rT=-%W*{KZ>I`io*u~2gtCkw*xn* Qu>b%707*qoM6N<$g50Ir-v9sr literal 0 HcmV?d00001 diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_checkmark_alt_40dp.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_checkmark_alt_40dp.png deleted file mode 100644 index b85458de72d6eb1fadf162c63f35303ea358ef98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5063 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 diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_generic_file_thumbnail.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_generic_file_thumbnail.png deleted file mode 100755 index f3eccddd19b81f2091596d793e654c73208304f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2868 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 O0im7TQTLAq)BXc+h}s|k diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_back_preview.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_back_preview.png deleted file mode 100644 index 16b0f1d40912926dd6d0b4e080c9f6e5c81c77ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 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 P00000NkvXXu0mjfBF&h3 diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_composing_close.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_composing_close.png deleted file mode 100644 index ff3f7e449e7d4d048839eb8f6aa83c41136fa304..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 923 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGojKx9jP7LeL$-HD>U=HxF(ijJ@%(;!d8~?D*}s-`4KGKY#D>%^metbIVp= zef79#=N>t}_H#;UT5YQt4)DMAm#7h!yZg1OHf=h?kJn$NEb|XPzEgU4^Kuq*M*a`Z zy7POZ4l)0kv3WI%I3wqejS60zoIecH%{iYjxji`Ev_hrlK)>Z~kBFl$!puvifZ;(JmBTj{UMV@XX*v58ZE|R)dlhS zyyE%oQdgY>gi38C&0UnX>VCgn)8EYcWuqIrJm+OjhoG547gE;*9&*1lg=xZ!g)C7& zt}yke1RP#2z9E3g_KzCNnJE`oYObW!g|alQ@>O^Ett{gm@ge!nk$A?f4Xhs)+gEXJ zVd8mUuGkpVpjcDIS;A!W@VK`^sg_dR)oC`*4;@$SmGD=8JS|}V_qojW|F)lUf+4faTHVu_W&McdCap5cm|A2WLjc@qf+S=71 z)Zo=)*!kgv-%-{nEWt%<1kas3>&kkCAt?Eb%G-Q15#az~m$Mu9C;of7Scyr3!Qjb< z)<1uHcQY(IG_$DFD2CNQ?98;uvl+HIJvQe%@3V6!M}pP{{(b*vsk#?4>a>1MTpnlq zB&#me#lrl*vB;exOq_n{_pggQI^=gs)b9Qxy(nkvGdI)p6z(LxQdKc3%Ql*I^b-$f z`kg~Ld`}kIJqs3Kliryw!28E;#>AH=p2j&!+;?SQQdbE$mdKI;Vst E0QBy5wg3PC diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_info.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_info.png deleted file mode 100755 index ca690445f38d226f7fe0174e83a80363de89396b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 854 zcmV-c1F8IpP)|J zK{H)UQRXc_S!0)Dj@f06pS-2a6kRl*&%kTxqsR|Df8z&5`lvlGp=W649{YG9ZJ&Fz zlW`k-4deX7i(&s5r^Z#%%&>`$xq3%hqc*&N8NKhz#+jG^*;MtpFcZG5=}y{}vLir(cKzdpY}<^-&3?&` zT?ymiUK;*sD_cud1+-{u-aj&Nu5eW;y84almFuAD*zQ$^p2l#nBf{`FG_Ae2 zC1G)pNpMs6`RPxQzcG2I0`l_L#-Fk)C{0cUGzmYu{*+@usc|ZxM)*1Y-@aKK0SH7< z4C}vUZs;{gX7W2=S$XRJ0RI;9A7b}43Or=M2LKNl040DA0H6c_=70|Xz#IUlfe!%S zG(~7`A3zZrfKmb<08mPR)B_&?ka|E?AwK|+Rs6!1Ut08wyMB3HZ*XWWCV|N(uvr(# zX4M|u!82m((<&h()_LF`fxd@Xt`2!9LW_Z1*^fbm=fr4o>*hE)-cuOe0k g_0@5krfHgH1<8XZp0D_U$p8QV07*qoM6N<$f@I^2-T(jq diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_profile_edit.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_profile_edit.png deleted file mode 100644 index ce269ca9a315a61ae1804943b2ebe3a047fc97e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 884 zcmV-)1B?8LP)Px&E=fc|RCodHnoDaGK@^3jT^PYf5LANVPEkY+0R@)^ACQf@c9B0KxbO#LBV^$| zdvzoDKo@~5Tu4AeM0dd`DoAt!BEtBcp*wVD80mD~>7MGU3n!KCuDmwiQ(xUP;jIEBKL+lBHYjVl zS3btP5`u&^>Px`Nk9?jR=}I6$jr=gkXFACDXjTG==`(Lx_8IBk zRx!+;3A+qS>JGjx8TuRKN--46#1acHjEKteBiL)uIRsT5POoyf@|OkI17$}Vb~{}z6CG9Gq8*(PA^AF2>|JFg5Lty!Bubs z)L~x<`W!q34-sQys7XM43OoRtVAM=GDYq$85pbA*+n|c=F2b0Ya#hZyDtt>o9B9OS zB2K#7Ou6s8BDiTB+y{Sw?7E_Ko?%GxbaN#m%o`5~wE6x4$8)`FD!Yfhi3IKWi)@B(T(#ZhqI~*qw zVLkf@%yS|X@)}=p73Y?|<1f&@)tK99|b5aT|;h+70{4@EKMU;Kxye3a^pXM1*3~B&i~K=0000< KMNUMnLSTZ=fQ*3v diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_remove_attachment.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_remove_attachment.png deleted file mode 100755 index 02481759634e499dbcca27e2830f42c6c4d7e6b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3853 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 diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_toolbar_close.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_ic_toolbar_close.png deleted file mode 100644 index 7b2a480a02138f7e1627c47c7810769c07d02987..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 662 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcg6p}rHd>I(3)EF2VS{N990fib~ zFff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9;eUJonf*W>XMsm#F#`j)FbFd;%$g$s zRKe%z;uunK>+Nmdyh8>8ZHbpxdC!t-6PsA@Az*9tuW|{ks)qI5Is(2vHs8$WDV#^lJw82zHADRtFfbG4gHTD`+TfU|z#4lOX$m0W5We-Q=O=n$W0Q z7uuIr=%3ieCeN^Mqu4w1{aY=VZaj|LHa}+~drgvrS>g%y26IV8{rSEYPrErM{n4Mp z-(4_IUuB8@=dO*4!X_uX5V?1HO6%{pS+`z&G2gTLp@3D==llE%%bt1rs9!l7u5jhta^Z@fm-)T; zCa)Lby!CVS3D2o+7tZl>>|*&_lj_u46Y4a##?>iv-;*-e)&&#g_eX{(Tsaf22-92i zY5URsj82yB8m)tB^F214S}yqJlPAmR8ZO1!mEx^`EEYazmfF+*$++&iuhN^1PniD+ zMf^-|Qi!h-vl5)~^Epf4zCTt50yloDHyPMJ_qvm?e1g3|Ri@pcL;t;BGO)*dw>VHG ulVHoYL5@A5pLxx3#%qrmUhk|rpuh24@WsQ^%4LDcg~8L+&t;ucLK6To`3n{R diff --git a/apptentive/src/main/res/drawable-xxxhdpi/apptentive_icon_no_connection.png b/apptentive/src/main/res/drawable-xxxhdpi/apptentive_icon_no_connection.png deleted file mode 100644 index bc93412e08dfb1b570eb2d2bf248e373e897c87e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2118 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 Wp7xYe@o}dB0000 + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_arrow_back.xml b/apptentive/src/main/res/drawable/apptentive_arrow_back.xml new file mode 100644 index 000000000..781d09fb7 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_arrow_back.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_attach_icon.xml b/apptentive/src/main/res/drawable/apptentive_attach_icon.xml new file mode 100644 index 000000000..ed34c3777 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_attach_icon.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_check_icon.xml b/apptentive/src/main/res/drawable/apptentive_check_icon.xml new file mode 100644 index 000000000..537d5d484 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_check_icon.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_close_x_dark.xml b/apptentive/src/main/res/drawable/apptentive_close_x_dark.xml new file mode 100644 index 000000000..97eb0c053 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_close_x_dark.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_close_x_light.xml b/apptentive/src/main/res/drawable/apptentive_close_x_light.xml new file mode 100644 index 000000000..d52ce8125 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_close_x_light.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_file_download.xml b/apptentive/src/main/res/drawable/apptentive_file_download.xml new file mode 100644 index 000000000..a55102ab5 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_file_download.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_file_icon.xml b/apptentive/src/main/res/drawable/apptentive_file_icon.xml new file mode 100644 index 000000000..49a3e94b3 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_file_icon.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_ic_action_attach_auto_mirror.xml b/apptentive/src/main/res/drawable/apptentive_ic_action_attach_auto_mirror.xml deleted file mode 100644 index e51201143..000000000 --- a/apptentive/src/main/res/drawable/apptentive_ic_action_attach_auto_mirror.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/apptentive/src/main/res/drawable/apptentive_ic_action_send_auto_mirror.xml b/apptentive/src/main/res/drawable/apptentive_ic_action_send_auto_mirror.xml deleted file mode 100644 index de4ebe320..000000000 --- a/apptentive/src/main/res/drawable/apptentive_ic_action_send_auto_mirror.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/apptentive/src/main/res/drawable/apptentive_ic_compose_auto_mirror.xml b/apptentive/src/main/res/drawable/apptentive_ic_compose_auto_mirror.xml deleted file mode 100644 index 852f38834..000000000 --- a/apptentive/src/main/res/drawable/apptentive_ic_compose_auto_mirror.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/apptentive/src/main/res/drawable/apptentive_ic_error.xml b/apptentive/src/main/res/drawable/apptentive_ic_error.xml new file mode 100644 index 000000000..26cd6fdf0 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_ic_error.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_ic_info.xml b/apptentive/src/main/res/drawable/apptentive_ic_info.xml new file mode 100644 index 000000000..c95990f38 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_ic_info.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_ic_no_connection.xml b/apptentive/src/main/res/drawable/apptentive_ic_no_connection.xml new file mode 100644 index 000000000..40fc54a5e --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_ic_no_connection.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_image_placeholder.xml b/apptentive/src/main/res/drawable/apptentive_image_placeholder.xml new file mode 100644 index 000000000..0aa0077c0 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_image_placeholder.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_listview_item_shadow.xml b/apptentive/src/main/res/drawable/apptentive_listview_item_shadow.xml deleted file mode 100644 index 6ae121537..000000000 --- a/apptentive/src/main/res/drawable/apptentive_listview_item_shadow.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/apptentive/src/main/res/drawable/apptentive_pencil_icon.xml b/apptentive/src/main/res/drawable/apptentive_pencil_icon.xml new file mode 100644 index 000000000..ba7c7370f --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_pencil_icon.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_person_icon_dark.xml b/apptentive/src/main/res/drawable/apptentive_person_icon_dark.xml new file mode 100644 index 000000000..50cda2200 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_person_icon_dark.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_person_icon_light.xml b/apptentive/src/main/res/drawable/apptentive_person_icon_light.xml new file mode 100644 index 000000000..5d9a674d6 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_person_icon_light.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_remove_button.xml b/apptentive/src/main/res/drawable/apptentive_remove_button.xml new file mode 100644 index 000000000..93d9e8fa3 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_remove_button.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apptentive/src/main/res/drawable/apptentive_remove_icon.xml b/apptentive/src/main/res/drawable/apptentive_remove_icon.xml new file mode 100644 index 000000000..aaa7f834c --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_remove_icon.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/apptentive/src/main/res/drawable/apptentive_send_icon.xml b/apptentive/src/main/res/drawable/apptentive_send_icon.xml new file mode 100644 index 000000000..bc82dbc74 --- /dev/null +++ b/apptentive/src/main/res/drawable/apptentive_send_icon.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/apptentive/src/main/res/layout/apptentive_about.xml b/apptentive/src/main/res/layout/apptentive_about.xml index 57dd7f50f..b40347f7d 100644 --- a/apptentive/src/main/res/layout/apptentive_about.xml +++ b/apptentive/src/main/res/layout/apptentive_about.xml @@ -7,6 +7,7 @@ --> @@ -39,7 +40,7 @@ android:paddingLeft="10dp" android:paddingRight="10dp" android:contentDescription="Close" - android:src="@drawable/apptentive_ic_toolbar_close" + app:srcCompat="@drawable/apptentive_close_x_light" android:background="?android:attr/selectableItemBackground" android:scaleType="fitCenter" android:tint="?android:attr/textColorPrimaryInverse"/> @@ -63,12 +64,14 @@ + android:text="@string/apptentive_about_description" + android:focusable="true"/> + android:text="@string/apptentive_about_privacy" + android:focusable="true"/>