Browse Source

Version 4.5-beta5

Threema 5 năm trước cách đây
mục cha
commit
ed382045a0
100 tập tin đã thay đổi với 335 bổ sung171 xóa
  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,

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác