diff --git a/gradle/verification-keyring.gpg b/gradle/verification-keyring.gpg
new file mode 100644
index 000000000..e69de29bb
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 840fdeb85..a78617212 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -13047,6 +13047,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/settings.gradle.kts b/settings.gradle.kts
index a79b08ad5..e8894d78c 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -5,6 +5,9 @@ pluginManagement {
gradlePluginPortal()
}
}
+plugins {
+ id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
+}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
diff --git a/src/com/android/messaging/datamodel/BugleNotifications.java b/src/com/android/messaging/datamodel/BugleNotifications.java
index 23c532fce..ea62c1b3c 100644
--- a/src/com/android/messaging/datamodel/BugleNotifications.java
+++ b/src/com/android/messaging/datamodel/BugleNotifications.java
@@ -134,7 +134,7 @@ public static void update(final String conversationId, final int coverage) {
LogUtil.v(TAG, "Update: conversationId = " + conversationId
+ " coverage = " + coverage);
}
- Assert.isNotMainThread();
+ Assert.isNotMainThread();
if (!PhoneUtils.getDefault().isDefaultSmsApp()) {
LogUtil.d(TAG, "Skipping notification: not the default SMS app");
@@ -157,10 +157,42 @@ public static void update(final String conversationId, final int coverage) {
private static void createMessageNotification(final String conversationId) {
final MessageNotificationState state = MessageNotificationState.getNotificationState();
final boolean softSound = DataModel.get().isNewMessageObservable(conversationId);
+
if (state == null) {
if (softSound && !TextUtils.isEmpty(conversationId)) {
- final Uri ringtoneUri = getNotificationRingtoneUriForConversationId(conversationId);
- playObservableConversationNotificationSound(ringtoneUri);
+
+ boolean isBlocked = false;
+
+ // 1. Access the database to check the participant's blocked status
+ final DatabaseWrapper db = DataModel.get().getDatabase();
+
+ // 2. Query the participant table for this specific conversation ID
+ final String query = "SELECT " + DatabaseHelper.ParticipantColumns.BLOCKED +
+ " FROM " + DatabaseHelper.PARTICIPANTS_TABLE +
+ " INNER JOIN " + DatabaseHelper.CONVERSATION_PARTICIPANTS_TABLE +
+ " ON " + DatabaseHelper.PARTICIPANTS_TABLE + "." + DatabaseHelper.ParticipantColumns._ID +
+ " = " + DatabaseHelper.CONVERSATION_PARTICIPANTS_TABLE + "." + DatabaseHelper.ConversationParticipantsColumns.PARTICIPANT_ID +
+ " WHERE " + DatabaseHelper.CONVERSATION_PARTICIPANTS_TABLE + "." + DatabaseHelper.ConversationParticipantsColumns.CONVERSATION_ID + " = ?";
+
+ try (android.database.Cursor cursor = db.rawQuery(query, new String[] { conversationId })) {
+ if (cursor != null) {
+ while (cursor.moveToNext()) {
+ // If any participant in this conversation has BLOCKED = 1, flag it
+ if (cursor.getInt(0) == 1) {
+ isBlocked = true;
+ break;
+ }
+ }
+ }
+ }
+
+ // 3. The Gatekeeper: Only play the sound if the conversation is NOT blocked
+ if (!isBlocked) {
+ final Uri ringtoneUri = getNotificationRingtoneUriForConversationId(conversationId);
+ playObservableConversationNotificationSound(ringtoneUri);
+ } else {
+ LogUtil.v(TAG, "Suppressed audio for blocked observable conversation.");
+ }
}
return;
}
@@ -232,7 +264,7 @@ private static Uri getNotificationRingtoneUriForConversationId(final String conv
* @param conversationId The conversation id (optional)
*/
private static String buildNotificationTag(final String name,
- final String conversationId) {
+ final String conversationId) {
final Context context = Factory.get().getApplicationContext();
if (conversationId != null) {
return context.getPackageName() + name + ":" + conversationId;
@@ -489,7 +521,7 @@ private static void playObservableConversationNotificationSound(final Uri ringto
final boolean silenced =
audioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
if (silenced) {
- return;
+ return;
}
final NotificationPlayer player = new NotificationPlayer(LogUtil.BUGLE_TAG);
@@ -522,12 +554,12 @@ public static void markMessagesAsRead(final String conversationId, final boolean
}
public static void notifyEmergencySmsFailed(final String emergencyNumber,
- final String conversationId) {
+ final String conversationId) {
final Context context = Factory.get().getApplicationContext();
final CharSequence line1 = MessageNotificationState.applyWarningTextColor(context,
context.getString(R.string.notification_emergency_send_failure_line1,
- emergencyNumber));
+ emergencyNumber));
final String line2 = context.getString(R.string.notification_emergency_send_failure_line2,
emergencyNumber);
final PendingIntent destinationIntent = UIIntents.get()
diff --git a/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java b/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java
index 21fdef56b..2ba2764af 100644
--- a/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java
+++ b/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java
@@ -136,10 +136,10 @@ public static void processMessageDownloaded(final int resultCode, final Bundle e
// This is called for fast failing downloading (due to airplane mode or mobile data )
public static void processMessageDownloadFastFailed(final String messageId,
- final Uri notificationUri, final String conversationId, final String participantId,
- final String contentLocation, final int subId, final String subPhoneNumber,
- final int statusIfFailed, final boolean autoDownload, final String transactionId,
- final int resultCode) {
+ final Uri notificationUri, final String conversationId, final String participantId,
+ final String contentLocation, final int subId, final String subPhoneNumber,
+ final int statusIfFailed, final boolean autoDownload, final String transactionId,
+ final int resultCode) {
Assert.notNull(messageId);
Assert.notNull(notificationUri);
Assert.notNull(conversationId);
@@ -163,8 +163,8 @@ public static void processMessageDownloadFastFailed(final String messageId,
}
public static void processDownloadActionFailure(final String messageId, final int status,
- final int rawStatus, final String conversationId, final String participantId,
- final int statusIfFailed, final int subId, final String transactionId) {
+ final int rawStatus, final String conversationId, final String participantId,
+ final int statusIfFailed, final int subId, final String transactionId) {
Assert.notNull(messageId);
Assert.notNull(conversationId);
Assert.notNull(participantId);
@@ -184,7 +184,7 @@ public static void processDownloadActionFailure(final String messageId, final in
}
public static void sendDeferredRespStatus(final String messageId, final String transactionId,
- final String contentLocation, final int subId) {
+ final String contentLocation, final int subId) {
final ProcessDownloadedMmsAction action = new ProcessDownloadedMmsAction();
final Bundle params = action.actionParameters;
params.putString(KEY_MESSAGE_ID, messageId);
@@ -473,7 +473,8 @@ private MessageData processResult(final int status, final int rawStatus, final U
// TODO: Also write these values to the telephony provider
mms.mRead = messageInFocusedConversation;
- mms.mSeen = messageInObservableConversation;
+ // Align with standard SMS: seen = read || messageInObservableConversation || blocked
+ mms.mSeen = mms.mRead || messageInObservableConversation || blockedSender;
// Translate to our format
message = MmsUtils.createMmsMessage(mms, conversationId, senderParticipantId,
diff --git a/src/com/android/messaging/datamodel/data/ConversationMessageData.java b/src/com/android/messaging/datamodel/data/ConversationMessageData.java
index 77e821f64..4303c2056 100644
--- a/src/com/android/messaging/datamodel/data/ConversationMessageData.java
+++ b/src/com/android/messaging/datamodel/data/ConversationMessageData.java
@@ -651,7 +651,9 @@ public static final String getNotificationQuerySql() {
+ MessageData.BUGLE_STATUS_INCOMING_COMPLETE + ", "
+ MessageData.BUGLE_STATUS_INCOMING_YET_TO_MANUAL_DOWNLOAD + ")"
+ " AND "
- + DatabaseHelper.MessageColumns.SEEN + " = 0)"
+ + DatabaseHelper.MessageColumns.SEEN + " = 0"
+ + " AND "
+ + DatabaseHelper.PARTICIPANTS_TABLE + "." + ParticipantColumns.BLOCKED + " = 0)"
+ ")"
+ NOTIFICATION_QUERY_SQL_GROUP_BY;
}
diff --git a/src/com/android/messaging/receiver/SmsReceiver.java b/src/com/android/messaging/receiver/SmsReceiver.java
index d96407d9b..3ae511b6f 100644
--- a/src/com/android/messaging/receiver/SmsReceiver.java
+++ b/src/com/android/messaging/receiver/SmsReceiver.java
@@ -153,8 +153,23 @@ public void onReceive(final Context context, final Intent intent) {
(Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action) ||
// TODO: update this with the actual constant from Telephony
"android.provider.Telephony.MMS_DOWNLOADED".equals(action))) {
- postNewMessageSecondaryUserNotification();
+ boolean isSenderBlocked = false;
+ final android.telephony.SmsMessage[] messages = getMessagesFromIntent(intent);
+ if (messages != null && messages.length > 0) {
+ final String senderAddress = messages[0].getOriginatingAddress();
+ if (senderAddress != null) {
+ final com.android.messaging.datamodel.DatabaseWrapper db = com.android.messaging.datamodel.DataModel.get().getDatabase();
+ isSenderBlocked = com.android.messaging.datamodel.BugleDatabaseOperations.isBlockedDestination(db, senderAddress);
+
+ }
+ }
+ if (isSenderBlocked) {
+ postNewMessageSecondaryUserNotification();
+ }else{
+ LogUtil.v(TAG,"SmsReceviver:Suppressed secondary user notification for blocked sender");
+ }
}
+
}
}