Parcourir la source

Version 4.5-beta5

Threema il y a 5 ans
Parent
commit
ed382045a0
100 fichiers modifiés avec 335 ajouts et 171 suppressions
  1. 1 0
      .gitignore
  2. 1 0
      README.md
  3. 38 5
      app/build.gradle
  4. 1 1
      app/src/androidTest/java/ch/threema/app/DangerousTest.java
  5. 1 1
      app/src/androidTest/java/ch/threema/app/ScreenshotTakingRule.java
  6. 1 1
      app/src/androidTest/java/ch/threema/app/TestApplication.java
  7. 1 1
      app/src/androidTest/java/ch/threema/app/TestFastlaneOnly.java
  8. 1 1
      app/src/androidTest/java/ch/threema/app/TestHelpers.java
  9. 1 1
      app/src/androidTest/java/ch/threema/app/ThreemaTestRunner.java
  10. 1 1
      app/src/androidTest/java/ch/threema/app/backuprestore/csv/BackupServiceTest.java
  11. 1 1
      app/src/androidTest/java/ch/threema/app/emojis/MarkupParserTest.java
  12. 1 1
      app/src/androidTest/java/ch/threema/app/testutils/InstructionUtil.java
  13. 1 1
      app/src/androidTest/java/ch/threema/app/testutils/RecyclerViewMatcher.java
  14. 1 1
      app/src/androidTest/java/ch/threema/app/utils/BackgroundErrorNotificationTest.java
  15. 1 1
      app/src/androidTest/java/ch/threema/app/utils/TextUtilTest.java
  16. 2 2
      app/src/androidTest/java/ch/threema/app/voip/SdpTest.java
  17. 1 1
      app/src/androidTest/java/ch/threema/app/voip/VoipStatusMessageTest.java
  18. 1 1
      app/src/androidTest/java/ch/threema/app/webclient/activities/SessionsActivityTest.java
  19. 1 1
      app/src/androidTest/java/ch/threema/app/webclient/converter/MessageTest.java
  20. 1 1
      app/src/androidTest/java/ch/threema/app/webclient/converter/MsgpackTest.java
  21. 1 1
      app/src/androidTest/java/ch/threema/logging/backend/DebugLogFileBackendTest.java
  22. 1 1
      app/src/main/java/androidx/appcompat/widget/PopupMenuWrapper.java
  23. 1 1
      app/src/main/java/androidx/core/app/FixedJobIntentService.java
  24. 1 1
      app/src/main/java/ch/threema/annotation/SameThread.java
  25. 1 1
      app/src/main/java/ch/threema/app/AutostartService.java
  26. 7 1
      app/src/main/java/ch/threema/app/BuildFlavor.java
  27. 1 1
      app/src/main/java/ch/threema/app/FcmListenerService.java
  28. 1 1
      app/src/main/java/ch/threema/app/FcmRegistrationIntentService.java
  29. 1 1
      app/src/main/java/ch/threema/app/QRScannerUtil.java
  30. 1 1
      app/src/main/java/ch/threema/app/RecipientChooserTargetService.java
  31. 49 4
      app/src/main/java/ch/threema/app/ThreemaApplication.java
  32. 1 1
      app/src/main/java/ch/threema/app/ThreemaLicensePolicy.java
  33. 1 1
      app/src/main/java/ch/threema/app/actions/LocationMessageSendAction.java
  34. 1 1
      app/src/main/java/ch/threema/app/actions/SendAction.java
  35. 1 1
      app/src/main/java/ch/threema/app/actions/TextMessageSendAction.java
  36. 1 1
      app/src/main/java/ch/threema/app/activities/AboutActivity.java
  37. 1 1
      app/src/main/java/ch/threema/app/activities/AddAccountActivity.java
  38. 1 1
      app/src/main/java/ch/threema/app/activities/AddContactActivity.java
  39. 1 1
      app/src/main/java/ch/threema/app/activities/AppLinksActivity.java
  40. 1 1
      app/src/main/java/ch/threema/app/activities/BackupAdminActivity.java
  41. 1 1
      app/src/main/java/ch/threema/app/activities/BiometricLockActivity.java
  42. 1 1
      app/src/main/java/ch/threema/app/activities/BlackListActivity.java
  43. 1 1
      app/src/main/java/ch/threema/app/activities/ComposeMessageActivity.java
  44. 8 1
      app/src/main/java/ch/threema/app/activities/ContactDetailActivity.java
  45. 1 1
      app/src/main/java/ch/threema/app/activities/ContactNotificationsActivity.java
  46. 1 1
      app/src/main/java/ch/threema/app/activities/CropImageActivity.java
  47. 1 1
      app/src/main/java/ch/threema/app/activities/DirectoryActivity.java
  48. 1 1
      app/src/main/java/ch/threema/app/activities/DisableBatteryOptimizationsActivity.java
  49. 1 1
      app/src/main/java/ch/threema/app/activities/DistributionListAddActivity.java
  50. 1 1
      app/src/main/java/ch/threema/app/activities/DummyActivity.java
  51. 1 1
      app/src/main/java/ch/threema/app/activities/EnterSerialActivity.java
  52. 1 1
      app/src/main/java/ch/threema/app/activities/ExcludedSyncIdentitiesActivity.java
  53. 1 1
      app/src/main/java/ch/threema/app/activities/ExportIDActivity.java
  54. 1 1
      app/src/main/java/ch/threema/app/activities/ExportIDResultActivity.java
  55. 1 1
      app/src/main/java/ch/threema/app/activities/GroupAdd2Activity.java
  56. 1 1
      app/src/main/java/ch/threema/app/activities/GroupAddActivity.java
  57. 8 1
      app/src/main/java/ch/threema/app/activities/GroupDetailActivity.java
  58. 1 1
      app/src/main/java/ch/threema/app/activities/GroupEditActivity.java
  59. 3 1
      app/src/main/java/ch/threema/app/activities/GroupNotificationsActivity.java
  60. 10 26
      app/src/main/java/ch/threema/app/activities/HomeActivity.java
  61. 1 1
      app/src/main/java/ch/threema/app/activities/IdentityListActivity.java
  62. 1 1
      app/src/main/java/ch/threema/app/activities/ImagePaintActivity.java
  63. 1 1
      app/src/main/java/ch/threema/app/activities/ImagePaintKeyboardActivity.java
  64. 1 1
      app/src/main/java/ch/threema/app/activities/LicenseActivity.java
  65. 1 1
      app/src/main/java/ch/threema/app/activities/MainActivity.java
  66. 1 1
      app/src/main/java/ch/threema/app/activities/MapActivity.java
  67. 1 1
      app/src/main/java/ch/threema/app/activities/MediaGalleryActivity.java
  68. 8 1
      app/src/main/java/ch/threema/app/activities/MediaViewerActivity.java
  69. 1 1
      app/src/main/java/ch/threema/app/activities/MemberChooseActivity.java
  70. 3 1
      app/src/main/java/ch/threema/app/activities/NotificationsActivity.java
  71. 1 1
      app/src/main/java/ch/threema/app/activities/PinLockActivity.java
  72. 1 1
      app/src/main/java/ch/threema/app/activities/PrivacyPolicyActivity.java
  73. 1 1
      app/src/main/java/ch/threema/app/activities/ProfilePicRecipientsActivity.java
  74. 1 1
      app/src/main/java/ch/threema/app/activities/QRCodeZoomActivity.java
  75. 1 1
      app/src/main/java/ch/threema/app/activities/RecipientListActivity.java
  76. 54 29
      app/src/main/java/ch/threema/app/activities/RecipientListBaseActivity.java
  77. 1 1
      app/src/main/java/ch/threema/app/activities/SMSVerificationLinkActivity.java
  78. 40 4
      app/src/main/java/ch/threema/app/activities/SendMediaActivity.java
  79. 1 1
      app/src/main/java/ch/threema/app/activities/ServerMessageActivity.java
  80. 1 1
      app/src/main/java/ch/threema/app/activities/SimpleWebViewActivity.java
  81. 1 1
      app/src/main/java/ch/threema/app/activities/StickerSelectorActivity.java
  82. 1 1
      app/src/main/java/ch/threema/app/activities/StopPassphraseServiceActivity.java
  83. 1 1
      app/src/main/java/ch/threema/app/activities/StorageManagementActivity.java
  84. 1 1
      app/src/main/java/ch/threema/app/activities/SupportActivity.java
  85. 12 6
      app/src/main/java/ch/threema/app/activities/TextChatBubbleActivity.java
  86. 1 1
      app/src/main/java/ch/threema/app/activities/ThreemaActivity.java
  87. 1 1
      app/src/main/java/ch/threema/app/activities/ThreemaAppCompatActivity.java
  88. 7 5
      app/src/main/java/ch/threema/app/activities/ThreemaToolbarActivity.java
  89. 1 1
      app/src/main/java/ch/threema/app/activities/UnlockMasterKeyActivity.java
  90. 1 1
      app/src/main/java/ch/threema/app/activities/VerificationLevelActivity.java
  91. 1 1
      app/src/main/java/ch/threema/app/activities/VoiceActionActivity.java
  92. 1 1
      app/src/main/java/ch/threema/app/activities/WhatsNew2Activity.java
  93. 1 1
      app/src/main/java/ch/threema/app/activities/WhatsNewActivity.java
  94. 1 1
      app/src/main/java/ch/threema/app/activities/WorkExplainActivity.java
  95. 1 1
      app/src/main/java/ch/threema/app/activities/ballot/BallotChooserActivity.java
  96. 1 1
      app/src/main/java/ch/threema/app/activities/ballot/BallotDetailActivity.java
  97. 1 1
      app/src/main/java/ch/threema/app/activities/ballot/BallotMatrixActivity.java
  98. 1 1
      app/src/main/java/ch/threema/app/activities/ballot/BallotOverviewActivity.java
  99. 1 1
      app/src/main/java/ch/threema/app/activities/ballot/BallotWizardActivity.java
  100. 1 1
      app/src/main/java/ch/threema/app/activities/ballot/BallotWizardFragment.java

+ 1 - 0
.gitignore

@@ -18,3 +18,4 @@ export/
 threema-android-*
 release/
 .cxx/
+patches/

+ 1 - 0
README.md

@@ -98,6 +98,7 @@ There are currently six product flavors:
 | `store_threema`     | Threema Store version                         | Threema Shop   |
 | `sandbox`           | Uses sandbox test environment¹                | Allowlist      |
 | `sandbox_work`      | Uses sandbox test environment¹                | Threema Work   |
+| `red`               | Uses sandbox test environment¹                | Threema Work   |
 
 For local testing, we recommend building the `store_google` or `store_threema` build variants.
 

+ 38 - 5
app/build.gradle

@@ -75,8 +75,8 @@ android {
         vectorDrawables.useSupportLibrary = true
         applicationId "ch.threema.app"
         testApplicationId 'ch.threema.app.test'
-        versionCode 658
-        versionName "4.5-beta4"
+        versionCode 659
+        versionName "4.5-beta5"
         resValue "string", "version_name_suffix", ""
         resValue "string", "app_name", "Threema"
         resValue "string", "uri_scheme", "threema"
@@ -141,7 +141,7 @@ android {
         }
         store_threema { }
         store_google_work {
-            versionName "4.5k-beta4"
+            versionName "4.5k-beta5"
             applicationId "ch.threema.app.work"
             testApplicationId 'ch.threema.app.work.test'
             resValue "string", "package_name", applicationId
@@ -151,7 +151,7 @@ android {
             resValue "string", "contact_action_url", "threema.id"
             resValue "string", "contacts_mime_type", "vnd.android.cursor.item/vnd.ch.threema.app.work.profile"
             resValue "string", "call_mime_type", "vnd.android.cursor.item/vnd.ch.threema.app.work.call"
-            resValue "integer", "max_group_size", "100"
+            resValue "integer", "max_group_size", "256"
             resValue "string", "shop_download_filename", ""
             buildConfigField "String", "CHAT_SERVER_PREFIX", "\"w-\""
             buildConfigField "String", "CHAT_SERVER_IPV6_PREFIX", "\"ds.\""
@@ -178,7 +178,7 @@ android {
             buildConfigField "byte[]", "SERVER_PUBKEY_ALT", "new byte[] {(byte) 0x5a, (byte) 0x98, (byte) 0xf2, (byte) 0x3d, (byte) 0xe6, (byte) 0x56, (byte) 0x05, (byte) 0xd0, (byte) 0x50, (byte) 0xdc, (byte) 0x00, (byte) 0x64, (byte) 0xbe, (byte) 0x07, (byte) 0xdd, (byte) 0xdd, (byte) 0x81, (byte) 0x1d, (byte) 0xa1, (byte) 0x16, (byte) 0xa5, (byte) 0x43, (byte) 0xce, (byte) 0x43, (byte) 0xaa, (byte) 0x26, (byte) 0x87, (byte) 0xd1, (byte) 0x9f, (byte) 0x20, (byte) 0xaf, (byte) 0x3c }"
         }
         sandbox_work {
-            versionName "4.5k-beta4"
+            versionName "4.5k-beta5"
             applicationId "ch.threema.app.sandbox.work"
             testApplicationId 'ch.threema.app.sandbox.work.test'
 
@@ -201,6 +201,36 @@ android {
             buildConfigField "byte[]", "SERVER_PUBKEY", "new byte[] {(byte) 0x5a, (byte) 0x98, (byte) 0xf2, (byte) 0x3d, (byte) 0xe6, (byte) 0x56, (byte) 0x05, (byte) 0xd0, (byte) 0x50, (byte) 0xdc, (byte) 0x00, (byte) 0x64, (byte) 0xbe, (byte) 0x07, (byte) 0xdd, (byte) 0xdd, (byte) 0x81, (byte) 0x1d, (byte) 0xa1, (byte) 0x16, (byte) 0xa5, (byte) 0x43, (byte) 0xce, (byte) 0x43, (byte) 0xaa, (byte) 0x26, (byte) 0x87, (byte) 0xd1, (byte) 0x9f, (byte) 0x20, (byte) 0xaf, (byte) 0x3c }"
             buildConfigField "byte[]", "SERVER_PUBKEY_ALT", "new byte[] {(byte) 0x5a, (byte) 0x98, (byte) 0xf2, (byte) 0x3d, (byte) 0xe6, (byte) 0x56, (byte) 0x05, (byte) 0xd0, (byte) 0x50, (byte) 0xdc, (byte) 0x00, (byte) 0x64, (byte) 0xbe, (byte) 0x07, (byte) 0xdd, (byte) 0xdd, (byte) 0x81, (byte) 0x1d, (byte) 0xa1, (byte) 0x16, (byte) 0xa5, (byte) 0x43, (byte) 0xce, (byte) 0x43, (byte) 0xaa, (byte) 0x26, (byte) 0x87, (byte) 0xd1, (byte) 0x9f, (byte) 0x20, (byte) 0xaf, (byte) 0x3c }"
 
+            manifestPlaceholders = [
+                actionUrl: "work.threema.ch",
+                uriScheme: "threemawork",
+                contactActionUrl: "threema.id"
+            ]
+        }
+        red { // Essentially like sandbox work, but with a different icon and accent color, used for internal testing
+            versionName "4.5r-beta5"
+            applicationId "ch.threema.app.red"
+            testApplicationId 'ch.threema.app.red.test'
+
+            resValue "string", "package_name", applicationId
+            resValue "string", "app_name", "Threema Red"
+            resValue "string", "uri_scheme", "threemawork"
+            resValue "string", "action_url", "work.threema.ch"
+            resValue "string", "contact_action_url", "threema.id"
+            resValue "string", "contacts_mime_type", "vnd.android.cursor.item/vnd.ch.threema.app.redwork.profile"
+            resValue "string", "call_mime_type", "vnd.android.cursor.item/vnd.ch.threema.app.redwork.call"
+            resValue "integer", "max_group_size", "100"
+            resValue "string", "shop_download_filename", ""
+
+            buildConfigField "String", "CHAT_SERVER_PREFIX", "\"w-\""
+            buildConfigField "String", "CHAT_SERVER_IPV6_PREFIX", "\"ds.\""
+            buildConfigField "String", "MEDIA_PATH", "\"ThreemaRed\""
+            buildConfigField "boolean", "CHAT_SERVER_GROUPS", "true"
+
+            buildConfigField "String", "CHAT_SERVER_SUFFIX", "\".0.test.threema.ch\""
+            buildConfigField "byte[]", "SERVER_PUBKEY", "new byte[] {(byte) 0x5a, (byte) 0x98, (byte) 0xf2, (byte) 0x3d, (byte) 0xe6, (byte) 0x56, (byte) 0x05, (byte) 0xd0, (byte) 0x50, (byte) 0xdc, (byte) 0x00, (byte) 0x64, (byte) 0xbe, (byte) 0x07, (byte) 0xdd, (byte) 0xdd, (byte) 0x81, (byte) 0x1d, (byte) 0xa1, (byte) 0x16, (byte) 0xa5, (byte) 0x43, (byte) 0xce, (byte) 0x43, (byte) 0xaa, (byte) 0x26, (byte) 0x87, (byte) 0xd1, (byte) 0x9f, (byte) 0x20, (byte) 0xaf, (byte) 0x3c }"
+            buildConfigField "byte[]", "SERVER_PUBKEY_ALT", "new byte[] {(byte) 0x5a, (byte) 0x98, (byte) 0xf2, (byte) 0x3d, (byte) 0xe6, (byte) 0x56, (byte) 0x05, (byte) 0xd0, (byte) 0x50, (byte) 0xdc, (byte) 0x00, (byte) 0x64, (byte) 0xbe, (byte) 0x07, (byte) 0xdd, (byte) 0xdd, (byte) 0x81, (byte) 0x1d, (byte) 0xa1, (byte) 0x16, (byte) 0xa5, (byte) 0x43, (byte) 0xce, (byte) 0x43, (byte) 0xaa, (byte) 0x26, (byte) 0x87, (byte) 0xd1, (byte) 0x9f, (byte) 0x20, (byte) 0xaf, (byte) 0x3c }"
+
             manifestPlaceholders = [
                 actionUrl: "work.threema.ch",
                 uriScheme: "threemawork",
@@ -245,6 +275,9 @@ android {
         sandbox_work {
             setRoot 'src/store_google_work'
         }
+        red {
+            setRoot 'src/red'
+        }
     }
 
     buildTypes {

+ 1 - 1
app/src/androidTest/java/ch/threema/app/DangerousTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/ScreenshotTakingRule.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/TestApplication.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/TestFastlaneOnly.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/TestHelpers.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/ThreemaTestRunner.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/backuprestore/csv/BackupServiceTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/emojis/MarkupParserTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/testutils/InstructionUtil.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/testutils/RecyclerViewMatcher.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/utils/BackgroundErrorNotificationTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/utils/TextUtilTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 2 - 2
app/src/androidTest/java/ch/threema/app/voip/SdpTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -67,7 +67,7 @@ public class SdpTest {
 		return new PeerConnectionClient.PeerConnectionParameters(
 			false,
 			false, false, false, false, false,
-			videoEnabled, videoEnabled,
+			videoEnabled, videoEnabled, true, true,
 			videoEnabled
 				? SdpPatcher.RtpHeaderExtensionConfig.ENABLE_WITH_ONE_AND_TWO_BYTE_HEADER
 				: SdpPatcher.RtpHeaderExtensionConfig.DISABLE,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/voip/VoipStatusMessageTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/webclient/activities/SessionsActivityTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/webclient/converter/MessageTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/app/webclient/converter/MsgpackTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/androidTest/java/ch/threema/logging/backend/DebugLogFileBackendTest.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/androidx/appcompat/widget/PopupMenuWrapper.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/androidx/core/app/FixedJobIntentService.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/annotation/SameThread.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/AutostartService.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 7 - 1
app/src/main/java/ch/threema/app/BuildFlavor.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -28,6 +28,7 @@ public class BuildFlavor {
 	private final static String FLAVOR_STORE_GOOGLE_WORK = "store_google_work";
 	private final static String FLAVOR_SANDBOX = "sandbox";
 	private final static String FLAVOR_SANDBOX_WORK = "sandbox_work";
+	private final static String FLAVOR_RED = "red";
 
 	public enum LicenseType {
 		NONE, GOOGLE, SERIAL, GOOGLE_WORK
@@ -106,6 +107,11 @@ public class BuildFlavor {
 					name = "Sandbox Work";
 					licenseType = LicenseType.GOOGLE_WORK;
 					break;
+				case FLAVOR_RED:
+					sandbox = true;
+					name = "Red";
+					licenseType = LicenseType.GOOGLE_WORK;
+					break;
 				default:
 					throw new RuntimeException("invalid flavor build " + BuildConfig.FLAVOR);
 			}

+ 1 - 1
app/src/main/java/ch/threema/app/FcmListenerService.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/FcmRegistrationIntentService.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/QRScannerUtil.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/RecipientChooserTargetService.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2016-2020 Threema GmbH
+ * Copyright (c) 2016-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 49 - 4
app/src/main/java/ch/threema/app/ThreemaApplication.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -40,8 +40,6 @@ import android.database.ContentObserver;
 import android.net.ConnectivityManager;
 import android.os.Build;
 import android.os.Environment;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.PowerManager;
 import android.os.StrictMode;
 import android.os.SystemClock;
@@ -80,9 +78,9 @@ import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 import androidx.appcompat.app.AppCompatDelegate;
 import androidx.core.content.ContextCompat;
-import androidx.core.os.HandlerCompat;
 import androidx.lifecycle.DefaultLifecycleObserver;
 import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LiveData;
 import androidx.lifecycle.ProcessLifecycleOwner;
 import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 import androidx.multidex.MultiDexApplication;
@@ -307,6 +305,7 @@ public class ThreemaApplication extends MultiDexApplication implements DefaultLi
 				.detectLeakedSqlLiteObjects()
 				.detectLeakedClosableObjects()
 				.penaltyLog()
+				.penaltyDeath()
 				.penaltyListener(Executors.newSingleThreadExecutor(), v -> {
 					logger.info("STRICTMODE VMPolicy: " + v.getCause());
 					logStackTrace(v.getStackTrace());
@@ -1083,6 +1082,52 @@ public class ThreemaApplication extends MultiDexApplication implements DefaultLi
 		}
 		try {
 			final WorkManager workManager = WorkManager.getInstance(context);
+			final NotificationService notificationService = serviceManager.getNotificationService();
+
+			LiveData<List<WorkInfo>> oneTimeLabelingWorkInfo;
+			LiveData<List<WorkInfo>> periodicTimeLabelingWorkInfo;
+
+			// observe worker states and cancel if blocked
+			oneTimeLabelingWorkInfo = workManager.getWorkInfosByTagLiveData(ImageLabelingWorker.UNIQUE_WORK_NAME);
+			periodicTimeLabelingWorkInfo = workManager.getWorkInfosByTagLiveData(WORKER_IMAGE_LABELS_PERIODIC);
+
+			oneTimeLabelingWorkInfo.observe(ProcessLifecycleOwner.get(), workInfos -> {
+				// If there are no matching work infos, do nothing
+				if (workInfos == null || workInfos.isEmpty()) {
+					return;
+				}
+
+				// We only care about the first output status.
+				// Every continuation has only one worker tagged TAG_OUTPUT
+				WorkInfo workInfo = workInfos.get(0);
+				WorkInfo.State state = workInfo.getState();
+				logger.debug("workstate one time label work " + state);
+				if (state == WorkInfo.State.BLOCKED) {
+					logger.info("Cancel image one time labeling work, worker is blocked");
+					workManager.cancelUniqueWork(ImageLabelingWorker.UNIQUE_WORK_NAME);
+					notificationService.showImageLabelingWorkerStuckNotification();
+				}
+			} );
+
+			periodicTimeLabelingWorkInfo.observe(ProcessLifecycleOwner.get(), workInfos -> {
+				// If there are no matching work infos, do nothing
+				if (workInfos == null || workInfos.isEmpty()) {
+					return;
+				}
+
+				// We only care about the first output status.
+				// Every continuation has only one worker tagged TAG_OUTPUT
+				WorkInfo workInfo = workInfos.get(0);
+				WorkInfo.State state = workInfo.getState();
+
+				logger.debug("workstate periodic label work " + state);
+				if (state == WorkInfo.State.BLOCKED) {
+					logger.info("Cancel periodic image labeling work, worker is blocked");
+					workManager.cancelUniqueWork(WORKER_IMAGE_LABELS_PERIODIC);
+					notificationService.showImageLabelingWorkerStuckNotification();
+				}
+			});
+
 
 			// Only run if storage and battery are both not low
 			final Constraints.Builder constraintsLabelingWork = new Constraints.Builder()

+ 1 - 1
app/src/main/java/ch/threema/app/ThreemaLicensePolicy.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/actions/LocationMessageSendAction.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/actions/SendAction.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/actions/TextMessageSendAction.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/AboutActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/AddAccountActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/AddContactActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/AppLinksActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/BackupAdminActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/BiometricLockActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/BlackListActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ComposeMessageActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 8 - 1
app/src/main/java/ch/threema/app/activities/ContactDetailActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -22,6 +22,7 @@
 package ch.threema.app.activities;
 
 import android.Manifest;
+import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -56,6 +57,7 @@ import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.UiThread;
 import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.view.menu.MenuBuilder;
 import androidx.fragment.app.Fragment;
 import androidx.lifecycle.LifecycleOwner;
 import androidx.palette.graphics.Palette;
@@ -624,6 +626,7 @@ public class ContactDetailActivity extends ThreemaToolbarActivity
 		contactEditDialog.show(getSupportFragmentManager(), DIALOG_TAG_EDIT);
 	}
 
+	@SuppressLint("RestrictedApi")
 	@Override
 	public boolean onCreateOptionsMenu(Menu menu) {
 		super.onCreateOptionsMenu(menu);
@@ -633,6 +636,10 @@ public class ContactDetailActivity extends ThreemaToolbarActivity
 		}
 
 		getMenuInflater().inflate(R.menu.activity_contact_detail, menu);
+		try {
+			MenuBuilder menuBuilder = (MenuBuilder) menu;
+			menuBuilder.setOptionalIconsVisible(true);
+		} catch (Exception ignored) {}
 
 		return true;
 	}

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ContactNotificationsActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/CropImageActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/DirectoryActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/DisableBatteryOptimizationsActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2016-2020 Threema GmbH
+ * Copyright (c) 2016-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/DistributionListAddActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/DummyActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/EnterSerialActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ExcludedSyncIdentitiesActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ExportIDActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ExportIDResultActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/GroupAdd2Activity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/GroupAddActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 8 - 1
app/src/main/java/ch/threema/app/activities/GroupDetailActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -51,6 +51,7 @@ import java.util.List;
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.view.menu.MenuBuilder;
 import androidx.appcompat.widget.Toolbar;
 import androidx.core.app.ActivityCompat;
 import androidx.core.app.ActivityOptionsCompat;
@@ -586,11 +587,17 @@ public class GroupDetailActivity extends GroupEditActivity implements SelectorDi
 		return super.onPrepareOptionsMenu(menu);
 	}
 
+	@SuppressLint("RestrictedApi")
 	@Override
 	public boolean onCreateOptionsMenu(Menu menu) {
 		super.onCreateOptionsMenu(menu);
 		getMenuInflater().inflate(R.menu.activity_group_detail, menu);
 
+		try {
+			MenuBuilder menuBuilder = (MenuBuilder) menu;
+			menuBuilder.setOptionalIconsVisible(true);
+		} catch (Exception ignored) {}
+
 		return true;
 	}
 

+ 1 - 1
app/src/main/java/ch/threema/app/activities/GroupEditActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 3 - 1
app/src/main/java/ch/threema/app/activities/GroupNotificationsActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -24,6 +24,7 @@ package ch.threema.app.activities;
 import android.os.Bundle;
 import android.view.View;
 
+import androidx.annotation.UiThread;
 import ch.threema.app.ThreemaApplication;
 import ch.threema.storage.models.GroupModel;
 
@@ -59,6 +60,7 @@ public class GroupNotificationsActivity extends NotificationsActivity {
 	}
 
 	@Override
+	@UiThread
 	protected void updateUI() {
 		super.updateUI();
 	}

+ 10 - 26
app/src/main/java/ch/threema/app/activities/HomeActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -68,10 +68,8 @@ import androidx.annotation.AnyThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.UiThread;
 import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.view.menu.MenuBuilder;
 import androidx.appcompat.widget.AppCompatImageView;
 import androidx.appcompat.widget.Toolbar;
-import androidx.core.view.MenuCompat;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentTransaction;
 import androidx.lifecycle.LifecycleOwner;
@@ -133,7 +131,6 @@ import ch.threema.app.utils.StateBitmapUtil;
 import ch.threema.app.utils.TestUtil;
 import ch.threema.app.voip.activities.CallActivity;
 import ch.threema.app.voip.services.VoipCallService;
-import ch.threema.app.webclient.Config;
 import ch.threema.app.webclient.activities.SessionsActivity;
 import ch.threema.client.ConnectionState;
 import ch.threema.client.ConnectionStateListener;
@@ -587,16 +584,17 @@ public class HomeActivity extends ThreemaAppCompatActivity implements
 					isWhatsNewShown = true; // make sure this is set false if no whatsnew activity is shown - otherwise pin lock will be skipped once
 
 					// Do not show whatsnew for users of the previous 4.0x version
-					int previous = preferenceService.getLatestVersion() % 1000;
+/*					int previous = preferenceService.getLatestVersion() % 1000;
 
-/*					if (previous < 494) {
-						Intent intent = new Intent(this, WhatsNewActivity.class);
+					if (previous < 494) {
+*/						Intent intent = new Intent(this, WhatsNewActivity.class);
 						startActivityForResult(intent, REQUEST_CODE_WHATSNEW);
 						overridePendingTransition(R.anim.abc_fade_in, R.anim.abc_fade_out);
-					} else {
-*/						isWhatsNewShown = false;
-/*					}
-*/					preferenceService.setLatestVersion(this);
+/*					} else {
+						isWhatsNewShown = false;
+					}
+*/
+					preferenceService.setLatestVersion(this);
 				}
 			}
 		}
@@ -1173,7 +1171,6 @@ public class HomeActivity extends ThreemaAppCompatActivity implements
 		}.execute();
 	}
 
-	@SuppressLint("RestrictedApi")
 	@Override
 	public boolean onCreateOptionsMenu(Menu menu) {
 		super.onCreateOptionsMenu(menu);
@@ -1181,19 +1178,7 @@ public class HomeActivity extends ThreemaAppCompatActivity implements
 		// Inflate the menu; this adds items to the action bar if it is present.
 		getMenuInflater().inflate(R.menu.activity_home, menu);
 
-		MenuCompat.setGroupDividerEnabled(menu, true);
-
-		try {
-			// restricted API
-			if (menu instanceof MenuBuilder) {
-				MenuBuilder menuBuilder = (MenuBuilder) menu;
-				menuBuilder.setOptionalIconsVisible(true);
-
-				ConfigUtils.themeMenu(menu, ConfigUtils.getColorFromAttribute(this, R.attr.textColorSecondary));
-			}
-		} catch (Exception e) {
-			logger.error("Exception", e);
-		}
+		ConfigUtils.addIconsToOverflowMenu(this, menu);
 
 		return true;
 	}
@@ -1567,7 +1552,6 @@ public class HomeActivity extends ThreemaAppCompatActivity implements
 						return;
 					}
 					this.startMainActivity(null);
-
 					showWhatsNew();
 				}
 				break;

+ 1 - 1
app/src/main/java/ch/threema/app/activities/IdentityListActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ImagePaintActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2016-2020 Threema GmbH
+ * Copyright (c) 2016-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ImagePaintKeyboardActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/LicenseActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/MainActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/MapActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2019-2020 Threema GmbH
+ * Copyright (c) 2019-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/MediaGalleryActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 8 - 1
app/src/main/java/ch/threema/app/activities/MediaViewerActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -53,6 +53,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.view.menu.MenuBuilder;
 import androidx.core.app.ActivityCompat;
 import androidx.core.view.ViewCompat;
 import androidx.fragment.app.Fragment;
@@ -369,12 +370,18 @@ public class MediaViewerActivity extends ThreemaToolbarActivity {
 		}
 	}
 
+	@SuppressLint("RestrictedApi")
 	@Override
 	public boolean onCreateOptionsMenu(Menu menu) {
 		super.onCreateOptionsMenu(menu);
 
 		getMenuInflater().inflate(R.menu.activity_media_viewer, menu);
 
+		try {
+			MenuBuilder menuBuilder = (MenuBuilder) menu;
+			menuBuilder.setOptionalIconsVisible(true);
+		} catch (Exception ignored) {}
+
 		if (AppRestrictionUtil.isShareMediaDisabled(this)) {
 			menu.findItem(R.id.menu_save).setVisible(false);
 			menu.findItem(R.id.menu_share).setVisible(false);

+ 1 - 1
app/src/main/java/ch/threema/app/activities/MemberChooseActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 3 - 1
app/src/main/java/ch/threema/app/activities/NotificationsActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -37,6 +37,7 @@ import android.widget.ImageView;
 import android.widget.ScrollView;
 import android.widget.TextView;
 
+import androidx.annotation.UiThread;
 import androidx.appcompat.widget.AppCompatRadioButton;
 import ch.threema.app.R;
 import ch.threema.app.ThreemaApplication;
@@ -224,6 +225,7 @@ public abstract class NotificationsActivity extends ThreemaActivity implements V
 		minusButton.setEnabled(enable);
 	}
 
+	@UiThread
 	protected void updateUI() {
 		boolean isMentionsOnly = mentionOnlyChatListService.has(this.uid);
 

+ 1 - 1
app/src/main/java/ch/threema/app/activities/PinLockActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/PrivacyPolicyActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ProfilePicRecipientsActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/QRCodeZoomActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/RecipientListActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 54 - 29
app/src/main/java/ch/threema/app/activities/RecipientListBaseActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -26,6 +26,7 @@ import android.annotation.SuppressLint;
 import android.app.SearchManager;
 import android.app.SearchableInfo;
 import android.content.ClipData;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -37,6 +38,7 @@ import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
+import android.text.TextUtils;
 import android.util.SparseArray;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -117,8 +119,13 @@ import ch.threema.storage.models.MessageType;
 import ch.threema.storage.models.data.LocationDataModel;
 
 import static ch.threema.app.activities.SendMediaActivity.MAX_SELECTABLE_IMAGES;
+import static ch.threema.app.ui.MediaItem.TYPE_TEXT;
+
+public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
+	CancelableHorizontalProgressDialog.ProgressDialogClickListener,
+	ExpandableTextEntryDialog.ExpandableTextEntryDialogClickListener,
+	SearchView.OnQueryTextListener {
 
-public class RecipientListBaseActivity extends ThreemaToolbarActivity implements CancelableHorizontalProgressDialog.ProgressDialogClickListener, ExpandableTextEntryDialog.ExpandableTextEntryDialogClickListener, SearchView.OnQueryTextListener {
 	private static final Logger logger = LoggerFactory.getLogger(RecipientListBaseActivity.class);
 
 	private final static int FRAGMENT_RECENT = 0;
@@ -408,33 +415,25 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 								if (!(textIntent.contains("---") && textIntent.contains("WhatsApp"))) {
 									// whatsapp forwards media as rfc822 with a footer
 									// strip this footer
-									mediaItems.add(new MediaItem(uri, MimeUtil.MIME_TYPE_TEXT, textIntent));
+									mediaItems.add(new MediaItem(uri, TYPE_TEXT, MimeUtil.MIME_TYPE_TEXT, textIntent));
 								}
 							}
 						}
 						if (type.equals("text/plain")) {
-							String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
-							String text = intent.getStringExtra(Intent.EXTRA_TEXT);
-							String textIntent;
-							if (subject != null && subject.length() > 0 && !subject.equals(text)) {
-								textIntent = subject + " - " + text;
-							}
-							else {
-								textIntent = text;
-							}
+							String textIntent = getTextFromIntent(intent);
 
 							if (uri != null) {
 								// send text as file
-								addMediaItem("x-text/plain", uri);
+								addMediaItem("x-text/plain", uri, null);
 								if (textIntent != null) {
 									captionText = textIntent;
 								}
 							} else if (textIntent != null) {
-								mediaItems.add(new MediaItem(uri, MimeUtil.MIME_TYPE_TEXT, textIntent));
+								mediaItems.add(new MediaItem(uri, TYPE_TEXT, MimeUtil.MIME_TYPE_TEXT, textIntent));
 							}
 						} else {
 							if (uri != null) {
-								if ("content".equalsIgnoreCase(uri.getScheme())) {
+								if (ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(uri.getScheme())) {
 									// query database for correct mime type as ACTION_SEND may have been called with a generic mime type such as "image/*"
 									String[] proj = {
 										DocumentsContract.Document.COLUMN_MIME_TYPE
@@ -448,7 +447,13 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 											}
 										}
 									} catch (Exception e) {
-										logger.error("Unable to query content provider", e);
+										String filemame = FileUtil.getFilenameFromUri(getContentResolver(), uri);
+										if (!TestUtil.empty(filemame)) {
+											String mimeType = FileUtil.getMimeTypeFromPath(filemame);
+											if (!TestUtil.empty(mimeType)) {
+												type = mimeType;
+											}
+										}
 									}
 								}
 
@@ -458,7 +463,10 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 									// force forwarding of jpegs as a file if requested
 									type = "x-threema/file";
 								}
-								addMediaItem(type, uri);
+
+								// if text was shared along with the media item, add that too
+								String textIntent = getTextFromIntent(intent);
+								addMediaItem(type, uri, textIntent);
 							}
 						}
 					} else {
@@ -470,9 +478,9 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 								CharSequence text = clipData.getItemAt(i).getText();
 
 								if (uri1 != null) {
-									addMediaItem(type, uri1);
+									addMediaItem(type, uri1, null);
 								} else if (!TestUtil.empty(text)) {
-									mediaItems.add(new MediaItem(uri, MimeUtil.MIME_TYPE_TEXT, text.toString()));
+									mediaItems.add(new MediaItem(uri, TYPE_TEXT, MimeUtil.MIME_TYPE_TEXT, text.toString()));
 								}
 							}
 						}
@@ -503,7 +511,7 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 
 					// skip user selection if recipient is already known
 					if (uri != null && "smsto".equals(uri.getScheme())) {
-						mediaItems.add(new MediaItem(uri, MimeUtil.MIME_TYPE_TEXT, intent.getStringExtra("sms_body")));
+						mediaItems.add(new MediaItem(uri, TYPE_TEXT, MimeUtil.MIME_TYPE_TEXT, intent.getStringExtra("sms_body")));
 
 						final ContactModel contactModel = ContactLookupUtil.phoneNumberToContact(this, contactService, uri.getSchemeSpecificPart());
 
@@ -537,7 +545,7 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 							{
 								String text = dataUri.getQueryParameter("text");
 								if (!TestUtil.empty(text)) {
-									mediaItems.add(new MediaItem(dataUri, MimeUtil.MIME_TYPE_TEXT, text));
+									mediaItems.add(new MediaItem(dataUri, TYPE_TEXT, MimeUtil.MIME_TYPE_TEXT, text));
 								}
 
 								String targetIdentity;
@@ -567,7 +575,7 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 								if (mimeType == null) {
 									mimeType = type;
 								}
-								addMediaItem(mimeType, uri);
+								addMediaItem(mimeType, uri, null);
 							}
 						}
 
@@ -603,8 +611,24 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 		setupUI();
 	}
 
-	private void addMediaItem(String mimeType, @NonNull Uri uri) {
-		if ("file".equals(uri.getScheme())) {
+	private String getTextFromIntent(Intent intent) {
+		String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
+		String text = intent.getStringExtra(Intent.EXTRA_TEXT);
+		String textIntent;
+		if (subject != null && subject.length() > 0 && !subject.equals(text)) {
+			textIntent = subject;
+			if (!TextUtils.isEmpty(text)) {
+				textIntent += " - " + text;
+			}
+		}
+		else {
+			textIntent = text;
+		}
+		return textIntent;
+	}
+
+	private void addMediaItem(String mimeType, @NonNull Uri uri, @Nullable String caption) {
+		if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(uri.getScheme())) {
 			String path = uri.getPath();
 			File applicationDir = new File(getApplicationInfo().dataDir);
 
@@ -622,7 +646,7 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 				}
 			}
 		}
-		mediaItems.add(new MediaItem(uri, mimeType, null));
+		mediaItems.add(new MediaItem(uri, mimeType, caption));
 	}
 
 	@SuppressLint("StaticFieldLeak")
@@ -732,11 +756,12 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 			MediaItem mediaItem = mediaItems.get(i);
 			mediaItem.setFilename(FileUtil.getFilenameFromUri(getContentResolver(), mediaItem));
 
-			if ("content".equals(mediaItem.getUri().getScheme())) {
+			if (ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(mediaItem.getUri().getScheme())) {
 				try {
 					File file = fileService.createTempFile("rcpt", null);
 					FileUtil.copyFile(mediaItem.getUri(), file, getContentResolver());
 					mediaItem.setUri(Uri.fromFile(file));
+					mediaItem.setDeleteAfterUse(true);
 				} catch (IOException e) {
 					logger.error("Unable to copy to tmp dir", e);
 				}
@@ -745,7 +770,7 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 	}
 
 	private void sendSharedMedia(final MessageReceiver[] messageReceivers, final Intent intent) {
-		if (messageReceivers.length == 1 && mediaItems.size() == 1 && MimeUtil.isTextFile(mediaItems.get(0).getMimeType())) {
+		if (messageReceivers.length == 1 && mediaItems.size() == 1 && TYPE_TEXT == mediaItems.get(0).getType()) {
 			intent.putExtra(ThreemaApplication.INTENT_DATA_TEXT, mediaItems.get(0).getCaption());
 			startComposeActivity(intent);
 		} else if (messageReceivers.length > 1 || mediaItems.size() > 0) {
@@ -786,10 +811,10 @@ public class RecipientListBaseActivity extends ThreemaToolbarActivity implements
 								break;
 							case VOICEMESSAGE:
 								// voice messages should always be forwarded as files in order not to appear to be recorded by the forwarder
-								sendMediaMessage(messageReceivers, uri, captionText, MediaItem.TYPE_NONE, MimeUtil.MIME_TYPE_AUDIO_AAC, FileData.RENDERING_DEFAULT);
+								sendMediaMessage(messageReceivers, uri, captionText, MediaItem.TYPE_FILE, MimeUtil.MIME_TYPE_AUDIO_AAC, FileData.RENDERING_DEFAULT);
 								break;
 							case FILE:
-								int mediaType = MediaItem.TYPE_NONE;
+								int mediaType = MediaItem.TYPE_FILE;
 								String mimeType = messageModel.getFileData().getMimeType();
 								int renderingType = messageModel.getFileData().getRenderingType();
 

+ 1 - 1
app/src/main/java/ch/threema/app/activities/SMSVerificationLinkActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 40 - 4
app/src/main/java/ch/threema/app/activities/SendMediaActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -26,6 +26,7 @@ import android.animation.Animator;
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -37,6 +38,7 @@ import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
 import android.provider.MediaStore;
 import android.text.Editable;
 import android.text.TextWatcher;
@@ -101,6 +103,7 @@ import ch.threema.app.ui.ComposeEditText;
 import ch.threema.app.ui.DebouncedOnClickListener;
 import ch.threema.app.ui.MediaItem;
 import ch.threema.app.ui.SendButton;
+import ch.threema.app.ui.TooltipPopup;
 import ch.threema.app.ui.VerificationLevelImageView;
 import ch.threema.app.ui.draggablegrid.DynamicGridView;
 import ch.threema.app.utils.AnimationUtil;
@@ -112,6 +115,7 @@ import ch.threema.app.utils.EditTextUtil;
 import ch.threema.app.utils.FileUtil;
 import ch.threema.app.utils.IntentDataUtil;
 import ch.threema.app.utils.MimeUtil;
+import ch.threema.app.utils.RuntimeUtil;
 import ch.threema.app.utils.TestUtil;
 import ch.threema.app.video.VideoTimelineCache;
 import ch.threema.base.ThreemaException;
@@ -211,7 +215,7 @@ public class SendMediaActivity extends ThreemaToolbarActivity implements
 						logger.info("%%% system window top " + insets.getSystemWindowInsetTop() + " bottom " + insets.getSystemWindowInsetBottom());
 						logger.info("%%% stable insets top " + insets.getStableInsetTop() + " bottom " + insets.getStableInsetBottom());
 
-						if (insets.getSystemWindowInsetBottom() == insets.getStableInsetBottom()) {
+						if (insets.getSystemWindowInsetBottom() <= insets.getStableInsetBottom()) {
 							onSoftKeyboardClosed();
 						} else {
 							onSoftKeyboardOpened(insets.getSystemWindowInsetBottom() - insets.getStableInsetBottom());
@@ -646,6 +650,34 @@ public class SendMediaActivity extends ThreemaToolbarActivity implements
 		} else {
 			this.backgroundLayout.setVisibility(View.VISIBLE);
 		}
+		maybeShowImageResolutionTooltip();
+	}
+
+	@UiThread
+	public void maybeShowImageResolutionTooltip() {
+		gridView.postDelayed(() -> {
+			if (sendMediaGridAdapter.holdsAdjustableImage() && !preferenceService.getIsImageResolutionTooltipShown()) {
+				int[] location = new int[2];
+				gridView.getLocationOnScreen(location);
+				location[0] += getResources().getDimensionPixelSize(R.dimen.grid_spacing);
+				location[1] += gridView.getHeight();
+
+				final TooltipPopup resolutionTooltipPopup = new TooltipPopup(this, R.string.preferences__image_resolution_tooltip_shown, R.layout.popup_tooltip_bottom_left_image_resolution, this, null);
+				resolutionTooltipPopup.show(this, gridView, getString(R.string.tooltip_image_resolution_hint), TooltipPopup.ALIGN_ABOVE_ANCHOR_ARROW_LEFT, location, 0);
+
+				new Handler().postDelayed(new Runnable() {
+					@Override
+					public void run() {
+						RuntimeUtil.runOnUiThread(new Runnable() {
+							@Override
+							public void run() {
+								resolutionTooltipPopup.dismissForever();
+							}
+						});
+					}
+				}, 4000);
+			}
+		}, 2000);
 	}
 
 	private void showSettingsDropDown(final View view, final MediaItem mediaItem) {
@@ -1027,7 +1059,6 @@ public class SendMediaActivity extends ThreemaToolbarActivity implements
 
 								final int position = addItemFromCamera(MediaItem.TYPE_IMAGE_CAM, cameraUri, exifOrientation);
 								showBigImage(position);
-
 								break;
 							}
 						}
@@ -1040,6 +1071,7 @@ public class SendMediaActivity extends ThreemaToolbarActivity implements
 					ArrayList<MediaItem> mediaItemsList = intent.getParcelableArrayListExtra(EXTRA_MEDIA_ITEMS);
 					if (mediaItemsList != null){
 						addItemsByMediaItem(mediaItemsList);
+						maybeShowImageResolutionTooltip();
 					}
 				default:
 					break;
@@ -1092,7 +1124,7 @@ public class SendMediaActivity extends ThreemaToolbarActivity implements
 	}
 
 	@UiThread
-	private int addItemFromCamera(int type, Uri imageUri, BitmapUtil.ExifOrientation exifOrientation) {
+	private int addItemFromCamera(int type, @NonNull Uri imageUri, BitmapUtil.ExifOrientation exifOrientation) {
 		if (mediaItems.size() >= MAX_SELECTABLE_IMAGES) {
 			Snackbar.make((View) gridView.getParent(), String.format(getString(R.string.max_images_reached), MAX_SELECTABLE_IMAGES), Snackbar.LENGTH_LONG).show();
 		}
@@ -1109,6 +1141,10 @@ public class SendMediaActivity extends ThreemaToolbarActivity implements
 			item.setMimeType(MimeUtil.MIME_TYPE_IMAGE_JPG);
 		}
 
+		if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(imageUri.getScheme())) {
+			item.setDeleteAfterUse(true);
+		}
+
 		if (sendMediaGridAdapter != null) {
 			sendMediaGridAdapter.add(item);
 		}

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ServerMessageActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/SimpleWebViewActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/StickerSelectorActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2016-2020 Threema GmbH
+ * Copyright (c) 2016-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/StopPassphraseServiceActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/StorageManagementActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2015-2020 Threema GmbH
+ * Copyright (c) 2015-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/SupportActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 12 - 6
app/src/main/java/ch/threema/app/activities/TextChatBubbleActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -55,6 +55,7 @@ import ch.threema.app.utils.ConfigUtils;
 import ch.threema.app.utils.IntentDataUtil;
 import ch.threema.app.utils.LinkifyUtil;
 import ch.threema.app.utils.MessageUtil;
+import ch.threema.app.utils.QuoteUtil;
 import ch.threema.app.utils.StateBitmapUtil;
 import ch.threema.base.ThreemaException;
 import ch.threema.storage.models.AbstractMessageModel;
@@ -186,16 +187,18 @@ public class TextChatBubbleActivity extends ThreemaActivity implements GenericAl
 			if (item.isChecked()) {
 				item.setChecked(false);
 				textView.setIgnoreMarkup(true);
-				textView.setText(messageModel.getBody());
+				setText(messageModel);
 			} else {
 				item.setChecked(true);
 				textView.setIgnoreMarkup(false);
-				textView.setText(messageModel.getBody());
+				setText(messageModel);
 			}
 			return true;
 		});
 		toolbar.setTitle(title);
 
+		ConfigUtils.addIconsToOverflowMenu(this, toolbar.getMenu());
+
 		// TODO: replace with "toolbarNavigationButtonStyle" attribute in theme as soon as all Toolbars have been switched to Material Components
 		toolbar.getNavigationIcon().setColorFilter(getResources().getColor(
 			ConfigUtils.getAppTheme(this) == ConfigUtils.THEME_DARK ?
@@ -210,9 +213,7 @@ public class TextChatBubbleActivity extends ThreemaActivity implements GenericAl
 		((ViewGroup) findViewById(R.id.footer)).addView(footerView);
 
 		textView = findViewById(R.id.text_view);
-		textView.setText(messageModel.getBody());
-
-		LinkifyUtil.getInstance().linkify(null, this, textView, messageModel, messageModel.getBody().length() < 80, false, null);
+		setText(messageModel);
 
 		// display date
 		CharSequence s = MessageUtil.getDisplayDate(this, messageModel, true);
@@ -227,6 +228,11 @@ public class TextChatBubbleActivity extends ThreemaActivity implements GenericAl
 		}
 	}
 
+	private void setText(AbstractMessageModel messageModel) {
+		textView.setText(QuoteUtil.getMessageBody(messageModel, false));
+		LinkifyUtil.getInstance().linkify(null, this, textView, messageModel, messageModel.getBody().length() < 80, false, null);
+	}
+
 	@Override
 	public void onYes(String tag, Object data) {
 		if (LinkifyUtil.DIALOG_TAG_CONFIRM_LINK.equals(tag)) {

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ThreemaActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ThreemaAppCompatActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2018-2020 Threema GmbH
+ * Copyright (c) 2018-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 7 - 5
app/src/main/java/ch/threema/app/activities/ThreemaToolbarActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,
@@ -282,9 +282,11 @@ public abstract class ThreemaToolbarActivity extends ThreemaActivity implements
 	}
 
 	public void onSoftKeyboardOpened(int softKeyboardHeight) {
-		logger.info("Soft keyboard opened. Height = " + softKeyboardHeight + " Min = " + minKeyboardSize);
+		logger.info("%%% Potential keyboard height = " + softKeyboardHeight + " Min = " + minKeyboardSize);
 
 		if (softKeyboardHeight >= minKeyboardSize) {
+			logger.info("%%% Soft keyboard open detected");
+
 			this.softKeyboardOpen = true;
 			saveSoftKeyboardHeight(softKeyboardHeight);
 
@@ -293,7 +295,7 @@ public abstract class ThreemaToolbarActivity extends ThreemaActivity implements
 	}
 
 	public void onSoftKeyboardClosed() {
-		logger.info("Soft keyboard closed");
+		logger.info("%%% Soft keyboard closed");
 
 		this.softKeyboardOpen = false;
 
@@ -351,11 +353,11 @@ public abstract class ThreemaToolbarActivity extends ThreemaActivity implements
 
 	public void saveSoftKeyboardHeight(int softKeyboardHeight) {
 		if (ConfigUtils.isLandscape(this)) {
-			logger.info("Keyboard height (landscape): " + softKeyboardHeight);
+			logger.info("%%% Keyboard height (landscape): " + softKeyboardHeight);
 			PreferenceManager.getDefaultSharedPreferences(this)
 				.edit().putInt(LANDSCAPE_HEIGHT, softKeyboardHeight).apply();
 		} else {
-			logger.info("Keyboard height (portrait): " + softKeyboardHeight);
+			logger.info("%%% Keyboard height (portrait): " + softKeyboardHeight);
 			PreferenceManager.getDefaultSharedPreferences(this)
 				.edit().putInt(PORTRAIT_HEIGHT, softKeyboardHeight).apply();
 		}

+ 1 - 1
app/src/main/java/ch/threema/app/activities/UnlockMasterKeyActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/VerificationLevelActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2013-2020 Threema GmbH
+ * Copyright (c) 2013-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/VoiceActionActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2016-2020 Threema GmbH
+ * Copyright (c) 2016-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/WhatsNew2Activity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/WhatsNewActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2017-2020 Threema GmbH
+ * Copyright (c) 2017-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/WorkExplainActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2020 Threema GmbH
+ * Copyright (c) 2020-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ballot/BallotChooserActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ballot/BallotDetailActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ballot/BallotMatrixActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ballot/BallotOverviewActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ballot/BallotWizardActivity.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

+ 1 - 1
app/src/main/java/ch/threema/app/activities/ballot/BallotWizardFragment.java

@@ -4,7 +4,7 @@
  *   |_| |_||_|_| \___\___|_|_|_\__,_(_)
  *
  * Threema for Android
- * Copyright (c) 2014-2020 Threema GmbH
+ * Copyright (c) 2014-2021 Threema GmbH
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License, version 3,

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff