Skip to content

Commit

Permalink
Add support for notification reminders.
Browse files Browse the repository at this point in the history
// FREEBIE

Closes #1623
Fixes #323
  • Loading branch information
moxie0 committed Dec 12, 2014
1 parent 6e7566f commit df12174
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 26 deletions.
12 changes: 11 additions & 1 deletion AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
<service android:enabled="true" android:name=".service.KeyCachingService"/>
<service android:enabled="true" android:name=".service.RegistrationService"/>
<service android:enabled="true" android:name=".service.DirectoryRefreshService"/>

<service android:name=".service.QuickResponseService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
Expand Down Expand Up @@ -305,6 +304,17 @@
</intent-filter>
</receiver>

<receiver android:name=".notifications.MessageNotifier$ReminderReceiver">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.MessageNotifier.REMINDER_ACTION"/>
</intent-filter>
</receiver>

<receiver android:name=".notifications.MessageNotifier$DeleteReceiver">
<intent-filter>
<action android:name="org.thoughtcrime.securesms.MessageNotifier.DELETE_REMINDER_ACTION"/>
</intent-filter>
</receiver>
<uses-library android:name="android.test.runner" />
</application>
</manifest>
18 changes: 18 additions & 0 deletions res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,22 @@
<item>@drawable/ic_send_sms_secure</item>
<item>@drawable/ic_send_push</item>
</string-array>

<string-array name="pref_repeat_alerts_entries">
<item>Never</item>
<item>One time</item>
<item>Two times</item>
<item>Three times</item>
<item>Five times</item>
<item>Ten times</item>
</string-array>

<string-array name="pref_repeat_alerts_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>5</item>
<item>10</item>
</string-array>
</resources>
31 changes: 20 additions & 11 deletions res/xml/preferences_notifications.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
android:summary="@string/preferences__display_message_notifications_in_status_bar"
android:defaultValue="true" />

<RingtonePreference android:dependency="pref_key_enable_notifications"
android:key="pref_key_ringtone"
android:title="@string/preferences__sound"
android:summary="@string/preferences__change_notification_sound"
android:ringtoneType="notification"
android:defaultValue="content://settings/system/notification_sound" />

<CheckBoxPreference android:dependency="pref_key_enable_notifications"
android:key="pref_key_vibrate"
android:defaultValue="true"
android:title="@string/preferences__vibrate"
android:summary="@string/preferences__also_vibrate_when_notified" />

<ListPreference
android:key="pref_led_color"
android:defaultValue="green"
Expand All @@ -22,22 +35,18 @@
android:entries="@array/pref_led_blink_pattern_entries"
android:entryValues="@array/pref_led_blink_pattern_values" />

<RingtonePreference android:dependency="pref_key_enable_notifications"
android:key="pref_key_ringtone"
android:title="@string/preferences__sound"
android:summary="@string/preferences__change_notification_sound"
android:ringtoneType="notification"
android:defaultValue="content://settings/system/notification_sound" />

<CheckBoxPreference android:key="pref_key_inthread_notifications"
android:title="@string/preferences__inthread_notifications"
android:summary="@string/preferences__play_inthread_notifications"
android:dependency="pref_key_enable_notifications"
android:defaultValue="true" />

<CheckBoxPreference android:dependency="pref_key_enable_notifications"
android:key="pref_key_vibrate"
android:defaultValue="true"
android:title="@string/preferences__vibrate"
android:summary="@string/preferences__also_vibrate_when_notified" />
<ListPreference
android:key="pref_repeat_alerts"
android:defaultValue="0"
android:title="Repeat alerts"
android:dependency="pref_key_enable_notifications"
android:entries="@array/pref_repeat_alerts_entries"
android:entryValues="@array/pref_repeat_alerts_values" />
</PreferenceScreen>
63 changes: 57 additions & 6 deletions src/org/thoughtcrime/securesms/notifications/MessageNotifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
*/
package org.thoughtcrime.securesms.notifications;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
Expand All @@ -40,23 +42,24 @@
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.RoutingActivity;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.PushDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.api.messages.TextSecureEnvelope;

import java.io.IOException;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.TimeUnit;

import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.ShortcutBadger;

/**
Expand Down Expand Up @@ -102,13 +105,12 @@ public static void notifyMessageDeliveryFailed(Context context, Recipients recip
}
}


public static void updateNotification(Context context, MasterSecret masterSecret) {
if (!TextSecurePreferences.isNotificationsEnabled(context)) {
return;
}

updateNotification(context, masterSecret, false);
updateNotification(context, masterSecret, false, 0);
}

public static void updateNotification(Context context, MasterSecret masterSecret, long threadId) {
Expand All @@ -120,11 +122,11 @@ public static void updateNotification(Context context, MasterSecret masterSecret
DatabaseFactory.getThreadDatabase(context).setRead(threadId);
sendInThreadNotification(context);
} else {
updateNotification(context, masterSecret, true);
updateNotification(context, masterSecret, true, 0);
}
}

private static void updateNotification(Context context, MasterSecret masterSecret, boolean signal) {
private static void updateNotification(Context context, MasterSecret masterSecret, boolean signal, int reminderCount) {
Cursor telcoCursor = null;
Cursor pushCursor = null;

Expand All @@ -138,6 +140,7 @@ private static void updateNotification(Context context, MasterSecret masterSecre
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
.cancel(NOTIFICATION_ID);
updateBadge(context, 0);
clearReminder(context);
return;
}

Expand All @@ -152,6 +155,7 @@ private static void updateNotification(Context context, MasterSecret masterSecre
}

updateBadge(context, notificationState.getMessageCount());
scheduleReminder(context, masterSecret, reminderCount);
} finally {
if (telcoCursor != null) telcoCursor.close();
if (pushCursor != null) pushCursor.close();
Expand Down Expand Up @@ -180,6 +184,7 @@ private static void sendSingleThreadNotification(Context context,
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
builder.setContentInfo(String.valueOf(notificationState.getMessageCount()));
builder.setNumber(notificationState.getMessageCount());
builder.setDeleteIntent(PendingIntent.getBroadcast(context, 0, new Intent(DeleteReceiver.DELETE_REMINDER_ACTION), 0));

if (masterSecret != null) {
builder.addAction(R.drawable.check, context.getString(R.string.MessageNotifier_mark_as_read),
Expand Down Expand Up @@ -227,6 +232,8 @@ private static void sendMultipleThreadNotification(Context context,
builder.setContentInfo(String.valueOf(notificationState.getMessageCount()));
builder.setNumber(notificationState.getMessageCount());

builder.setDeleteIntent(PendingIntent.getBroadcast(context, 0, new Intent(DeleteReceiver.DELETE_REMINDER_ACTION), 0));

if (masterSecret != null) {
builder.addAction(R.drawable.check, context.getString(R.string.MessageNotifier_mark_all_as_read),
notificationState.getMarkAsReadIntent(context, masterSecret));
Expand Down Expand Up @@ -400,4 +407,48 @@ private static void updateBadge(Context context, int count) {
Log.w("MessageNotifier", t);
}
}

private static void scheduleReminder(Context context, MasterSecret masterSecret, int count) {
if (count >= TextSecurePreferences.getRepeatAlertsCount(context)) {
return;
}

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(ReminderReceiver.REMINDER_ACTION);
alarmIntent.putExtra("reminder_count", count);

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
long timeout = TimeUnit.SECONDS.toMillis(10);

alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, pendingIntent);
}

private static void clearReminder(Context context) {
Intent alarmIntent = new Intent(ReminderReceiver.REMINDER_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}

public static class ReminderReceiver extends BroadcastReceiver {

public static final String REMINDER_ACTION = "org.thoughtcrime.securesms.MessageNotifier.REMINDER_ACTION";

@Override
public void onReceive(Context context, Intent intent) {
MasterSecret masterSecret = KeyCachingService.getMasterSecret(context);
int reminderCount = intent.getIntExtra("reminder_count", 0);
MessageNotifier.updateNotification(context, masterSecret, true, reminderCount + 1);
}
}

public static class DeleteReceiver extends BroadcastReceiver {

public static final String DELETE_REMINDER_ACTION = "org.thoughtcrime.securesms.MessageNotifier.DELETE_REMINDER_ACTION";

@Override
public void onReceive(Context context, Intent intent) {
clearReminder(context);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ public void onCreate(Bundle paramBundle) {
addPreferencesFromResource(R.xml.preferences_notifications);

this.findPreference(TextSecurePreferences.LED_COLOR_PREF)
.setOnPreferenceChangeListener(new ListSummaryListener());
.setOnPreferenceChangeListener(new ListSummaryListener());
this.findPreference(TextSecurePreferences.LED_BLINK_PREF)
.setOnPreferenceChangeListener(new ListSummaryListener());
.setOnPreferenceChangeListener(new ListSummaryListener());
this.findPreference(TextSecurePreferences.RINGTONE_PREF)
.setOnPreferenceChangeListener(new RingtoneSummaryListener());
.setOnPreferenceChangeListener(new RingtoneSummaryListener());
this.findPreference(TextSecurePreferences.REPEAT_ALERTS_PREF)
.setOnPreferenceChangeListener(new ListSummaryListener());

initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_COLOR_PREF));
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_BLINK_PREF));
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.REPEAT_ALERTS_PREF));
initializeRingtoneSummary((RingtonePreference) findPreference(TextSecurePreferences.RINGTONE_PREF));
}

Expand Down
26 changes: 21 additions & 5 deletions src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

public class TextSecurePreferences {

private static final String TAG = TextSecurePreferences.class.getSimpleName();

public static final String IDENTITY_PREF = "pref_choose_identity";
public static final String CHANGE_PASSPHRASE_PREF = "pref_change_passphrase";
public static final String DISABLE_PASSPHRASE_PREF = "pref_disable_passphrase";
Expand Down Expand Up @@ -56,6 +58,25 @@ public class TextSecurePreferences {
private static final String FALLBACK_MMS_ENABLED_PREF = "pref_mms_fallback_enabled";
private static final String SIGNED_PREKEY_REGISTERED_PREF = "pref_signed_prekey_registered";

private static final String GCM_REGISTRATION_ID_PREF = "pref_gcm_registration_id";
private static final String GCM_REGISTRATION_ID_VERSION_PREF = "pref_gcm_registration_id_version";

private static final String PUSH_REGISTRATION_REMINDER_PREF = "pref_push_registration_reminder";
public static final String REPEAT_ALERTS_PREF = "pref_repeat_alerts";

public static int getRepeatAlertsCount(Context context) {
try {
return Integer.parseInt(getStringPreference(context, REPEAT_ALERTS_PREF, "0"));
} catch (NumberFormatException e) {
Log.w(TAG, e);
return 0;
}
}

public static void setRepeatAlertsCount(Context context, int count) {
setStringPreference(context, REPEAT_ALERTS_PREF, String.valueOf(count));
}

public static boolean isSignedPreKeyRegistered(Context context) {
return getBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, false);
}
Expand All @@ -64,11 +85,6 @@ public static void setSignedPreKeyRegistered(Context context, boolean value) {
setBooleanPreference(context, SIGNED_PREKEY_REGISTERED_PREF, value);
}

private static final String GCM_REGISTRATION_ID_PREF = "pref_gcm_registration_id";
private static final String GCM_REGISTRATION_ID_VERSION_PREF = "pref_gcm_registration_id_version";

private static final String PUSH_REGISTRATION_REMINDER_PREF = "pref_push_registration_reminder";

public static void setGcmRegistrationId(Context context, String registrationId) {
setStringPreference(context, GCM_REGISTRATION_ID_PREF, registrationId);
setIntegerPrefrence(context, GCM_REGISTRATION_ID_VERSION_PREF, Util.getCurrentApkReleaseVersion(context));
Expand Down

3 comments on commit df12174

@mcginty
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#323 seems unrelated to this, wrong issue?

@pejakm
Copy link

@pejakm pejakm commented on df12174 Dec 12, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strings aren't translated, intentional?

@haffenloher
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moxie0 I think this commit should close #393 instead of #323.

Please sign in to comment.