Messaging: Implement per conversation channels. Update API level to 28.

* Get rid of in-app settings for notifications, replaced by channels features
* Remove all the notification plumbing and dead code

Test: m, manual

Signed-off-by: Luca Stefani <luca.stefani.ge1@gmail.com>
Signed-off-by: Joey <joey@lineageos.org>
Signed-off-by: Danny Baumann <dannybaumann@web.de>
Signed-off-by: Arne Coucheron <arco68@gmail.com>
Signed-off-by: Lyubo <lyubodzhamov@gmail.com>
Change-Id: Idb39ca32751d40b3376934775d2119dd6cc7e297
This commit is contained in:
Luca Stefani
2019-02-14 18:03:48 +01:00
committed by Michael Bestas
parent 2fa1f81707
commit 4246987beb
66 changed files with 249 additions and 942 deletions

View File

@@ -17,6 +17,8 @@
package com.android.messaging.datamodel;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -74,10 +76,10 @@ import com.android.messaging.util.ConversationIdSet;
import com.android.messaging.util.ImageUtils;
import com.android.messaging.util.LogUtil;
import com.android.messaging.util.NotificationPlayer;
import com.android.messaging.util.NotificationsUtil;
import com.android.messaging.util.OsUtil;
import com.android.messaging.util.PendingIntentConstants;
import com.android.messaging.util.PhoneUtils;
import com.android.messaging.util.RingtoneUtil;
import com.android.messaging.util.ThreadUtil;
import com.android.messaging.util.UriUtil;
@@ -173,18 +175,10 @@ public class BugleNotifications {
}
Assert.isNotMainThread();
checkInitialized();
if (!shouldNotify()) {
if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
LogUtil.v(TAG, "Notifications disabled");
}
cancel(PendingIntentConstants.SMS_NOTIFICATION_ID);
return;
} else {
if ((coverage & UPDATE_MESSAGES) != 0) {
createMessageNotification(silent, conversationId);
}
if ((coverage & UPDATE_MESSAGES) != 0) {
createMessageNotification(silent, conversationId);
}
if ((coverage & UPDATE_ERRORS) != 0) {
MessageNotificationState.checkFailedMessages();
}
@@ -195,8 +189,7 @@ public class BugleNotifications {
*
*/
public static void playClassZeroNotification() {
final Uri ringtoneUri = RingtoneUtil.getNotificationRingtoneUri(null);
playObservableConversationNotificationSound(ringtoneUri);
playObservableConversationNotificationSound(null);
}
/**
@@ -297,56 +290,6 @@ public class BugleNotifications {
}
}
/**
* Returns {@code true} if incoming notifications should display a
* notification, {@code false} otherwise.
*
* @return true if the notification should occur
*/
private static boolean shouldNotify() {
// If we're not the default sms app, don't put up any notifications.
if (!PhoneUtils.getDefault().isDefaultSmsApp()) {
return false;
}
// Now check prefs (i.e. settings) to see if the user turned off notifications.
final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
final Context context = Factory.get().getApplicationContext();
final String prefKey = context.getString(R.string.notifications_enabled_pref_key);
final boolean defaultValue = context.getResources().getBoolean(
R.bool.notifications_enabled_pref_default);
return prefs.getBoolean(prefKey, defaultValue);
}
/**
* Returns {@code true} if incoming notifications for the given {@link NotificationState}
* should vibrate the device, {@code false} otherwise.
*
* @return true if vibration should be used
*/
public static boolean shouldVibrate(final NotificationState state) {
// The notification should vibrate if the global setting is turned on AND
// the per-conversation setting is turned on (default).
if (!state.getNotificationVibrate()) {
return false;
} else {
final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
final Context context = Factory.get().getApplicationContext();
final String prefKey = context.getString(R.string.notification_vibration_pref_key);
final boolean defaultValue = context.getResources().getBoolean(
R.bool.notification_vibration_pref_default);
return prefs.getBoolean(prefKey, defaultValue);
}
}
private static Uri getNotificationRingtoneUriForConversationId(final String conversationId) {
final DatabaseWrapper db = DataModel.get().getDatabase();
final ConversationListItemData convData =
ConversationListItemData.getExistingConversation(db, conversationId);
return RingtoneUtil.getNotificationRingtoneUri(
convData != null ? convData.getNotificationSoundUri() : null);
}
/**
* Returns a unique tag to identify a notification.
*
@@ -420,13 +363,15 @@ public class BugleNotifications {
private static void processAndSend(final NotificationState state, final boolean silent,
final boolean softSound) {
final Context context = Factory.get().getApplicationContext();
final NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context);
notifBuilder.setCategory(Notification.CATEGORY_MESSAGE);
// TODO: Need to fix this for multi conversation notifications to rate limit dings.
final String conversationId = state.mConversationIds.first();
String id = NotificationsUtil.DEFAULT_CHANNEL_ID;
if (NotificationsUtil.getNotificationChannel(context, conversationId) != null) {
id = conversationId;
}
final NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context, id);
notifBuilder.setCategory(Notification.CATEGORY_MESSAGE);
final Uri ringtoneUri = RingtoneUtil.getNotificationRingtoneUri(state.getRingtoneUri());
// If the notification's conversation is currently observable (focused or in the
// conversation list), then play a notification beep at a low volume and don't display an
// actual notification.
@@ -436,7 +381,7 @@ public class BugleNotifications {
"sCurrentlyDisplayedConversationId so NOT showing notification," +
" but playing soft sound. conversationId: " + conversationId);
}
playObservableConversationNotificationSound(ringtoneUri);
playObservableConversationNotificationSound(conversationId);
return;
}
state.mBaseRequestCode = state.mType;
@@ -449,7 +394,7 @@ public class BugleNotifications {
notifBuilder.setDeleteIntent(clearIntent);
}
updateBuilderAudioVibrate(state, notifBuilder, silent, ringtoneUri, conversationId);
updateBuilderAudioVibrate(state, notifBuilder, silent, conversationId);
// Set the content intent
PendingIntent destinationIntent;
@@ -607,8 +552,7 @@ public class BugleNotifications {
if (state == null) {
cancel(PendingIntentConstants.SMS_NOTIFICATION_ID);
if (softSound && !TextUtils.isEmpty(conversationId)) {
final Uri ringtoneUri = getNotificationRingtoneUriForConversationId(conversationId);
playObservableConversationNotificationSound(ringtoneUri);
playObservableConversationNotificationSound(conversationId);
}
return;
}
@@ -646,8 +590,8 @@ public class BugleNotifications {
private static void updateBuilderAudioVibrate(final NotificationState state,
final NotificationCompat.Builder notifBuilder, final boolean silent,
final Uri ringtoneUri, final String conversationId) {
int defaults = Notification.DEFAULT_LIGHTS;
final String conversationId) {
int defaults = Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE;
if (!silent) {
final BuglePrefs prefs = Factory.get().getApplicationPrefs();
final long latestNotificationTimestamp = prefs.getLong(
@@ -669,10 +613,6 @@ public class BugleNotifications {
if (lastTime == null
|| SystemClock.elapsedRealtime() - lastTime > sTimeBetweenDingsMs) {
sLastMessageDingTime.put(conversationId, SystemClock.elapsedRealtime());
notifBuilder.setSound(ringtoneUri);
if (shouldVibrate(state)) {
defaults |= Notification.DEFAULT_VIBRATE;
}
}
}
}
@@ -826,8 +766,14 @@ public class BugleNotifications {
notificationState.mNotificationBuilder.setLargeIcon(smallBitmap);
// Add a wearable page with no visible card so you can more easily see the photo.
String conversationId = notificationState.mConversationIds.first();
String id = NotificationsUtil.DEFAULT_CHANNEL_ID;
if (NotificationsUtil.getNotificationChannel(context, conversationId) != null) {
id = conversationId;
}
final NotificationCompat.Builder photoPageNotifBuilder =
new NotificationCompat.Builder(Factory.get().getApplicationContext());
new NotificationCompat.Builder(Factory.get().getApplicationContext(),
NotificationsUtil.DEFAULT_CHANNEL_ID);
final WearableExtender photoPageWearableExtender = new WearableExtender();
photoPageWearableExtender.setHintShowBackgroundOnly(true);
if (attachmentBitmap != null) {
@@ -982,6 +928,16 @@ public class BugleNotifications {
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_LIGHTS;
Context context = Factory.get().getApplicationContext();
NotificationsUtil.createNotificationChannelGroup(context,
NotificationsUtil.CONVERSATION_GROUP_NAME,
R.string.notification_channel_messages_title);
NotificationsUtil.createNotificationChannel(context,
NotificationsUtil.DEFAULT_CHANNEL_ID,
R.string.notification_channel_messages_title,
NotificationManager.IMPORTANCE_DEFAULT,
NotificationsUtil.CONVERSATION_GROUP_NAME);
notificationManager.notify(notificationTag, type, notification);
LogUtil.i(TAG, "Notifying for conversation " + conversationId + "; "
@@ -1105,7 +1061,7 @@ public class BugleNotifications {
* Play the observable conversation notification sound (it's the regular notification sound, but
* played at half-volume)
*/
private static void playObservableConversationNotificationSound(final Uri ringtoneUri) {
private static void playObservableConversationNotificationSound(final String conversationId) {
final Context context = Factory.get().getApplicationContext();
final AudioManager audioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
@@ -1116,7 +1072,11 @@ public class BugleNotifications {
}
final NotificationPlayer player = new NotificationPlayer(LogUtil.BUGLE_TAG);
player.play(ringtoneUri, false,
NotificationChannel channel = NotificationsUtil.getNotificationChannel(context, conversationId);
if (channel == null) {
channel = NotificationsUtil.getNotificationChannel(context, NotificationsUtil.DEFAULT_CHANNEL_ID);
}
player.play(channel != null ? channel.getSound() : null, false,
AudioManager.STREAM_NOTIFICATION,
OBSERVABLE_CONVERSATION_NOTIFICATION_VOLUME);
@@ -1211,7 +1171,8 @@ public class BugleNotifications {
final PendingIntent destinationIntent = UIIntents.get()
.getPendingIntentForConversationActivity(context, conversationId, null /* draft */);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
final NotificationCompat.Builder builder =
new NotificationCompat.Builder(context, NotificationsUtil.DEFAULT_CHANNEL_ID);
builder.setTicker(line1)
.setContentTitle(line1)
.setContentText(line2)
@@ -1221,6 +1182,15 @@ public class BugleNotifications {
.setSound(UriUtil.getUriForResourceId(context, R.raw.message_failure));
final String tag = context.getPackageName() + ":emergency_sms_error";
NotificationsUtil.createNotificationChannelGroup(context,
NotificationsUtil.CONVERSATION_GROUP_NAME,
R.string.notification_channel_messages_title);
NotificationsUtil.createNotificationChannel(context,
NotificationsUtil.DEFAULT_CHANNEL_ID,
R.string.notification_channel_messages_title,
NotificationManager.IMPORTANCE_HIGH,
null);
NotificationManagerCompat.from(context).notify(
tag,
PendingIntentConstants.MSG_SEND_ERROR,