diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 49b968fc89..79d55b37f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,6 +41,7 @@ + diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt index 198fc33372..afa6944645 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/WebRtcCallActivity.kt @@ -93,6 +93,7 @@ class WebRtcCallActivity : PassphraseRequiredActionBarActivity() { super.onNewIntent(intent) if (intent?.action == ACTION_ANSWER) { val answerIntent = WebRtcCallService.acceptCallIntent(this) + answerIntent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT ContextCompat.startForegroundService(this, answerIntent) } } @@ -106,6 +107,7 @@ class WebRtcCallActivity : PassphraseRequiredActionBarActivity() { setShowWhenLocked(true) setTurnScreenOn(true) } + window.addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/ContactListAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/ContactListAdapter.kt index 245b14da56..df2bc1c371 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/ContactListAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/ContactListAdapter.kt @@ -36,7 +36,7 @@ class ContactListAdapter( binding.nameTextView.text = contact.displayName binding.root.setOnClickListener { listener(contact.recipient) } - // TODO: When we implement deleting contacts (hide might be safest) then probably set a long-click listener here w/ something like: + // TODO: When we implement deleting contacts (hide might be safest for now) then probably set a long-click listener here w/ something like: /* binding.root.setOnLongClickListener { Log.w("[ACL]", "Long clicked on contact ${contact.recipient.name}") diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java index 088685241c..76b95d7b17 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java @@ -241,7 +241,21 @@ public class AttachmentManager { } public static void selectDocument(Activity activity, int requestCode) { - selectMediaType(activity, "*/*", null, requestCode); + Permissions.PermissionsBuilder builder = Permissions.with(activity); + + // The READ_EXTERNAL_STORAGE permission is deprecated (and will AUTO-FAIL if requested!) on + // Android 13 and above (API 33 - 'Tiramisu') we must ask for READ_MEDIA_VIDEO/IMAGES/AUDIO instead. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + builder = builder.request(Manifest.permission.READ_MEDIA_VIDEO) + .request(Manifest.permission.READ_MEDIA_IMAGES) + .request(Manifest.permission.READ_MEDIA_AUDIO); + } else { + builder = builder.request(Manifest.permission.READ_EXTERNAL_STORAGE); + } + builder.withPermanentDenialDialog(activity.getString(R.string.AttachmentManager_signal_requires_the_external_storage_permission_in_order_to_attach_photos_videos_or_audio)) + .withRationaleDialog(activity.getString(R.string.ConversationActivity_to_send_photos_and_video_allow_signal_access_to_storage), R.drawable.ic_baseline_photo_library_24) + .onAllGranted(() -> selectMediaType(activity, "*/*", null, requestCode)) // Note: We can use startActivityForResult w/ the ACTION_OPEN_DOCUMENT or ACTION_OPEN_DOCUMENT_TREE intent if we need to modernise this. + .execute(); } public static void selectGallery(Activity activity, int requestCode, @NonNull Recipient recipient, @NonNull String body) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt index a52d8458f1..cb9a19ffc1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.conversation.v2.utilities +import android.app.Application import android.content.Context import android.graphics.Typeface import android.text.Spannable diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java index db1076e472..639ea0db09 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/DisplayRecord.java @@ -78,8 +78,8 @@ public abstract class DisplayRecord { public int getReadReceiptCount() { return readReceiptCount; } public boolean isDelivered() { - return (deliveryStatus >= SmsDatabase.Status.STATUS_COMPLETE - && deliveryStatus < SmsDatabase.Status.STATUS_PENDING) || deliveryReceiptCount > 0; + return (deliveryStatus >= SmsDatabase.Status.STATUS_COMPLETE && + deliveryStatus < SmsDatabase.Status.STATUS_PENDING) || deliveryReceiptCount > 0; } public boolean isSent() { return MmsSmsColumns.Types.isSentType(type); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 2c70bff637..b281e0798b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -349,11 +349,17 @@ public class DefaultMessageNotifier implements MessageNotifier { builder.setThread(notifications.get(0).getRecipient()); builder.setMessageCount(notificationState.getMessageCount()); MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(notifications.get(0).getThreadId(),context); + + // TODO: Removing highlighting mentions in the notification because this context is the libsession one which + // TODO: doesn't have access to the `R.attr.message_sent_text_color` and `R.attr.message_received_text_color` + // TODO: attributes to perform the colour lookup. Also, it makes little sense to highlight the mentions using + // TODO: the app theme as it may result in insufficient contrast with the notification background which will + // TODO: be using the SYSTEM theme. builder.setPrimaryMessageBody(recipient, notifications.get(0).getIndividualRecipient(), - MentionUtilities.highlightMentions(text == null ? "" : text, - notifications.get(0).getThreadId(), - context), + //MentionUtilities.highlightMentions(text == null ? "" : text, notifications.get(0).getThreadId(), context), // Removing hightlighting mentions -ACL + text == null ? "" : text, notifications.get(0).getSlideDeck()); + builder.setContentIntent(notifications.get(0).getPendingIntent(context)); builder.setDeleteIntent(notificationState.getDeleteIntent(context)); builder.setOnlyAlertOnce(!signal); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt index 3ae3d30f01..cfe1f38f58 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt @@ -182,9 +182,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener { } fun broadcastWantsToAnswer(context: Context, wantsToAnswer: Boolean) { - val intent = Intent(ACTION_WANTS_TO_ANSWER) - .putExtra(EXTRA_WANTS_TO_ANSWER, wantsToAnswer) - + val intent = Intent(ACTION_WANTS_TO_ANSWER).putExtra(EXTRA_WANTS_TO_ANSWER, wantsToAnswer) LocalBroadcastManager.getInstance(context).sendBroadcast(intent) } @@ -506,9 +504,9 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener { } private fun handleAnswerCall(intent: Intent) { - val recipient = callManager.recipient ?: return - val pending = callManager.pendingOffer ?: return - val callId = callManager.callId ?: return + val recipient = callManager.recipient ?: return Log.e(TAG, "No recipient to answer in handleAnswerCall") + val pending = callManager.pendingOffer ?: return Log.e(TAG, "No pending offer in handleAnswerCall") + val callId = callManager.callId ?: return Log.e(TAG, "No callId in handleAnswerCall") val timestamp = callManager.pendingOfferTime if (callManager.currentConnectionState != CallState.RemoteRing) { @@ -526,9 +524,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener { insertMissedCall(recipient, true) terminate() } - if (didHangup) { - return - } + if (didHangup) { return } } callManager.postConnectionEvent(Event.SendAnswer) { @@ -686,7 +682,6 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener { private fun registerPowerButtonReceiver() { if (powerButtonReceiver == null) { powerButtonReceiver = PowerButtonReceiver() - registerReceiver(powerButtonReceiver, IntentFilter(Intent.ACTION_SCREEN_OFF)) } } @@ -719,7 +714,6 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener { } } - private fun handleCheckTimeout(intent: Intent) { val callId = callManager.callId ?: return val callState = callManager.currentConnectionState @@ -746,9 +740,9 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener { } if (!CallNotificationBuilder.areNotificationsEnabled(this) && type == TYPE_INCOMING_PRE_OFFER) { - // start an intent for the fullscreen + // Start an intent for the fullscreen call activity val foregroundIntent = Intent(this, WebRtcCallActivity::class.java) - .setFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_BROUGHT_TO_FRONT) + .setFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_BROUGHT_TO_FRONT or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) .setAction(WebRtcCallActivity.ACTION_FULL_SCREEN_INTENT) startActivity(foregroundIntent) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ViewUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/util/ViewUtilities.kt index 9c427e1f86..c0477825fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ViewUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ViewUtilities.kt @@ -19,6 +19,7 @@ import android.view.inputmethod.InputMethodManager import androidx.annotation.AttrRes import androidx.annotation.ColorRes import androidx.core.graphics.applyCanvas +import org.session.libsignal.utilities.Log import kotlin.math.roundToInt fun View.contains(point: PointF): Boolean { @@ -38,15 +39,19 @@ fun Context.getAccentColor() = getColorFromAttr(R.attr.colorAccent) // Method to grab the appropriate attribute for a message colour. // Note: This is an attribute, NOT a resource Id - see `getColorResourceIdFromAttr` for that. @AttrRes -fun getMessageTextColourAttr(messageIsOutgoing: Boolean): Int = - if (messageIsOutgoing) R.attr.message_sent_text_color else R.attr.message_received_text_color +fun getMessageTextColourAttr(messageIsOutgoing: Boolean): Int { + return if (messageIsOutgoing) R.attr.message_sent_text_color else R.attr.message_received_text_color +} // Method to get an actual R.id. resource Id from an attribute such as R.attr.message_sent_text_color etc. @ColorRes fun getColorResourceIdFromAttr(context: Context, attr: Int): Int { - val typedValue = TypedValue() - context.theme.resolveAttribute(attr, typedValue, true) - return typedValue.resourceId + val outTypedValue = TypedValue() + val successfullyFoundAttribute = context.theme.resolveAttribute(attr, outTypedValue, true) + if (successfullyFoundAttribute) { return outTypedValue.resourceId } + + Log.w("ViewUtils", "Could not find colour attribute $attr in theme - using grey as a safe fallback") + return R.color.gray50 } fun View.animateSizeChange(@DimenRes startSizeID: Int, @DimenRes endSizeID: Int, animationDuration: Long = 250) { diff --git a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index 1b431d62bb..af16d93f5a 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -842,7 +842,7 @@ interface TextSecurePreferences { getDefaultSharedPreferences(context).edit().putString(key, value).apply() } - private fun getIntegerPreference(context: Context, key: String, defaultValue: Int): Int { + fun getIntegerPreference(context: Context, key: String, defaultValue: Int): Int { return getDefaultSharedPreferences(context).getInt(key, defaultValue) }