diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index 3c2084bd75417d0e4430f7b66ffd736ca6763b9a..2967668427e7d72fd8b22c078afedb1b7e7d2e36 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -133,6 +133,10 @@ <item quantity="one">New forum post.</item> <item quantity="other">%d new forum posts.</item> </plurals> + <plurals name="blog_post_notification_text"> + <item quantity="one">New blog post.</item> + <item quantity="other">%d new blog posts.</item> + </plurals> <!-- Settings --> <string name="settings_title">Settings</string> @@ -151,6 +155,7 @@ <string name="notification_settings_title">Notifications</string> <string name="notify_private_messages_setting">Show alerts for private messages</string> <string name="notify_forum_posts_setting">Show alerts for forum posts</string> + <string name="notify_blog_posts_setting">Show alerts for blog posts</string> <string name="notify_vibration_setting">Vibrate</string> <string name="notify_sound_setting">Sound</string> <string name="notify_sound_setting_default">Default ringtone</string> diff --git a/briar-android/res/xml/settings.xml b/briar-android/res/xml/settings.xml index 9814fabee101cfb1c39ee4657690f8c72a9e4a04..881f700bf52c70f00e273ffe749604620eeb2bc3 100644 --- a/briar-android/res/xml/settings.xml +++ b/briar-android/res/xml/settings.xml @@ -69,6 +69,12 @@ android:persistent="false" android:title="@string/notify_forum_posts_setting"/> + <CheckBoxPreference + android:defaultValue="true" + android:key="pref_key_notify_blog_posts" + android:persistent="false" + android:title="@string/notify_blog_posts_setting"/> + <CheckBoxPreference android:defaultValue="true" android:key="pref_key_notify_vibration" diff --git a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java index 069d9473f07f7f3f2918a5ac68944986efd447c2..f8874fd71ecd575e999b856063ce5337059c8746 100644 --- a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java @@ -18,6 +18,7 @@ import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.db.DatabaseExecutor; import org.briarproject.api.db.DbException; +import org.briarproject.api.event.BlogPostAddedEvent; import org.briarproject.api.event.Event; import org.briarproject.api.event.EventListener; import org.briarproject.api.event.ForumInvitationReceivedEvent; @@ -57,6 +58,7 @@ import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL; import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET; import static java.util.logging.Level.WARNING; import static org.briarproject.android.BriarActivity.GROUP_ID; +import static org.briarproject.android.fragment.SettingsFragment.PREF_NOTIFY_BLOG; import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE; class AndroidNotificationManagerImpl implements AndroidNotificationManager, @@ -64,7 +66,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3; private static final int FORUM_POST_NOTIFICATION_ID = 4; - private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 5; + private static final int BLOG_POST_NOTIFICATION_ID = 5; + private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 6; private static final String CONTACT_URI = "content://org.briarproject/contact"; private static final String FORUM_URI = @@ -84,9 +87,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, private final Map<GroupId, Integer> forumCounts = new HashMap<>(); private final AtomicBoolean used = new AtomicBoolean(false); - private int contactTotal = 0, forumTotal = 0; + private int contactTotal = 0, forumTotal = 0, blogTotal = 0; private int nextRequestId = 0; private GroupId visibleGroup = null; + private boolean blogBlocked = false; private volatile Settings settings = new Settings(); @@ -158,6 +162,9 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, } else if (e instanceof ForumPostReceivedEvent) { ForumPostReceivedEvent m = (ForumPostReceivedEvent) e; showForumPostNotification(m.getGroupId()); + } else if (e instanceof BlogPostAddedEvent) { + BlogPostAddedEvent be = (BlogPostAddedEvent) e; + showBlogPostNotification(be.getGroupId()); } else if (e instanceof IntroductionRequestReceivedEvent) { ContactId c = ((IntroductionRequestReceivedEvent) e).getContactId(); showNotificationForPrivateConversation(c); @@ -351,6 +358,61 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, } } + @Override + public void showBlogPostNotification(final GroupId g) { + androidExecutor.execute(new Runnable() { + @Override + public void run() { + if (!blogBlocked) { + blogTotal++; + updateBlogPostNotification(); + } + } + }); + } + + @Override + public void clearBlogPostNotification() { + blogTotal = 0; + Object o = appContext.getSystemService(NOTIFICATION_SERVICE); + NotificationManager nm = (NotificationManager) o; + nm.cancel(BLOG_POST_NOTIFICATION_ID); + } + + private void updateBlogPostNotification() { + if (settings.getBoolean(PREF_NOTIFY_BLOG, true)) { + NotificationCompat.Builder b = + new NotificationCompat.Builder(appContext); + b.setSmallIcon(R.drawable.message_notification_icon); + b.setContentTitle(appContext.getText(R.string.app_name)); + b.setContentText(appContext.getResources().getQuantityString( + R.plurals.blog_post_notification_text, blogTotal, + blogTotal)); + String ringtoneUri = settings.get("notifyRingtoneUri"); + if (!StringUtils.isNullOrEmpty(ringtoneUri)) + b.setSound(Uri.parse(ringtoneUri)); + b.setDefaults(getDefaults()); + b.setOnlyAlertOnce(true); + b.setAutoCancel(true); + + Intent i = new Intent(appContext, NavDrawerActivity.class); + i.putExtra(NavDrawerActivity.INTENT_BLOGS, true); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + TaskStackBuilder t = TaskStackBuilder.create(appContext); + t.addParentStack(NavDrawerActivity.class); + t.addNextIntent(i); + b.setContentIntent(t.getPendingIntent(nextRequestId++, 0)); + + if (Build.VERSION.SDK_INT >= 21) { + b.setCategory(CATEGORY_SOCIAL); + b.setVisibility(VISIBILITY_SECRET); + } + Object o = appContext.getSystemService(NOTIFICATION_SERVICE); + NotificationManager nm = (NotificationManager) o; + nm.notify(BLOG_POST_NOTIFICATION_ID, b.build()); + } + } + @Override public void blockNotification(final GroupId g) { androidExecutor.execute(new Runnable() { @@ -371,6 +433,26 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, }); } + @Override + public void blockBlogNotification() { + androidExecutor.execute(new Runnable() { + @Override + public void run() { + blogBlocked = true; + } + }); + } + + @Override + public void unblockBlogNotification() { + androidExecutor.execute(new Runnable() { + @Override + public void run() { + blogBlocked = false; + } + }); + } + private void showNotificationForPrivateConversation(final ContactId c) { androidExecutor.execute(new Runnable() { @Override diff --git a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java index a46581c471a1af1bf524aa15461ee918d453afdf..e6082e07f11852d6187a2672a987b5962da3816e 100644 --- a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java +++ b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java @@ -32,7 +32,7 @@ public abstract class BriarFragmentActivity extends BriarActivity { } } - protected void clearBackStack() { + void clearBackStack() { getSupportFragmentManager() .popBackStackImmediate( null, @@ -69,7 +69,7 @@ public abstract class BriarFragmentActivity extends BriarActivity { else startFragment(fragment, true); } - protected void showMessageDialog(int titleStringId, int msgStringId) { + void showMessageDialog(int titleStringId, int msgStringId) { // TODO replace with custom dialog fragment ? AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.BriarDialogTheme); @@ -80,12 +80,12 @@ public abstract class BriarFragmentActivity extends BriarActivity { dialog.show(); } - protected void startFragment(BaseFragment fragment, + private void startFragment(BaseFragment fragment, boolean isAddedToBackStack) { startFragment(fragment, 0, 0, isAddedToBackStack); } - protected void startFragment(BaseFragment fragment, + private void startFragment(BaseFragment fragment, @AnimRes int inAnimation, @AnimRes int outAnimation, boolean isAddedToBackStack) { FragmentTransaction trans = diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java index 847a8d7e6a76913fe078b70512981b3090d83779..8de76247adbcc85f138f1f2a37dbb544a1efb75c 100644 --- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java +++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java @@ -47,14 +47,15 @@ public class NavDrawerActivity extends BriarFragmentActivity implements BaseFragment.BaseFragmentListener, TransportStateListener, OnNavigationItemSelectedListener { - public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; - - public static final String INTENT_CONTACTS = "intent_contacts"; - public static final String INTENT_FORUMS = "intent_forums"; + static final String INTENT_CONTACTS = "intent_contacts"; + static final String INTENT_FORUMS = "intent_forums"; + static final String INTENT_BLOGS = "intent_blogs"; private static final Logger LOG = Logger.getLogger(NavDrawerActivity.class.getName()); + private final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; + private ActionBarDrawerToggle drawerToggle; @Inject @@ -80,6 +81,10 @@ public class NavDrawerActivity extends BriarFragmentActivity implements else if (intent.getBooleanExtra(INTENT_CONTACTS, false)) { startFragment(ContactListFragment.newInstance()); } + else if (intent.getBooleanExtra(INTENT_BLOGS, false)) { + startFragment(BlogsFragment.newInstance()); + } + setIntent(null); } @Override @@ -122,6 +127,9 @@ public class NavDrawerActivity extends BriarFragmentActivity implements navigation.setCheckedItem(R.id.nav_btn_contacts); startFragment(ContactListFragment.newInstance()); } + if (getIntent() != null) { + onNewIntent(getIntent()); + } } private void welcomeMessageCheck() { diff --git a/briar-android/src/org/briarproject/android/api/AndroidNotificationManager.java b/briar-android/src/org/briarproject/android/api/AndroidNotificationManager.java index 33177e1b8c42aee32ca58196a75a175cbed64c46..776ed723af1def7b3148a47144548231c3bd0512 100644 --- a/briar-android/src/org/briarproject/android/api/AndroidNotificationManager.java +++ b/briar-android/src/org/briarproject/android/api/AndroidNotificationManager.java @@ -13,7 +13,15 @@ public interface AndroidNotificationManager { void clearForumPostNotification(GroupId g); + void showBlogPostNotification(GroupId g); + + void clearBlogPostNotification(); + void blockNotification(GroupId g); void unblockNotification(GroupId g); + + void blockBlogNotification(); + + void unblockBlogNotification(); } diff --git a/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java index 98ed5862629217687ed62880168f692e60c6eab3..e02022ac1c238e7b0ea7572d0f614c0e28b8ad56 100644 --- a/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java +++ b/briar-android/src/org/briarproject/android/blogs/FeedControllerImpl.java @@ -1,5 +1,6 @@ package org.briarproject.android.blogs; +import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.controller.DbControllerImpl; import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.api.blogs.Blog; @@ -29,6 +30,9 @@ public class FeedControllerImpl extends DbControllerImpl private static final Logger LOG = Logger.getLogger(FeedControllerImpl.class.getName()); + @SuppressWarnings("WeakerAccess") + @Inject + AndroidNotificationManager notificationManager; @Inject protected volatile BlogManager blogManager; @Inject @@ -44,11 +48,14 @@ public class FeedControllerImpl extends DbControllerImpl @Override public void onResume() { + notificationManager.blockBlogNotification(); + notificationManager.clearBlogPostNotification(); eventBus.addListener(this); } @Override public void onPause() { + notificationManager.unblockBlogNotification(); eventBus.removeListener(this); } diff --git a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java index 0f4fada2342802e9931f677cc574e1f64756e9d5..eff999072c6d1e1b70c64922e2336eba701cdd1a 100644 --- a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java +++ b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java @@ -17,6 +17,7 @@ import android.view.ViewGroup; import org.briarproject.R; import org.briarproject.android.ActivityComponent; +import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener; import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.android.fragment.BaseFragment; diff --git a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java index b7750dc17a91f3f96f480126eb31397c602376f8..7bde67e6e224a2051ffd83421c5ee96ea99a150b 100644 --- a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java +++ b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java @@ -48,8 +48,9 @@ import static java.util.logging.Level.WARNING; public class SettingsFragment extends PreferenceFragmentCompat implements EventListener, Preference.OnPreferenceChangeListener { - public static final int REQUEST_RINGTONE = 2; + private static final int REQUEST_RINGTONE = 2; public static final String SETTINGS_NAMESPACE = "android-ui"; + public static final String PREF_NOTIFY_BLOG = "notifyBlogPosts"; private static final Logger LOG = Logger.getLogger(SettingsFragment.class.getName()); @@ -60,6 +61,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private ListPreference torOverMobile; private CheckBoxPreference notifyPrivateMessages; private CheckBoxPreference notifyForumPosts; + private CheckBoxPreference notifyBlogPosts; private CheckBoxPreference notifyVibration; private Preference notifySound; @@ -96,6 +98,8 @@ public class SettingsFragment extends PreferenceFragmentCompat "pref_key_notify_private_messages"); notifyForumPosts = (CheckBoxPreference) findPreference( "pref_key_notify_forum_posts"); + notifyBlogPosts = (CheckBoxPreference) findPreference( + "pref_key_notify_blog_posts"); notifyVibration = (CheckBoxPreference) findPreference( "pref_key_notify_vibration"); notifySound = findPreference("pref_key_notify_sound"); @@ -104,6 +108,7 @@ public class SettingsFragment extends PreferenceFragmentCompat torOverMobile.setOnPreferenceChangeListener(this); notifyPrivateMessages.setOnPreferenceChangeListener(this); notifyForumPosts.setOnPreferenceChangeListener(this); + notifyBlogPosts.setOnPreferenceChangeListener(this); notifyVibration.setOnPreferenceChangeListener(this); notifySound.setOnPreferenceClickListener( @@ -200,6 +205,9 @@ public class SettingsFragment extends PreferenceFragmentCompat notifyForumPosts.setChecked(settings.getBoolean( "notifyForumPosts", true)); + notifyBlogPosts.setChecked(settings.getBoolean( + PREF_NOTIFY_BLOG, true)); + notifyVibration.setChecked(settings.getBoolean( "notifyVibration", true)); @@ -245,6 +253,10 @@ public class SettingsFragment extends PreferenceFragmentCompat Settings s = new Settings(); s.putBoolean("notifyForumPosts", (Boolean) o); storeSettings(s); + } else if (preference == notifyBlogPosts) { + Settings s = new Settings(); + s.putBoolean(PREF_NOTIFY_BLOG, (Boolean) o); + storeSettings(s); } else if (preference == notifyVibration) { Settings s = new Settings(); s.putBoolean("notifyVibration", (Boolean) o);