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:
@@ -171,8 +171,7 @@ public class BugleDatabaseOperations {
|
||||
final ArrayList<ParticipantData> participants =
|
||||
getConversationParticipantsFromRecipients(recipients, refSubId);
|
||||
|
||||
return getOrCreateConversation(db, threadId, senderBlocked, participants, false, false,
|
||||
null);
|
||||
return getOrCreateConversation(db, threadId, senderBlocked, participants);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,7 +189,7 @@ public class BugleDatabaseOperations {
|
||||
Assert.isNotMainThread();
|
||||
final ArrayList<ParticipantData> recipients = new ArrayList<>(1);
|
||||
recipients.add(recipient);
|
||||
return getOrCreateConversation(db, threadId, senderBlocked, recipients, false, false, null);
|
||||
return getOrCreateConversation(db, threadId, senderBlocked, recipients);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,15 +199,11 @@ public class BugleDatabaseOperations {
|
||||
* @param threadId The message's thread
|
||||
* @param archived Flag whether the conversation should be created archived
|
||||
* @param participants list of conversation participants
|
||||
* @param noNotification If notification should be disabled
|
||||
* @param noVibrate If vibrate on notification should be disabled
|
||||
* @param soundUri If there is custom sound URI
|
||||
* @return a conversation id
|
||||
*/
|
||||
@DoesNotRunOnMainThread
|
||||
public static String getOrCreateConversation(final DatabaseWrapper db, final long threadId,
|
||||
final boolean archived, final ArrayList<ParticipantData> participants,
|
||||
boolean noNotification, boolean noVibrate, String soundUri) {
|
||||
final boolean archived, final ArrayList<ParticipantData> participants) {
|
||||
Assert.isNotMainThread();
|
||||
|
||||
// Check to see if this conversation is already in out local db cache
|
||||
@@ -231,8 +226,7 @@ public class BugleDatabaseOperations {
|
||||
BugleDatabaseOperations.getOrCreateParticipantInTransaction(db, self);
|
||||
// Create a new conversation
|
||||
conversationId = BugleDatabaseOperations.createConversationInTransaction(
|
||||
db, threadId, conversationName, selfId, participants, archived,
|
||||
noNotification, noVibrate, soundUri);
|
||||
db, threadId, conversationName, selfId, participants, archived);
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
@@ -357,15 +351,11 @@ public class BugleDatabaseOperations {
|
||||
* @param threadId The message's thread
|
||||
* @param selfId The selfId to make default for this conversation
|
||||
* @param archived Flag whether the conversation should be created archived
|
||||
* @param noNotification If notification should be disabled
|
||||
* @param noVibrate If vibrate on notification should be disabled
|
||||
* @param soundUri The customized sound
|
||||
* @return The existing conversation id or new conversation id
|
||||
*/
|
||||
static String createConversationInTransaction(final DatabaseWrapper dbWrapper,
|
||||
final long threadId, final String conversationName, final String selfId,
|
||||
final List<ParticipantData> participants, final boolean archived,
|
||||
boolean noNotification, boolean noVibrate, String soundUri) {
|
||||
final List<ParticipantData> participants, final boolean archived) {
|
||||
// We want conversation and participant creation to be atomic
|
||||
Assert.isTrue(dbWrapper.getDatabase().inTransaction());
|
||||
boolean hasEmailAddress = false;
|
||||
@@ -389,15 +379,6 @@ public class BugleDatabaseOperations {
|
||||
if (archived) {
|
||||
values.put(ConversationColumns.ARCHIVE_STATUS, 1);
|
||||
}
|
||||
if (noNotification) {
|
||||
values.put(ConversationColumns.NOTIFICATION_ENABLED, 0);
|
||||
}
|
||||
if (noVibrate) {
|
||||
values.put(ConversationColumns.NOTIFICATION_VIBRATION, 0);
|
||||
}
|
||||
if (!TextUtils.isEmpty(soundUri)) {
|
||||
values.put(ConversationColumns.NOTIFICATION_SOUND_URI, soundUri);
|
||||
}
|
||||
|
||||
fillParticipantData(values, participants);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -136,15 +136,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
/* Participant count not including self (so will be 1 for 1:1 or bigger for group) */
|
||||
public static final String PARTICIPANT_COUNT = "participant_count";
|
||||
|
||||
/* Should notifications be enabled for this conversation? */
|
||||
public static final String NOTIFICATION_ENABLED = "notification_enabled";
|
||||
|
||||
/* Notification sound used for the conversation */
|
||||
public static final String NOTIFICATION_SOUND_URI = "notification_sound_uri";
|
||||
|
||||
/* Should vibrations be enabled for the conversation's notification? */
|
||||
public static final String NOTIFICATION_VIBRATION = "notification_vibration";
|
||||
|
||||
/* Conversation recipients include email address */
|
||||
public static final String INCLUDE_EMAIL_ADDRESS = "include_email_addr";
|
||||
|
||||
@@ -184,9 +175,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
+ ConversationColumns.OTHER_PARTICIPANT_NORMALIZED_DESTINATION + " TEXT, "
|
||||
+ ConversationColumns.CURRENT_SELF_ID + " TEXT, "
|
||||
+ ConversationColumns.PARTICIPANT_COUNT + " INT DEFAULT(0), "
|
||||
+ ConversationColumns.NOTIFICATION_ENABLED + " INT DEFAULT(1), "
|
||||
+ ConversationColumns.NOTIFICATION_SOUND_URI + " TEXT, "
|
||||
+ ConversationColumns.NOTIFICATION_VIBRATION + " INT DEFAULT(1), "
|
||||
+ ConversationColumns.INCLUDE_EMAIL_ADDRESS + " INT DEFAULT(0), "
|
||||
+ ConversationColumns.SMS_SERVICE_CENTER + " TEXT ,"
|
||||
+ ConversationColumns.IS_ENTERPRISE + " INT DEFAULT(0)"
|
||||
|
||||
@@ -197,15 +197,6 @@ public abstract class MessageNotificationState extends NotificationState {
|
||||
// line infos is capped.
|
||||
int mTotalMessageCount;
|
||||
|
||||
// Custom ringtone if set
|
||||
final String mRingtoneUri;
|
||||
|
||||
// Should notification be enabled for this conversation?
|
||||
final boolean mNotificationEnabled;
|
||||
|
||||
// Should notifications vibrate for this conversation?
|
||||
final boolean mNotificationVibrate;
|
||||
|
||||
// Avatar uri of sender
|
||||
final Uri mAvatarUri;
|
||||
|
||||
@@ -224,9 +215,6 @@ public abstract class MessageNotificationState extends NotificationState {
|
||||
final boolean includeEmailAddress,
|
||||
final long receivedTimestamp,
|
||||
final String selfParticipantId,
|
||||
final String ringtoneUri,
|
||||
final boolean notificationEnabled,
|
||||
final boolean notificationVibrate,
|
||||
final Uri avatarUri,
|
||||
final Uri contactUri,
|
||||
final int subId,
|
||||
@@ -239,11 +227,8 @@ public abstract class MessageNotificationState extends NotificationState {
|
||||
mSelfParticipantId = selfParticipantId;
|
||||
mLineInfos = new ArrayList<NotificationLineInfo>();
|
||||
mTotalMessageCount = 0;
|
||||
mRingtoneUri = ringtoneUri;
|
||||
mAvatarUri = avatarUri;
|
||||
mContactUri = contactUri;
|
||||
mNotificationEnabled = notificationEnabled;
|
||||
mNotificationVibrate = notificationVibrate;
|
||||
mSubId = subId;
|
||||
mParticipantCount = participantCount;
|
||||
}
|
||||
@@ -870,10 +855,6 @@ public abstract class MessageNotificationState extends NotificationState {
|
||||
if (currConvInfo == null) {
|
||||
final ConversationListItemData convData =
|
||||
ConversationListItemData.getExistingConversation(db, convId);
|
||||
if (!convData.getNotificationEnabled()) {
|
||||
// Skip conversations that have notifications disabled.
|
||||
continue;
|
||||
}
|
||||
final int subId = BugleDatabaseOperations.getSelfSubscriptionId(db,
|
||||
convData.getSelfId());
|
||||
groupConversationName = convData.getName();
|
||||
@@ -888,9 +869,6 @@ public abstract class MessageNotificationState extends NotificationState {
|
||||
convData.getIncludeEmailAddress(),
|
||||
convMessageData.getReceivedTimeStamp(),
|
||||
convData.getSelfId(),
|
||||
convData.getNotificationSoundUri(),
|
||||
convData.getNotificationEnabled(),
|
||||
convData.getNotifiationVibrate(),
|
||||
avatarUri,
|
||||
convMessageData.getSenderContactLookupUri(),
|
||||
subId,
|
||||
@@ -1103,22 +1081,6 @@ public abstract class MessageNotificationState extends NotificationState {
|
||||
return BugleNotifications.LOCAL_SMS_NOTIFICATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRingtoneUri() {
|
||||
if (mConvList.mConvInfos.size() > 0) {
|
||||
return mConvList.mConvInfos.get(0).mRingtoneUri;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getNotificationVibrate() {
|
||||
if (mConvList.mConvInfos.size() > 0) {
|
||||
return mConvList.mConvInfos.get(0).mNotificationVibrate;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected CharSequence getTicker() {
|
||||
return BugleNotifications.buildColonSeparatedMessage(
|
||||
mTickerSender != null ? mTickerSender : mTitle,
|
||||
|
||||
@@ -134,15 +134,6 @@ public abstract class NotificationState {
|
||||
*/
|
||||
public abstract int getPriority();
|
||||
|
||||
/** @return custom ringtone URI or null if not set */
|
||||
public String getRingtoneUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getNotificationVibrate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public long getLatestReceivedTimestamp() {
|
||||
return Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
@@ -51,33 +51,14 @@ public class SyncManager {
|
||||
*/
|
||||
public static class ConversationCustomization {
|
||||
private final boolean mArchived;
|
||||
private final boolean mMuted;
|
||||
private final boolean mNoVibrate;
|
||||
private final String mNotificationSoundUri;
|
||||
|
||||
public ConversationCustomization(final boolean archived, final boolean muted,
|
||||
final boolean noVibrate, final String notificationSoundUri) {
|
||||
public ConversationCustomization(final boolean archived) {
|
||||
mArchived = archived;
|
||||
mMuted = muted;
|
||||
mNoVibrate = noVibrate;
|
||||
mNotificationSoundUri = notificationSoundUri;
|
||||
}
|
||||
|
||||
public boolean isArchived() {
|
||||
return mArchived;
|
||||
}
|
||||
|
||||
public boolean isMuted() {
|
||||
return mMuted;
|
||||
}
|
||||
|
||||
public boolean noVibrate() {
|
||||
return mNoVibrate;
|
||||
}
|
||||
|
||||
public String getNotificationSoundUri() {
|
||||
return mNotificationSoundUri;
|
||||
}
|
||||
}
|
||||
|
||||
SyncManager() {
|
||||
@@ -436,15 +417,13 @@ public class SyncManager {
|
||||
if (customization != null) {
|
||||
// There is user customization we need to recover
|
||||
conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId,
|
||||
customization.isArchived(), participants, customization.isMuted(),
|
||||
customization.noVibrate(), customization.getNotificationSoundUri());
|
||||
customization.isArchived(), participants);
|
||||
if (customization.isArchived()) {
|
||||
mArchivedConversations.add(conversationId);
|
||||
}
|
||||
} else {
|
||||
conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId,
|
||||
false/*archived*/, participants, false/*noNotification*/,
|
||||
false/*noVibrate*/, null/*soundUri*/);
|
||||
false/*archived*/, participants);
|
||||
}
|
||||
|
||||
if (conversationId != null) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.android.messaging.datamodel.MessagingContentProvider;
|
||||
import com.android.messaging.sms.MmsUtils;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.LogUtil;
|
||||
import com.android.messaging.util.NotificationsUtil;
|
||||
import com.android.messaging.widget.WidgetConversationProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -118,6 +119,10 @@ public class DeleteConversationAction extends Action implements Parcelable {
|
||||
+ " has an invalid telephony thread id; will delete messages individually");
|
||||
deleteConversationMessagesFromTelephony();
|
||||
}
|
||||
|
||||
// Finally, remove the conversation specific notification channel
|
||||
NotificationsUtil.deleteNotificationChannel(Factory.get().getApplicationContext(),
|
||||
conversationId);
|
||||
} else {
|
||||
LogUtil.e(TAG, "DeleteConversationAction: conversationId is empty");
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class GetOrCreateConversationAction extends Action implements Parcelable
|
||||
}
|
||||
|
||||
final String conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId,
|
||||
false, participants, false, false, null);
|
||||
false, participants);
|
||||
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ public class InsertNewMessageAction extends Action implements Parcelable {
|
||||
}
|
||||
|
||||
final String conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId,
|
||||
false, participants, false, false, null);
|
||||
false, participants);
|
||||
|
||||
final ParticipantData self = BugleDatabaseOperations.getOrCreateSelf(db, subId);
|
||||
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.messaging.datamodel.action;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.messaging.datamodel.BugleDatabaseOperations;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ConversationColumns;
|
||||
import com.android.messaging.datamodel.DatabaseWrapper;
|
||||
import com.android.messaging.datamodel.MessagingContentProvider;
|
||||
import com.android.messaging.util.Assert;
|
||||
|
||||
/**
|
||||
* Action used to update conversation options such as notification settings.
|
||||
*/
|
||||
public class UpdateConversationOptionsAction extends Action
|
||||
implements Parcelable {
|
||||
/**
|
||||
* Enable/disable conversation notifications.
|
||||
*/
|
||||
public static void enableConversationNotifications(final String conversationId,
|
||||
final boolean enableNotification) {
|
||||
Assert.notNull(conversationId);
|
||||
|
||||
final UpdateConversationOptionsAction action = new UpdateConversationOptionsAction(
|
||||
conversationId, enableNotification, null, null);
|
||||
action.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets conversation notification sound.
|
||||
*/
|
||||
public static void setConversationNotificationSound(final String conversationId,
|
||||
final String ringtoneUri) {
|
||||
Assert.notNull(conversationId);
|
||||
|
||||
final UpdateConversationOptionsAction action = new UpdateConversationOptionsAction(
|
||||
conversationId, null, ringtoneUri, null);
|
||||
action.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable vibrations for conversation notification.
|
||||
*/
|
||||
public static void enableVibrationForConversationNotification(final String conversationId,
|
||||
final boolean enableVibration) {
|
||||
Assert.notNull(conversationId);
|
||||
|
||||
final UpdateConversationOptionsAction action = new UpdateConversationOptionsAction(
|
||||
conversationId, null, null, enableVibration);
|
||||
action.start();
|
||||
}
|
||||
|
||||
private static final String KEY_CONVERSATION_ID = "conversation_id";
|
||||
|
||||
// Keys for all settable settings.
|
||||
private static final String KEY_ENABLE_NOTIFICATION = "enable_notification";
|
||||
private static final String KEY_RINGTONE_URI = "ringtone_uri";
|
||||
private static final String KEY_ENABLE_VIBRATION = "enable_vibration";
|
||||
|
||||
protected UpdateConversationOptionsAction(final String conversationId,
|
||||
final Boolean enableNotification, final String ringtoneUri,
|
||||
final Boolean enableVibration) {
|
||||
Assert.notNull(conversationId);
|
||||
actionParameters.putString(KEY_CONVERSATION_ID, conversationId);
|
||||
if (enableNotification != null) {
|
||||
actionParameters.putBoolean(KEY_ENABLE_NOTIFICATION, enableNotification);
|
||||
}
|
||||
|
||||
if (ringtoneUri != null) {
|
||||
actionParameters.putString(KEY_RINGTONE_URI, ringtoneUri);
|
||||
}
|
||||
|
||||
if (enableVibration != null) {
|
||||
actionParameters.putBoolean(KEY_ENABLE_VIBRATION, enableVibration);
|
||||
}
|
||||
}
|
||||
|
||||
protected void putOptionValuesInTransaction(final ContentValues values,
|
||||
final DatabaseWrapper dbWrapper) {
|
||||
Assert.isTrue(dbWrapper.getDatabase().inTransaction());
|
||||
if (actionParameters.containsKey(KEY_ENABLE_NOTIFICATION)) {
|
||||
values.put(ConversationColumns.NOTIFICATION_ENABLED,
|
||||
actionParameters.getBoolean(KEY_ENABLE_NOTIFICATION));
|
||||
}
|
||||
|
||||
if (actionParameters.containsKey(KEY_RINGTONE_URI)) {
|
||||
values.put(ConversationColumns.NOTIFICATION_SOUND_URI,
|
||||
actionParameters.getString(KEY_RINGTONE_URI));
|
||||
}
|
||||
|
||||
if (actionParameters.containsKey(KEY_ENABLE_VIBRATION)) {
|
||||
values.put(ConversationColumns.NOTIFICATION_VIBRATION,
|
||||
actionParameters.getBoolean(KEY_ENABLE_VIBRATION));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object executeAction() {
|
||||
final String conversationId = actionParameters.getString(KEY_CONVERSATION_ID);
|
||||
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final ContentValues values = new ContentValues();
|
||||
putOptionValuesInTransaction(values, db);
|
||||
|
||||
BugleDatabaseOperations.updateConversationRowIfExists(db, conversationId, values);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
MessagingContentProvider.notifyConversationMetadataChanged(conversationId);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected UpdateConversationOptionsAction(final Parcel in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<UpdateConversationOptionsAction> CREATOR
|
||||
= new Parcelable.Creator<UpdateConversationOptionsAction>() {
|
||||
@Override
|
||||
public UpdateConversationOptionsAction createFromParcel(final Parcel in) {
|
||||
return new UpdateConversationOptionsAction(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateConversationOptionsAction[] newArray(final int size) {
|
||||
return new UpdateConversationOptionsAction[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int flags) {
|
||||
writeActionToParcel(parcel, flags);
|
||||
}
|
||||
}
|
||||
@@ -52,9 +52,6 @@ public class ConversationListItemData {
|
||||
private String mOtherParticipantNormalizedDestination;
|
||||
private String mSelfId;
|
||||
private int mParticipantCount;
|
||||
private boolean mNotificationEnabled;
|
||||
private String mNotificationSoundUri;
|
||||
private boolean mNotificationVibrate;
|
||||
private boolean mIncludeEmailAddress;
|
||||
private int mMessageStatus;
|
||||
private int mMessageRawTelephonyStatus;
|
||||
@@ -92,9 +89,6 @@ public class ConversationListItemData {
|
||||
INDEX_OTHER_PARTICIPANT_NORMALIZED_DESTINATION);
|
||||
mSelfId = cursor.getString(INDEX_SELF_ID);
|
||||
mParticipantCount = cursor.getInt(INDEX_PARTICIPANT_COUNT);
|
||||
mNotificationEnabled = cursor.getInt(INDEX_NOTIFICATION_ENABLED) == 1;
|
||||
mNotificationSoundUri = cursor.getString(INDEX_NOTIFICATION_SOUND_URI);
|
||||
mNotificationVibrate = cursor.getInt(INDEX_NOTIFICATION_VIBRATION) == 1;
|
||||
mIncludeEmailAddress = cursor.getInt(INDEX_INCLUDE_EMAIL_ADDRESS) == 1;
|
||||
mMessageStatus = cursor.getInt(INDEX_MESSAGE_STATUS);
|
||||
mMessageRawTelephonyStatus = cursor.getInt(INDEX_MESSAGE_RAW_TELEPHONY_STATUS);
|
||||
@@ -199,18 +193,6 @@ public class ConversationListItemData {
|
||||
return mIncludeEmailAddress;
|
||||
}
|
||||
|
||||
public boolean getNotificationEnabled() {
|
||||
return mNotificationEnabled;
|
||||
}
|
||||
|
||||
public String getNotificationSoundUri() {
|
||||
return mNotificationSoundUri;
|
||||
}
|
||||
|
||||
public boolean getNotifiationVibrate() {
|
||||
return mNotificationVibrate;
|
||||
}
|
||||
|
||||
public final boolean getIsFailedStatus() {
|
||||
return (mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_FAILED ||
|
||||
mMessageStatus == MessageData.BUGLE_STATUS_OUTGOING_FAILED_EMERGENCY_NUMBER ||
|
||||
@@ -328,12 +310,6 @@ public class ConversationListItemData {
|
||||
+ " as " + ConversationListViewColumns.PREVIEW_CONTENT_TYPE + ", "
|
||||
+ DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.PARTICIPANT_COUNT
|
||||
+ " as " + ConversationListViewColumns.PARTICIPANT_COUNT + ", "
|
||||
+ DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.NOTIFICATION_ENABLED
|
||||
+ " as " + ConversationListViewColumns.NOTIFICATION_ENABLED + ", "
|
||||
+ DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.NOTIFICATION_SOUND_URI
|
||||
+ " as " + ConversationListViewColumns.NOTIFICATION_SOUND_URI + ", "
|
||||
+ DatabaseHelper.CONVERSATIONS_TABLE + '.' + ConversationColumns.NOTIFICATION_VIBRATION
|
||||
+ " as " + ConversationListViewColumns.NOTIFICATION_VIBRATION + ", "
|
||||
+ DatabaseHelper.CONVERSATIONS_TABLE + '.' +
|
||||
ConversationColumns.INCLUDE_EMAIL_ADDRESS
|
||||
+ " as " + ConversationListViewColumns.INCLUDE_EMAIL_ADDRESS + ", "
|
||||
@@ -396,9 +372,6 @@ public class ConversationListItemData {
|
||||
ConversationColumns.OTHER_PARTICIPANT_NORMALIZED_DESTINATION;
|
||||
static final String CURRENT_SELF_ID = ConversationColumns.CURRENT_SELF_ID;
|
||||
static final String PARTICIPANT_COUNT = ConversationColumns.PARTICIPANT_COUNT;
|
||||
static final String NOTIFICATION_ENABLED = ConversationColumns.NOTIFICATION_ENABLED;
|
||||
static final String NOTIFICATION_SOUND_URI = ConversationColumns.NOTIFICATION_SOUND_URI;
|
||||
static final String NOTIFICATION_VIBRATION = ConversationColumns.NOTIFICATION_VIBRATION;
|
||||
static final String INCLUDE_EMAIL_ADDRESS =
|
||||
ConversationColumns.INCLUDE_EMAIL_ADDRESS;
|
||||
static final String MESSAGE_STATUS = MessageColumns.STATUS;
|
||||
@@ -424,9 +397,6 @@ public class ConversationListItemData {
|
||||
ConversationListViewColumns.OTHER_PARTICIPANT_NORMALIZED_DESTINATION,
|
||||
ConversationListViewColumns.PARTICIPANT_COUNT,
|
||||
ConversationListViewColumns.CURRENT_SELF_ID,
|
||||
ConversationListViewColumns.NOTIFICATION_ENABLED,
|
||||
ConversationListViewColumns.NOTIFICATION_SOUND_URI,
|
||||
ConversationListViewColumns.NOTIFICATION_VIBRATION,
|
||||
ConversationListViewColumns.INCLUDE_EMAIL_ADDRESS,
|
||||
ConversationListViewColumns.MESSAGE_STATUS,
|
||||
ConversationListViewColumns.SHOW_DRAFT,
|
||||
@@ -456,23 +426,20 @@ public class ConversationListItemData {
|
||||
private static final int INDEX_OTHER_PARTICIPANT_NORMALIZED_DESTINATION = 10;
|
||||
private static final int INDEX_PARTICIPANT_COUNT = 11;
|
||||
private static final int INDEX_SELF_ID = 12;
|
||||
private static final int INDEX_NOTIFICATION_ENABLED = 13;
|
||||
private static final int INDEX_NOTIFICATION_SOUND_URI = 14;
|
||||
private static final int INDEX_NOTIFICATION_VIBRATION = 15;
|
||||
private static final int INDEX_INCLUDE_EMAIL_ADDRESS = 16;
|
||||
private static final int INDEX_MESSAGE_STATUS = 17;
|
||||
private static final int INDEX_SHOW_DRAFT = 18;
|
||||
private static final int INDEX_DRAFT_PREVIEW_URI = 19;
|
||||
private static final int INDEX_DRAFT_PREVIEW_CONTENT_TYPE = 20;
|
||||
private static final int INDEX_DRAFT_SNIPPET_TEXT = 21;
|
||||
private static final int INDEX_ARCHIVE_STATUS = 22;
|
||||
private static final int INDEX_MESSAGE_ID = 23;
|
||||
private static final int INDEX_SUBJECT_TEXT = 24;
|
||||
private static final int INDEX_DRAFT_SUBJECT_TEXT = 25;
|
||||
private static final int INDEX_MESSAGE_RAW_TELEPHONY_STATUS = 26;
|
||||
private static final int INDEX_SNIPPET_SENDER_FIRST_NAME = 27;
|
||||
private static final int INDEX_SNIPPET_SENDER_DISPLAY_DESTINATION = 28;
|
||||
private static final int INDEX_IS_ENTERPRISE = 29;
|
||||
private static final int INDEX_INCLUDE_EMAIL_ADDRESS = 13;
|
||||
private static final int INDEX_MESSAGE_STATUS = 14;
|
||||
private static final int INDEX_SHOW_DRAFT = 15;
|
||||
private static final int INDEX_DRAFT_PREVIEW_URI = 16;
|
||||
private static final int INDEX_DRAFT_PREVIEW_CONTENT_TYPE = 17;
|
||||
private static final int INDEX_DRAFT_SNIPPET_TEXT = 18;
|
||||
private static final int INDEX_ARCHIVE_STATUS = 19;
|
||||
private static final int INDEX_MESSAGE_ID = 20;
|
||||
private static final int INDEX_SUBJECT_TEXT = 21;
|
||||
private static final int INDEX_DRAFT_SUBJECT_TEXT = 22;
|
||||
private static final int INDEX_MESSAGE_RAW_TELEPHONY_STATUS = 23;
|
||||
private static final int INDEX_SNIPPET_SENDER_FIRST_NAME = 24;
|
||||
private static final int INDEX_SNIPPET_SENDER_DISPLAY_DESTINATION = 25;
|
||||
private static final int INDEX_IS_ENTERPRISE = 26;
|
||||
|
||||
private static final String DIVIDER_TEXT = ", ";
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import android.os.Bundle;
|
||||
import com.android.messaging.datamodel.BoundCursorLoader;
|
||||
import com.android.messaging.datamodel.MessagingContentProvider;
|
||||
import com.android.messaging.datamodel.action.BugleActionToasts;
|
||||
import com.android.messaging.datamodel.action.UpdateConversationOptionsAction;
|
||||
import com.android.messaging.datamodel.action.UpdateDestinationBlockedAction;
|
||||
import com.android.messaging.datamodel.binding.BindableData;
|
||||
import com.android.messaging.datamodel.binding.BindingBase;
|
||||
@@ -74,7 +73,7 @@ public class PeopleAndOptionsData extends BindableData implements
|
||||
final Uri uri =
|
||||
MessagingContentProvider.buildConversationMetadataUri(mConversationId);
|
||||
return new BoundCursorLoader(bindingId, mContext, uri,
|
||||
PeopleOptionsItemData.PROJECTION, null, null, null);
|
||||
new String[]{}, null, null, null);
|
||||
}
|
||||
|
||||
case PARTICIPANT_LOADER: {
|
||||
@@ -169,33 +168,6 @@ public class PeopleAndOptionsData extends BindableData implements
|
||||
}
|
||||
}
|
||||
|
||||
public void enableConversationNotifications(final BindingBase<PeopleAndOptionsData> binding,
|
||||
final boolean enable) {
|
||||
final String bindingId = binding.getBindingId();
|
||||
if (isBound(bindingId)) {
|
||||
UpdateConversationOptionsAction.enableConversationNotifications(
|
||||
mConversationId, enable);
|
||||
}
|
||||
}
|
||||
|
||||
public void setConversationNotificationSound(final BindingBase<PeopleAndOptionsData> binding,
|
||||
final String ringtoneUri) {
|
||||
final String bindingId = binding.getBindingId();
|
||||
if (isBound(bindingId)) {
|
||||
UpdateConversationOptionsAction.setConversationNotificationSound(mConversationId,
|
||||
ringtoneUri);
|
||||
}
|
||||
}
|
||||
|
||||
public void enableConversationNotificationVibration(
|
||||
final BindingBase<PeopleAndOptionsData> binding, final boolean enable) {
|
||||
final String bindingId = binding.getBindingId();
|
||||
if (isBound(bindingId)) {
|
||||
UpdateConversationOptionsAction.enableVibrationForConversationNotification(
|
||||
mConversationId, enable);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDestinationBlocked(final BindingBase<PeopleAndOptionsData> binding,
|
||||
final boolean blocked) {
|
||||
final String bindingId = binding.getBindingId();
|
||||
@@ -207,4 +179,8 @@ public class PeopleAndOptionsData extends BindableData implements
|
||||
BugleActionToasts.makeUpdateDestinationBlockedActionListener(mContext));
|
||||
}
|
||||
}
|
||||
|
||||
public String getConversationId() {
|
||||
return mConversationId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,44 +17,19 @@ package com.android.messaging.datamodel.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.data.ConversationListItemData.ConversationListViewColumns;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.RingtoneUtil;
|
||||
|
||||
public class PeopleOptionsItemData {
|
||||
public static final String[] PROJECTION = {
|
||||
ConversationListViewColumns.NOTIFICATION_ENABLED,
|
||||
ConversationListViewColumns.NOTIFICATION_SOUND_URI,
|
||||
ConversationListViewColumns.NOTIFICATION_VIBRATION,
|
||||
};
|
||||
|
||||
// Column index for query projection.
|
||||
private static final int INDEX_NOTIFICATION_ENABLED = 0;
|
||||
private static final int INDEX_NOTIFICATION_SOUND_URI = 1;
|
||||
private static final int INDEX_NOTIFICATION_VIBRATION = 2;
|
||||
|
||||
// Identification for each setting that's surfaced to the UI layer.
|
||||
public static final int SETTING_NOTIFICATION_ENABLED = 0;
|
||||
public static final int SETTING_NOTIFICATION_SOUND_URI = 1;
|
||||
public static final int SETTING_NOTIFICATION_VIBRATION = 2;
|
||||
public static final int SETTING_BLOCKED = 3;
|
||||
public static final int SETTINGS_COUNT = 4;
|
||||
|
||||
// Type of UI switch to show for the toggle button.
|
||||
public static final int TOGGLE_TYPE_CHECKBOX = 0;
|
||||
public static final int TOGGLE_TYPE_SWITCH = 1;
|
||||
public static final int SETTING_NOTIFICATION = 0;
|
||||
public static final int SETTING_BLOCKED = 1;
|
||||
public static final int SETTINGS_COUNT = 2;
|
||||
|
||||
private String mTitle;
|
||||
private String mSubtitle;
|
||||
private Uri mRingtoneUri;
|
||||
private boolean mCheckable;
|
||||
private boolean mChecked;
|
||||
private boolean mEnabled;
|
||||
private int mItemId;
|
||||
private ParticipantData mOtherParticipant;
|
||||
|
||||
@@ -71,41 +46,12 @@ public class PeopleOptionsItemData {
|
||||
*/
|
||||
public void bind(
|
||||
final Cursor cursor, final ParticipantData otherParticipant, final int settingType) {
|
||||
mSubtitle = null;
|
||||
mRingtoneUri = null;
|
||||
mCheckable = true;
|
||||
mEnabled = true;
|
||||
mItemId = settingType;
|
||||
mOtherParticipant = otherParticipant;
|
||||
|
||||
final boolean notificationEnabled = cursor.getInt(INDEX_NOTIFICATION_ENABLED) == 1;
|
||||
switch (settingType) {
|
||||
case SETTING_NOTIFICATION_ENABLED:
|
||||
case SETTING_NOTIFICATION:
|
||||
mTitle = mContext.getString(R.string.notifications_enabled_conversation_pref_title);
|
||||
mChecked = notificationEnabled;
|
||||
break;
|
||||
|
||||
case SETTING_NOTIFICATION_SOUND_URI:
|
||||
mTitle = mContext.getString(R.string.notification_sound_pref_title);
|
||||
final String ringtoneString = cursor.getString(INDEX_NOTIFICATION_SOUND_URI);
|
||||
Uri ringtoneUri = RingtoneUtil.getNotificationRingtoneUri(ringtoneString);
|
||||
|
||||
mSubtitle = mContext.getString(R.string.silent_ringtone);
|
||||
if (ringtoneUri != null) {
|
||||
final Ringtone ringtone = RingtoneManager.getRingtone(mContext, ringtoneUri);
|
||||
if (ringtone != null) {
|
||||
mSubtitle = ringtone.getTitle(mContext);
|
||||
}
|
||||
}
|
||||
mCheckable = false;
|
||||
mRingtoneUri = ringtoneUri;
|
||||
mEnabled = notificationEnabled;
|
||||
break;
|
||||
|
||||
case SETTING_NOTIFICATION_VIBRATION:
|
||||
mTitle = mContext.getString(R.string.notification_vibrate_pref_title);
|
||||
mChecked = cursor.getInt(INDEX_NOTIFICATION_VIBRATION) == 1;
|
||||
mEnabled = notificationEnabled;
|
||||
break;
|
||||
|
||||
case SETTING_BLOCKED:
|
||||
@@ -113,7 +59,6 @@ public class PeopleOptionsItemData {
|
||||
final int resourceId = otherParticipant.isBlocked() ?
|
||||
R.string.unblock_contact_title : R.string.block_contact_title;
|
||||
mTitle = mContext.getString(resourceId, otherParticipant.getDisplayDestination());
|
||||
mCheckable = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -125,30 +70,10 @@ public class PeopleOptionsItemData {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
public String getSubtitle() {
|
||||
return mSubtitle;
|
||||
}
|
||||
|
||||
public boolean getCheckable() {
|
||||
return mCheckable;
|
||||
}
|
||||
|
||||
public boolean getChecked() {
|
||||
return mChecked;
|
||||
}
|
||||
|
||||
public boolean getEnabled() {
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return mItemId;
|
||||
}
|
||||
|
||||
public Uri getRingtoneUri() {
|
||||
return mRingtoneUri;
|
||||
}
|
||||
|
||||
public ParticipantData getOtherParticipant() {
|
||||
return mOtherParticipant;
|
||||
}
|
||||
|
||||
@@ -252,11 +252,6 @@ public final class SmsReceiver extends BroadcastReceiver {
|
||||
protected Style build(Builder builder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getNotificationVibrate() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void postNewMessageSecondaryUserNotification() {
|
||||
@@ -282,10 +277,7 @@ public final class SmsReceiver extends BroadcastReceiver {
|
||||
final NotificationManagerCompat notificationManager =
|
||||
NotificationManagerCompat.from(Factory.get().getApplicationContext());
|
||||
|
||||
int defaults = Notification.DEFAULT_LIGHTS;
|
||||
if (BugleNotifications.shouldVibrate(new SecondaryUserNotificationState())) {
|
||||
defaults |= Notification.DEFAULT_VIBRATE;
|
||||
}
|
||||
int defaults = Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE;
|
||||
notification.defaults = defaults;
|
||||
|
||||
notificationManager.notify(getNotificationTag(),
|
||||
|
||||
@@ -264,16 +264,6 @@ public abstract class UIIntents {
|
||||
*/
|
||||
public abstract Intent getViewUrlIntent(final String url);
|
||||
|
||||
/**
|
||||
* Get an intent to launch the ringtone picker
|
||||
* @param title the title to show in the ringtone picker
|
||||
* @param existingUri the currently set uri
|
||||
* @param defaultUri the default uri if none is currently set
|
||||
* @param toneType type of ringtone to pick, maybe any of RingtoneManager.TYPE_*
|
||||
*/
|
||||
public abstract Intent getRingtonePickerIntent(final String title, final Uri existingUri,
|
||||
final Uri defaultUri, final int toneType);
|
||||
|
||||
/**
|
||||
* Get an intent to launch the wireless alert viewer.
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
@@ -450,16 +449,6 @@ public class UIIntentsImpl extends UIIntents {
|
||||
return resultPendingIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getRingtonePickerIntent(final String title, final Uri existingUri,
|
||||
final Uri defaultUri, final int toneType) {
|
||||
return new Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
|
||||
.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, toneType)
|
||||
.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, title)
|
||||
.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, existingUri)
|
||||
.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, defaultUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingIntent getPendingIntentForLowStorageNotifications(final Context context) {
|
||||
final TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
|
||||
|
||||
@@ -18,18 +18,12 @@ package com.android.messaging.ui.appsettings;
|
||||
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.RingtonePreference;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.preference.TwoStatePreference;
|
||||
import android.provider.Settings;
|
||||
import androidx.core.app.NavUtils;
|
||||
import android.text.TextUtils;
|
||||
@@ -85,14 +79,10 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public static class ApplicationSettingsFragment extends PreferenceFragment implements
|
||||
OnSharedPreferenceChangeListener {
|
||||
public static class ApplicationSettingsFragment extends PreferenceFragment {
|
||||
|
||||
private String mNotificationsEnabledPreferenceKey;
|
||||
private TwoStatePreference mNotificationsEnabledPreference;
|
||||
private String mRingtonePreferenceKey;
|
||||
private RingtonePreference mRingtonePreference;
|
||||
private Preference mVibratePreference;
|
||||
private String mNotificationsPreferenceKey;
|
||||
private Preference mNotificationsPreference;
|
||||
private String mSmsDisabledPrefKey;
|
||||
private Preference mSmsDisabledPreference;
|
||||
private String mSmsEnabledPrefKey;
|
||||
@@ -112,14 +102,9 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
|
||||
getPreferenceManager().setSharedPreferencesName(BuglePrefs.SHARED_PREFERENCES_NAME);
|
||||
addPreferencesFromResource(R.xml.preferences_application);
|
||||
|
||||
mNotificationsEnabledPreferenceKey =
|
||||
getString(R.string.notifications_enabled_pref_key);
|
||||
mNotificationsEnabledPreference = (TwoStatePreference) findPreference(
|
||||
mNotificationsEnabledPreferenceKey);
|
||||
mRingtonePreferenceKey = getString(R.string.notification_sound_pref_key);
|
||||
mRingtonePreference = (RingtonePreference) findPreference(mRingtonePreferenceKey);
|
||||
mVibratePreference = findPreference(
|
||||
getString(R.string.notification_vibration_pref_key));
|
||||
mNotificationsPreferenceKey =
|
||||
getString(R.string.notifications_pref_key);
|
||||
mNotificationsPreference = findPreference(mNotificationsPreferenceKey);
|
||||
mSmsDisabledPrefKey = getString(R.string.sms_disabled_pref_key);
|
||||
mSmsDisabledPreference = findPreference(mSmsDisabledPrefKey);
|
||||
mSmsEnabledPrefKey = getString(R.string.sms_enabled_pref_key);
|
||||
@@ -130,9 +115,6 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
|
||||
(SwitchPreference) findPreference(mSwipeRightToDeleteConversationkey);
|
||||
mIsSmsPreferenceClicked = false;
|
||||
|
||||
final SharedPreferences prefs = getPreferenceScreen().getSharedPreferences();
|
||||
updateSoundSummary(prefs);
|
||||
|
||||
if (!DebugUtils.isDebugEnabled()) {
|
||||
final Preference debugCategory = findPreference(getString(
|
||||
R.string.debug_pref_key));
|
||||
@@ -154,8 +136,13 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick (PreferenceScreen preferenceScreen,
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
|
||||
Preference preference) {
|
||||
if (preference.getKey() == mNotificationsPreferenceKey) {
|
||||
Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
|
||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName());
|
||||
startActivity(intent);
|
||||
}
|
||||
if (preference.getKey() == mSmsDisabledPrefKey ||
|
||||
preference.getKey() == mSmsEnabledPrefKey) {
|
||||
mIsSmsPreferenceClicked = true;
|
||||
@@ -163,35 +150,6 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
|
||||
return super.onPreferenceTreeClick(preferenceScreen, preference);
|
||||
}
|
||||
|
||||
private void updateSoundSummary(final SharedPreferences sharedPreferences) {
|
||||
// The silent ringtone just returns an empty string
|
||||
String ringtoneName = mRingtonePreference.getContext().getString(
|
||||
R.string.silent_ringtone);
|
||||
|
||||
String ringtoneString = sharedPreferences.getString(mRingtonePreferenceKey, null);
|
||||
|
||||
// Bootstrap the default setting in the preferences so that we have a valid selection
|
||||
// in the dialog the first time that the user opens it.
|
||||
if (ringtoneString == null) {
|
||||
ringtoneString = Settings.System.DEFAULT_NOTIFICATION_URI.toString();
|
||||
final SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putString(mRingtonePreferenceKey, ringtoneString);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(ringtoneString)) {
|
||||
final Uri ringtoneUri = Uri.parse(ringtoneString);
|
||||
final Ringtone tone = RingtoneManager.getRingtone(mRingtonePreference.getContext(),
|
||||
ringtoneUri);
|
||||
|
||||
if (tone != null) {
|
||||
ringtoneName = tone.getTitle(mRingtonePreference.getContext());
|
||||
}
|
||||
}
|
||||
|
||||
mRingtonePreference.setSummary(ringtoneName);
|
||||
}
|
||||
|
||||
private void updateSmsEnabledPreferences() {
|
||||
if (!OsUtil.isAtLeastKLP()) {
|
||||
getPreferenceScreen().removePreference(mSmsDisabledPreference);
|
||||
@@ -222,48 +180,14 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
|
||||
getPreferenceScreen().removePreference(mSmsEnabledPreference);
|
||||
mSmsDisabledPreference.setSummary(defaultSmsAppLabel);
|
||||
}
|
||||
updateNotificationsPreferences();
|
||||
}
|
||||
mIsSmsPreferenceClicked = false;
|
||||
}
|
||||
|
||||
private void updateNotificationsPreferences() {
|
||||
final boolean canNotify = !OsUtil.isAtLeastKLP()
|
||||
|| PhoneUtils.getDefault().isDefaultSmsApp();
|
||||
mNotificationsEnabledPreference.setEnabled(canNotify);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
// We do this on start rather than on resume because the sound picker is in a
|
||||
// separate activity.
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
updateSmsEnabledPreferences();
|
||||
updateNotificationsPreferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences,
|
||||
final String key) {
|
||||
if (key.equals(mNotificationsEnabledPreferenceKey)) {
|
||||
updateNotificationsPreferences();
|
||||
} else if (key.equals(mRingtonePreferenceKey)) {
|
||||
updateSoundSummary(sharedPreferences);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.view.View;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.action.DeleteConversationAction;
|
||||
import com.android.messaging.datamodel.action.UpdateConversationArchiveStatusAction;
|
||||
import com.android.messaging.datamodel.action.UpdateConversationOptionsAction;
|
||||
import com.android.messaging.datamodel.action.UpdateDestinationBlockedAction;
|
||||
import com.android.messaging.datamodel.data.ConversationListData;
|
||||
import com.android.messaging.datamodel.data.ConversationListItemData;
|
||||
@@ -190,23 +189,6 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAc
|
||||
exitMultiSelectState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionBarNotification(final Iterable<SelectedConversation> conversations,
|
||||
final boolean isNotificationOn) {
|
||||
for (final SelectedConversation conversation : conversations) {
|
||||
UpdateConversationOptionsAction.enableConversationNotifications(
|
||||
conversation.conversationId, isNotificationOn);
|
||||
}
|
||||
|
||||
final int textId = isNotificationOn ?
|
||||
R.string.notification_on_toast_message : R.string.notification_off_toast_message;
|
||||
final String message = getResources().getString(textId, 1);
|
||||
UiUtils.showSnackBar(this, findViewById(android.R.id.list), message,
|
||||
null /* undoRunnable */,
|
||||
SnackBar.Action.SNACK_BAR_UNDO, mConversationListFragment.getSnackBarInteractions());
|
||||
exitMultiSelectState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionBarAddContact(final SelectedConversation conversation) {
|
||||
final Uri avatarUri;
|
||||
|
||||
@@ -127,7 +127,6 @@ public class ConversationListItemView extends FrameLayout implements OnClickList
|
||||
private TextView mTimestampTextView;
|
||||
private ContactIconView mContactIconView;
|
||||
private ImageView mContactCheckmarkView;
|
||||
private ImageView mNotificationBellView;
|
||||
private ImageView mFailedStatusIconView;
|
||||
private ImageView mCrossSwipeArchiveLeftImageView;
|
||||
private ImageView mCrossSwipeArchiveRightImageView;
|
||||
@@ -153,7 +152,6 @@ public class ConversationListItemView extends FrameLayout implements OnClickList
|
||||
mTimestampTextView = (TextView) findViewById(R.id.conversation_timestamp);
|
||||
mContactIconView = (ContactIconView) findViewById(R.id.conversation_icon);
|
||||
mContactCheckmarkView = (ImageView) findViewById(R.id.conversation_checkmark);
|
||||
mNotificationBellView = (ImageView) findViewById(R.id.conversation_notification_bell);
|
||||
mFailedStatusIconView = (ImageView) findViewById(R.id.conversation_failed_status_icon);
|
||||
mCrossSwipeArchiveLeftImageView = (ImageView) findViewById(R.id.crossSwipeArchiveIconLeft);
|
||||
mCrossSwipeArchiveRightImageView =
|
||||
@@ -503,9 +501,6 @@ public class ConversationListItemView extends FrameLayout implements OnClickList
|
||||
mAudioAttachmentView.setOnLongClickListener(this);
|
||||
mAudioAttachmentView.setVisibility(audioPreviewVisiblity);
|
||||
|
||||
final int notificationBellVisiblity = mData.getNotificationEnabled() ? GONE : VISIBLE;
|
||||
mNotificationBellView.setVisibility(notificationBellVisiblity);
|
||||
|
||||
if (PrefsUtils.isSwipeRightToDeleteEnabled()) {
|
||||
mCrossSwipeArchiveLeftImageView.setImageDrawable(getResources()
|
||||
.getDrawable(R.drawable.ic_delete_small_dark));
|
||||
|
||||
@@ -37,8 +37,6 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
void onActionBarDelete(Collection<SelectedConversation> conversations);
|
||||
void onActionBarArchive(Iterable<SelectedConversation> conversations,
|
||||
boolean isToArchive);
|
||||
void onActionBarNotification(Iterable<SelectedConversation> conversations,
|
||||
boolean isNotificationOn);
|
||||
void onActionBarAddContact(final SelectedConversation conversation);
|
||||
void onActionBarBlock(final SelectedConversation conversation);
|
||||
void onActionBarHome();
|
||||
@@ -52,7 +50,6 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
public final CharSequence participantLookupKey;
|
||||
public final boolean isGroup;
|
||||
public final boolean isArchived;
|
||||
public final boolean notificationEnabled;
|
||||
public SelectedConversation(ConversationListItemData data) {
|
||||
conversationId = data.getConversationId();
|
||||
timestamp = data.getTimestamp();
|
||||
@@ -61,7 +58,6 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
participantLookupKey = data.getParticipantLookupKey();
|
||||
isGroup = data.getIsGroup();
|
||||
isArchived = data.getIsArchived();
|
||||
notificationEnabled = data.getNotificationEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,8 +68,6 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
private MenuItem mUnarchiveMenuItem;
|
||||
private MenuItem mAddContactMenuItem;
|
||||
private MenuItem mBlockMenuItem;
|
||||
private MenuItem mNotificationOnMenuItem;
|
||||
private MenuItem mNotificationOffMenuItem;
|
||||
private boolean mHasInflated;
|
||||
|
||||
public MultiSelectActionModeCallback(final Listener listener) {
|
||||
@@ -89,8 +83,6 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
mUnarchiveMenuItem = menu.findItem(R.id.action_unarchive);
|
||||
mAddContactMenuItem = menu.findItem(R.id.action_add_contact);
|
||||
mBlockMenuItem = menu.findItem(R.id.action_block);
|
||||
mNotificationOffMenuItem = menu.findItem(R.id.action_notification_off);
|
||||
mNotificationOnMenuItem = menu.findItem(R.id.action_notification_on);
|
||||
mHasInflated = true;
|
||||
updateActionIconsVisiblity();
|
||||
return true;
|
||||
@@ -113,12 +105,6 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
case R.id.action_unarchive:
|
||||
mListener.onActionBarArchive(mSelectedConversations.values(), false);
|
||||
return true;
|
||||
case R.id.action_notification_off:
|
||||
mListener.onActionBarNotification(mSelectedConversations.values(), false);
|
||||
return true;
|
||||
case R.id.action_notification_on:
|
||||
mListener.onActionBarNotification(mSelectedConversations.values(), true);
|
||||
return true;
|
||||
case R.id.action_add_contact:
|
||||
Assert.isTrue(mSelectedConversations.size() == 1);
|
||||
mListener.onActionBarAddContact(mSelectedConversations.valueAt(0));
|
||||
@@ -186,16 +172,8 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
|
||||
boolean hasCurrentlyArchived = false;
|
||||
boolean hasCurrentlyUnarchived = false;
|
||||
boolean hasCurrentlyOnNotification = false;
|
||||
boolean hasCurrentlyOffNotification = false;
|
||||
final Iterable<SelectedConversation> conversations = mSelectedConversations.values();
|
||||
for (final SelectedConversation conversation : conversations) {
|
||||
if (conversation.notificationEnabled) {
|
||||
hasCurrentlyOnNotification = true;
|
||||
} else {
|
||||
hasCurrentlyOffNotification = true;
|
||||
}
|
||||
|
||||
if (conversation.isArchived) {
|
||||
hasCurrentlyArchived = true;
|
||||
} else {
|
||||
@@ -203,15 +181,10 @@ public class MultiSelectActionModeCallback implements Callback {
|
||||
}
|
||||
|
||||
// If we found at least one of each example we don't need to keep looping.
|
||||
if (hasCurrentlyOffNotification && hasCurrentlyOnNotification &&
|
||||
hasCurrentlyArchived && hasCurrentlyUnarchived) {
|
||||
if (hasCurrentlyArchived && hasCurrentlyUnarchived) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we have notification off conversations we show on button, if we have notification on
|
||||
// conversation we show off button. We can show both if we have a mixture.
|
||||
mNotificationOffMenuItem.setVisible(hasCurrentlyOnNotification);
|
||||
mNotificationOnMenuItem.setVisible(hasCurrentlyOffNotification);
|
||||
|
||||
mArchiveMenuItem.setVisible(hasCurrentlyUnarchived);
|
||||
mUnarchiveMenuItem.setVisible(hasCurrentlyArchived);
|
||||
|
||||
@@ -18,12 +18,12 @@ package com.android.messaging.ui.conversationsettings;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Fragment;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.media.RingtoneManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.Settings;
|
||||
@@ -49,6 +49,7 @@ import com.android.messaging.ui.CompositeAdapter;
|
||||
import com.android.messaging.ui.PersonItemView;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.ui.conversation.ConversationActivity;
|
||||
import com.android.messaging.util.NotificationsUtil;
|
||||
import com.android.messaging.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -62,11 +63,10 @@ public class PeopleAndOptionsFragment extends Fragment
|
||||
private ListView mListView;
|
||||
private OptionsListAdapter mOptionsListAdapter;
|
||||
private PeopleListAdapter mPeopleListAdapter;
|
||||
private List<ParticipantData> mOtherParticipants;
|
||||
private final Binding<PeopleAndOptionsData> mBinding =
|
||||
BindingBase.createBinding(this);
|
||||
|
||||
private static final int REQUEST_CODE_RINGTONE_PICKER = 1000;
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -89,17 +89,6 @@ public class PeopleAndOptionsFragment extends Fragment
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_RINGTONE_PICKER) {
|
||||
final Parcelable pick = data.getParcelableExtra(
|
||||
RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
final String pickedUri = pick == null ? "" : pick.toString();
|
||||
mBinding.getData().setConversationNotificationSound(mBinding, pickedUri);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
@@ -125,30 +114,31 @@ public class PeopleAndOptionsFragment extends Fragment
|
||||
final List<ParticipantData> participants) {
|
||||
mBinding.ensureBound(data);
|
||||
mPeopleListAdapter.updateParticipants(participants);
|
||||
mOtherParticipants = participants;
|
||||
final ParticipantData otherParticipant = participants.size() == 1 ?
|
||||
participants.get(0) : null;
|
||||
mOptionsListAdapter.setOtherParticipant(otherParticipant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOptionsItemViewClicked(final PeopleOptionsItemData item,
|
||||
final boolean isChecked) {
|
||||
public void onOptionsItemViewClicked(final PeopleOptionsItemData item) {
|
||||
switch (item.getItemId()) {
|
||||
case PeopleOptionsItemData.SETTING_NOTIFICATION_ENABLED:
|
||||
mBinding.getData().enableConversationNotifications(mBinding, isChecked);
|
||||
break;
|
||||
|
||||
case PeopleOptionsItemData.SETTING_NOTIFICATION_SOUND_URI:
|
||||
final Intent ringtonePickerIntent = UIIntents.get().getRingtonePickerIntent(
|
||||
getString(R.string.notification_sound_pref_title),
|
||||
item.getRingtoneUri(), Settings.System.DEFAULT_NOTIFICATION_URI,
|
||||
RingtoneManager.TYPE_NOTIFICATION);
|
||||
startActivityForResult(ringtonePickerIntent, REQUEST_CODE_RINGTONE_PICKER);
|
||||
break;
|
||||
|
||||
case PeopleOptionsItemData.SETTING_NOTIFICATION_VIBRATION:
|
||||
mBinding.getData().enableConversationNotificationVibration(mBinding,
|
||||
isChecked);
|
||||
case PeopleOptionsItemData.SETTING_NOTIFICATION:
|
||||
ArrayList<String> participantsNames = new ArrayList<String>();
|
||||
for (ParticipantData participant : mOtherParticipants) {
|
||||
participantsNames.add(participant.getDisplayName(true));
|
||||
}
|
||||
NotificationsUtil.createNotificationChannelGroup(getActivity(),
|
||||
NotificationsUtil.CONVERSATION_GROUP_NAME,
|
||||
R.string.notification_channel_messages_title);
|
||||
NotificationsUtil.createNotificationChannel(getActivity(),
|
||||
mBinding.getData().getConversationId(),
|
||||
String.join(", ", participantsNames),
|
||||
NotificationManager.IMPORTANCE_DEFAULT,
|
||||
NotificationsUtil.CONVERSATION_GROUP_NAME);
|
||||
Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
|
||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName());
|
||||
startActivity(intent);
|
||||
break;
|
||||
|
||||
case PeopleOptionsItemData.SETTING_BLOCKED:
|
||||
|
||||
@@ -38,7 +38,7 @@ public class PeopleOptionsItemView extends LinearLayout {
|
||||
* Implemented by the host of this view that handles options click event.
|
||||
*/
|
||||
public interface HostInterface {
|
||||
void onOptionsItemViewClicked(PeopleOptionsItemData item, boolean isChecked);
|
||||
void onOptionsItemViewClicked(PeopleOptionsItemData item);
|
||||
}
|
||||
|
||||
private TextView mTitle;
|
||||
@@ -55,12 +55,10 @@ public class PeopleOptionsItemView extends LinearLayout {
|
||||
@Override
|
||||
protected void onFinishInflate () {
|
||||
mTitle = (TextView) findViewById(R.id.title);
|
||||
mSubtitle = (TextView) findViewById(R.id.subtitle);
|
||||
mSwitch = (SwitchCompat) findViewById(R.id.switch_button);
|
||||
setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
mHostInterface.onOptionsItemViewClicked(mData, !mData.getChecked());
|
||||
mHostInterface.onOptionsItemViewClicked(mData);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -72,28 +70,5 @@ public class PeopleOptionsItemView extends LinearLayout {
|
||||
mHostInterface = hostInterface;
|
||||
|
||||
mTitle.setText(mData.getTitle());
|
||||
final String subtitle = mData.getSubtitle();
|
||||
if (TextUtils.isEmpty(subtitle)) {
|
||||
mSubtitle.setVisibility(GONE);
|
||||
} else {
|
||||
mSubtitle.setVisibility(VISIBLE);
|
||||
mSubtitle.setText(subtitle);
|
||||
}
|
||||
|
||||
if (mData.getCheckable()) {
|
||||
mSwitch.setVisibility(VISIBLE);
|
||||
mSwitch.setChecked(mData.getChecked());
|
||||
} else {
|
||||
mSwitch.setVisibility(GONE);
|
||||
}
|
||||
|
||||
final boolean enabled = mData.getEnabled();
|
||||
if (enabled != isEnabled()) {
|
||||
mTitle.setEnabled(enabled);
|
||||
mSubtitle.setEnabled(enabled);
|
||||
mSwitch.setEnabled(enabled);
|
||||
setAlpha(enabled ? 1.0f : 0.5f);
|
||||
setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.messaging.util;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
public final class NotificationsUtil {
|
||||
public static final String DEFAULT_CHANNEL_ID = "messaging_channel";
|
||||
public static final String CONVERSATION_GROUP_NAME = "conversation_group";
|
||||
|
||||
private NotificationsUtil() {
|
||||
}
|
||||
|
||||
public static void createNotificationChannel(Context context, String id,
|
||||
int titleResId, int priority, String groupId) {
|
||||
String title = context.getString(titleResId);
|
||||
createNotificationChannel(context, id, title, priority, groupId);
|
||||
}
|
||||
|
||||
public static void createNotificationChannel(Context context, String id,
|
||||
String title, int priority, String groupId) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationManager manager = context.getSystemService(NotificationManager.class);
|
||||
NotificationChannel existing = manager.getNotificationChannel(id);
|
||||
if (existing != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationChannel newChannel = new NotificationChannel(id, title, priority);
|
||||
newChannel.enableLights(true);
|
||||
if (groupId != null) {
|
||||
newChannel.setGroup(groupId);
|
||||
}
|
||||
manager.createNotificationChannel(newChannel);
|
||||
}
|
||||
|
||||
public static void deleteNotificationChannel(Context context, String id) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationManager manager = context.getSystemService(NotificationManager.class);
|
||||
manager.deleteNotificationChannel(id);
|
||||
}
|
||||
|
||||
public static void createNotificationChannelGroup(Context context, String id,
|
||||
int titleResId) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationManager manager = context.getSystemService(NotificationManager.class);
|
||||
NotificationChannelGroup existing = manager.getNotificationChannelGroup(id);
|
||||
if (existing != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String title = context.getString(titleResId);
|
||||
NotificationChannelGroup newChannelGroup = new NotificationChannelGroup(id, title);
|
||||
manager.createNotificationChannelGroup(newChannelGroup);
|
||||
}
|
||||
|
||||
public static NotificationChannel getNotificationChannel(Context context, String id) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NotificationManager manager = context.getSystemService(NotificationManager.class);
|
||||
return manager.getNotificationChannel(id);
|
||||
}
|
||||
|
||||
public static NotificationChannelGroup getNotificationChannelGroup(Context context, String id) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NotificationManager manager = context.getSystemService(NotificationManager.class);
|
||||
return manager.getNotificationChannelGroup(id);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.messaging.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.messaging.Factory;
|
||||
import com.android.messaging.R;
|
||||
|
||||
public class RingtoneUtil {
|
||||
/**
|
||||
* Return a ringtone Uri for the string representation passed in. Use the app
|
||||
* and system defaults as fallbacks
|
||||
* @param ringtoneString is the ringtone to resolve
|
||||
* @return the Uri of the ringtone or the fallback ringtone
|
||||
*/
|
||||
public static Uri getNotificationRingtoneUri(String ringtoneString) {
|
||||
if (ringtoneString == null) {
|
||||
// No override specified, fall back to system-wide setting.
|
||||
final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
|
||||
final Context context = Factory.get().getApplicationContext();
|
||||
final String prefKey = context.getString(R.string.notification_sound_pref_key);
|
||||
ringtoneString = prefs.getString(prefKey, null);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(ringtoneString)) {
|
||||
// We have set a value, even if it is the default Uri at some point
|
||||
return Uri.parse(ringtoneString);
|
||||
} else if (ringtoneString == null) {
|
||||
// We have no setting specified (== null), so we default to the system default
|
||||
return Settings.System.DEFAULT_NOTIFICATION_URI;
|
||||
} else {
|
||||
// An empty string (== "") here is the result of selecting "None" as the ringtone
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,10 +120,6 @@ public class WidgetConversationListService extends RemoteViewsService {
|
||||
remoteViews.setTextViewText(R.id.from,
|
||||
boldifyIfUnread(conv.getName(), hasUnreadMessages));
|
||||
|
||||
// Notifications turned off mini-bell icon
|
||||
remoteViews.setViewVisibility(R.id.conversation_notification_bell,
|
||||
conv.getNotificationEnabled() ? View.GONE : View.VISIBLE);
|
||||
|
||||
// On click intent.
|
||||
final Intent intent = UIIntents.get().getIntentForConversationActivity(mContext,
|
||||
conv.getConversationId(), null /* draft */);
|
||||
|
||||
Reference in New Issue
Block a user